From 5d7758b3589b177f21a1cedf5b1fd47f7c897e26 Mon Sep 17 00:00:00 2001 From: Jason van Zyl Date: Wed, 22 Apr 2009 23:04:06 +0000 Subject: [PATCH] o pull from trunky dunk dunk git-svn-id: https://svn.apache.org/repos/asf/maven/components/branches/MNG-2766@767707 13f79535-47bb-0310-9956-ffa450edef68 --- README.bootstrap.mercury.txt | 36 + README.bootstrap.txt | 2 +- apache-maven/pom.xml | 10 +- build-mercury.xml | 79 +- build.xml | 6 +- maven-compat/pom.xml | 9 +- .../artifact/manager/DefaultWagonManager.java | 5 + .../maven/artifact/manager/WagonManager.java | 2 + .../filter/IncludesArtifactFilter.java | 5 + .../resolver/filter/ScopeArtifactFilter.java | 9 + .../project/path/DefaultPathTranslator.java | 15 + maven-core/pom.xml | 30 +- .../java/org/apache/maven/DefaultMaven.java | 2 +- .../DefaultMavenExecutionRequest.java | 17 +- .../execution/MavenExecutionRequest.java | 3 + .../listeners/BuildExtensionListener.java | 95 +- .../listeners/MavenModelEventListener.java | 3 +- maven-core/src/main/mdo/settings.mdo | 23 +- .../listeners/BuildExtensionListenerTest.java | 57 +- .../maven/project/harness/PomTestWrapper.java | 173 ++++ .../harness/Xpp3DomAttributeIterator.java | 90 ++ .../harness/Xpp3DomAttributePointer.java | 105 +++ .../project/harness/Xpp3DomNodeIterator.java | 161 ++++ .../project/harness/Xpp3DomNodePointer.java | 156 ++++ .../harness/Xpp3DomPointerFactory.java | 62 ++ .../PomConstructionWithSettingsTest.java | 124 +++ .../resources-settings/repositories/pom.xml | 29 + .../repositories/settings.xml | 55 ++ .../settings-no-pom/pom.xml | 13 + .../settings-no-pom/settings.xml | 20 + .../pom.xml | 78 ++ .../settings.xml | 35 + maven-embedder/pom.xml | 13 +- .../java/org/apache/maven/cli/CLIManager.java | 3 + .../org/apache/maven/cli/CLIRequestUtils.java | 26 +- .../apache/maven/embedder/MavenEmbedder.java | 2 + ...DefaultMavenExecutionRequestPopulator.java | 52 +- .../maven/embedder/MavenEmbedderTest.java | 5 +- maven-mercury/pom.xml | 36 +- .../mercury/MavenDependencyProcessor.java | 88 +- .../maven/mercury/MavenDomainModel.java | 248 +---- .../apache/maven/mercury/PomProcessor.java | 16 - .../maven/mercury/PomProcessorException.java | 36 - maven-model-builder/pom.xml | 65 ++ .../org/apache/maven/model/DomainModel.java | 8 + .../maven/model/ModelEventListener.java | 14 + .../org/apache/maven/model/ModelListener.java | 29 + .../maven/model/PomClassicDomainModel.java | 288 ++++++ .../org/apache/maven/model/Processor.java | 36 + .../apache/maven/model/ProcessorContext.java | 352 +++++++ .../org/apache/maven/model}/ProjectUri.java | 2 +- .../interpolator/DefaultInterpolator.java | 811 ++++++++++++++++ .../model/interpolator/Interpolator.java | 17 + .../interpolator/InterpolatorProperty.java | 175 ++++ .../model/interpolator/ModelProperty.java | 255 +++++ .../interpolator}/PomInterpolatorTag.java | 2 +- .../maven/model/processors/BaseProcessor.java | 177 ++++ .../model/processors/BuildProcessor.java | 264 ++++++ .../processors/CiManagementProcessor.java | 89 ++ .../processors/ContributorsProcessor.java | 70 ++ .../processors/DependenciesProcessor.java | 92 ++ .../DependencyManagementProcessor.java | 132 +++ .../model/processors/DependencyProcessor.java | 225 +++++ .../model/processors/DevelopersProcessor.java | 71 ++ .../DistributionManagementProcessor.java | 163 ++++ .../processors/IssueManagementProcessor.java | 54 ++ .../model/processors/LicensesProcessor.java | 59 ++ .../processors/MailingListProcessor.java | 64 ++ .../model/processors/ModelProcessor.java | 177 ++++ .../model/processors/ModuleProcessor.java | 43 + .../processors/OrganizationProcessor.java | 54 ++ .../model/processors/ParentProcessor.java | 48 + .../model/processors/PluginProcessor.java | 359 +++++++ .../PluginsManagementProcessor.java | 189 ++++ .../model/processors/PluginsProcessor.java | 107 +++ .../processors/PrerequisitesProcessor.java | 45 + .../ProfilePropertiesProcessor.java | 58 ++ .../processors/ProfilesModuleProcessor.java | 57 ++ .../model/processors/ProfilesProcessor.java | 45 + .../model/processors/PropertiesProcessor.java | 58 ++ .../model/processors/ReportingProcessor.java | 163 ++++ .../processors/RepositoriesProcessor.java | 98 ++ .../maven/model/processors/ScmProcessor.java | 107 +++ .../maven/profiles/DefaultProfileManager.java | 278 +++--- .../profiles/ProfileActivationContext.java | 3 +- .../profiles/ProfileActivationException.java | 0 .../apache/maven/profiles/ProfileManager.java | 4 + .../maven/profiles/ProfileManagerInfo.java | 35 + .../profiles/matchers/DefaultMatcher.java | 22 +- .../maven/profiles/matchers/FileMatcher.java | 34 + .../maven/profiles/matchers}/JdkMatcher.java | 121 +-- .../profiles/matchers/ProfileMatcher.java | 30 + .../profiles/matchers/PropertyMatcher.java | 60 ++ .../src/main/mdo/profiles.mdo | 0 .../org/apache/maven/project/pom-4.0.0.xml | 0 .../projects/enforcer/enforcer-api/pom.xml | 0 .../projects/enforcer/enforcer-rules/pom.xml | 0 .../enforcer/maven-enforcer-plugin/pom.xml | 0 .../src/test/projects/enforcer/pom.xml | 0 .../src/test/resources/test.txt | 0 maven-model/pom.xml | 22 +- maven-model/src/main/mdo/maven.mdo | 54 +- maven-plugin-api/pom.xml | 9 +- .../lifecycle/LifecycleXpp3ReaderTest.java | 3 +- .../maven/project/builder/DataSourceRule.java | 9 - .../maven/project/builder/JoinRule.java | 11 - .../builder/PomClassicDomainModel.java | 401 -------- .../builder/PomClassicDomainModelFactory.java | 16 - .../maven/project/builder/PomTransformer.java | 873 ------------------ .../builder/TransformerRemovalRule.java | 12 - .../project/builder/TransformerRule.java | 12 - .../AlwaysJoinModelContainerFactory.java | 63 -- .../ArtifactModelContainerFactory.java | 241 ----- .../ExclusionModelContainerFactory.java | 62 -- .../factories/IdModelContainerFactory.java | 127 --- ...luginExecutionIdModelContainerFactory.java | 86 -- ...luginReportSetIdModelContainerFactory.java | 85 -- .../builder/profile/ActiveProfileMatcher.java | 18 - .../builder/profile/ByDefaultMatcher.java | 24 - .../project/builder/profile/FileMatcher.java | 47 - .../profile/OperatingSystemMatcher.java | 62 -- .../builder/profile/ProfileContext.java | 88 -- .../project/builder/profile/ProfileUri.java | 178 ---- .../builder/profile/PropertyMatcher.java | 46 - ...DefaultDependencyScopeTransformerRule.java | 46 - .../DefaultExecutionIdTransformerRule.java | 29 - .../DependencyManagementDataSourceRule.java | 67 -- .../project/builder/rules/DependencyRule.java | 18 - .../DuplicateFiltersTransformerRule.java | 34 - .../project/builder/rules/ExecutionRule.java | 100 -- .../rules/MissingGroupIdTransformerRule.java | 27 - .../rules/MissingVersionTransformerRule.java | 27 - .../ModulesNotInheritedTransformerRule.java | 31 - .../NameNotInheritedTransformerRule.java | 33 - ...heritedPluginExecutionTransformerRule.java | 56 -- .../NotInheritedPluginTransformerRule.java | 51 - .../rules/OverideConfigTransformerRule.java | 61 -- .../PackagingNotInheritedTransformerRule.java | 30 - ...lativePathNotInheritedTransformerRule.java | 33 - .../project/builder/DefaultDomainModel.java | 44 - .../builder/DefaultDomainModelFactory.java | 14 - .../project/builder/EnforcerPomTest.java | 74 -- .../maven/project/builder/PluginSpecTest.java | 92 -- .../profile/DefaultModelContainer.java | 31 - .../builder/profile/FileMatcherTest.java | 81 -- .../builder/profile/JdkMatcherTest.java | 210 ----- .../builder/profile/ProfileContextTest.java | 129 --- .../builder/profile/PropertyMatcherTest.java | 52 -- .../builder/rules/ExecutionRuleTest.java | 31 - maven-project/pom.xml | 90 +- .../project/DefaultMavenProjectBuilder.java | 708 ++++++-------- .../DefaultProjectBuilderConfiguration.java | 14 +- .../apache/maven/project/MavenProject.java | 62 +- .../maven/project/MavenProjectBuilder.java | 3 + .../project/ProjectBuilderConfiguration.java | 4 + .../project/processor/BaseProcessor.java | 58 -- .../project/processor/BuildProcessor.java | 18 - .../processor/DependenciesProcessor.java | 18 - .../processor/DependencyProcessor.java | 5 - .../project/processor/ModelListener.java | 10 - .../project/processor/ModelProcessor.java | 66 -- .../project/processor/ModuleProcessor.java | 22 - .../project/processor/ParentProcessor.java | 29 - .../maven/project/processor/Processor.java | 9 - .../validation/DefaultModelValidator.java | 17 +- .../manager/DefaultProfileManagerTest.java | 25 +- .../profiles/matchers/JdkMatcherTest.java | 24 + .../project/AbstractMavenProjectTestCase.java | 2 +- .../maven/project/PomConstructionTest.java | 718 +++++++++++--- .../maven/project/ProjectClasspathTest.java | 2 + .../maven/project/harness/PomTestWrapper.java | 175 +--- .../t10/ProjectInheritanceTest.java | 3 +- .../t12scm/ProjectInheritanceTest.java | 13 +- .../project/processor/ModelProcessorTest.java | 127 --- .../maven/project/processor/ModuleTest.java | 54 -- .../baseurl-interpolation/pom.xml | 38 + .../boolean-interpolation/pom.xml | 82 ++ .../build-extension-inheritance/pom.xml | 49 + .../build-extension-inheritance/sub/pom.xml | 75 ++ .../complete-model/w-parent/pom.xml | 31 + .../complete-model/w-parent/sub/pom.xml | 319 +++++++ .../complete-model/wo-parent/pom.xml | 313 +++++++ .../pom.xml | 1 + .../dependency-inheritance/maven-parent.xml | 31 + .../dependency-inheritance/pom.xml | 48 + .../dependency-inheritance/sub}/pom.xml | 10 +- .../distribution-management/pom.xml | 39 + .../dual-execution-ids/sub/pom.xml | 2 +- .../empty-scm/pom.xml | 58 ++ .../pom.xml | 1 + .../active-profile/pom.xml | 50 + .../active-profile/sub/pom.xml | 54 ++ .../no-profile/pom.xml | 41 + .../no-profile/sub/pom.xml | 45 + .../jdk-activation/pom.xml | 105 +++ .../micromailer/pom.xml | 248 ++--- .../multiple-filters/pom.xml | 1 + .../{ => no-profile}/pom.xml | 0 .../{ => no-profile}/subproject/pom.xml | 0 .../plugin-config-append/with-profile/pom.xml | 90 ++ .../with-profile/subproject/pom.xml | 80 ++ .../plugin-config-properties/pom.xml | 1 + .../wo-plugin-mngt/sub/pom.xml | 2 +- .../plugin-inheritance-simple/pom.xml | 16 + .../plugin-inheritance-simple/sub/pom.xml | 20 + .../plugin-management-duplicate/pom.xml | 93 +- .../plugin-management-duplicate/sub/pom.xml | 64 ++ .../plugin-management-inheritance/pom.xml | 64 ++ .../pom-inheritance/pom.xml | 188 ++++ .../pom-inheritance/sub/pom.xml | 36 + .../profile-default-deactivation/pom.xml | 35 + .../profile-injection-order/pom.xml | 68 ++ .../profile-plugin-mng-dependencies/pom.xml | 77 ++ .../sub/pom.xml | 62 ++ .../profile-plugins/pom.xml | 50 + .../profile-properties-interpolation/pom.xml | 3 +- .../properties-inheritance/pom.xml | 34 + .../properties-inheritance/sub/pom.xml | 40 + .../properties-no-duplication/pom.xml | 11 + .../properties-no-duplication/sub/pom.xml | 17 + .../repo-inheritance/pom.xml | 64 ++ .../reporting-plugin-config/pom.xml | 51 + .../reporting-plugin-config/sub/pom.xml | 47 + .../unc-path/pom.xml | 41 + .../unc-path/sub/pom.xml | 57 ++ .../url-append/child/pom.xml | 64 ++ .../url-append/parent/pom.xml | 53 ++ .../url-inheritance/another-parent/pom.xml | 36 + .../another-parent/sub/pom.xml | 35 + .../url-no-decoding/pom.xml | 64 ++ maven-repository-mercury/pom.xml | 39 +- .../repository/mercury/MercuryAdaptor.java | 320 ++++++- .../mercury/MercuryRepositorySystem.java | 178 +++- .../mercury/MercuryRepositorySystemTest.java | 57 ++ maven-repository/pom.xml | 12 +- .../repository/LegacyRepositorySystem.java | 30 +- .../repository/MavenArtifactMetadata.java | 122 +++ .../maven/repository/MetadataGraph.java | 94 ++ .../maven/repository/MetadataGraphNode.java | 94 ++ .../repository/MetadataResolutionRequest.java | 158 ++-- .../repository/MetadataResolutionResult.java | 26 +- .../maven/repository/RepositorySystem.java | 11 +- .../LegacyMavenRepositorySystemTest.java | 5 +- maven-toolchain/pom.xml | 21 +- .../toolchain/DefaultToolchainManager.java | 226 ++--- .../DefaultToolchainManagerPrivate.java | 89 ++ .../toolchain/DefaultToolchainsBuilder.java | 85 ++ .../maven/toolchain/ToolchainsBuilder.java | 52 ++ .../java/DefaultJavaToolchainFactory.java | 2 +- mercury-ant-tasks-1.0-alpha-6-SNAPSHOT.jar | Bin 4929434 -> 5038193 bytes pom.xml | 653 ++++++------- 251 files changed, 12744 insertions(+), 6703 deletions(-) create mode 100644 README.bootstrap.mercury.txt create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java create mode 100644 maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java create mode 100644 maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java create mode 100644 maven-core/src/test/resources-settings/repositories/pom.xml create mode 100644 maven-core/src/test/resources-settings/repositories/settings.xml create mode 100644 maven-core/src/test/resources-settings/settings-no-pom/pom.xml create mode 100644 maven-core/src/test/resources-settings/settings-no-pom/settings.xml create mode 100644 maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml create mode 100644 maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml delete mode 100644 maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessor.java delete mode 100644 maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessorException.java create mode 100644 maven-model-builder/pom.xml create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/DomainModel.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/ModelEventListener.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/ModelListener.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/PomClassicDomainModel.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/Processor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/ProcessorContext.java rename {maven-project-builder/src/main/java/org/apache/maven/project/builder => maven-model-builder/src/main/java/org/apache/maven/model}/ProjectUri.java (99%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/interpolator/DefaultInterpolator.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/interpolator/Interpolator.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/interpolator/InterpolatorProperty.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/interpolator/ModelProperty.java rename {maven-project-builder/src/main/java/org/apache/maven/project/builder => maven-model-builder/src/main/java/org/apache/maven/model/interpolator}/PomInterpolatorTag.java (70%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/BaseProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/BuildProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/CiManagementProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ContributorsProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/DependenciesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyManagementProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/DevelopersProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/DistributionManagementProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/IssueManagementProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/LicensesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/MailingListProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ModelProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ModuleProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/OrganizationProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ParentProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsManagementProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/PrerequisitesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilePropertiesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesModuleProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/PropertiesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ReportingProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/RepositoriesProcessor.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/processors/ScmProcessor.java rename {maven-project => maven-model-builder}/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java (50%) rename {maven-project => maven-model-builder}/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java (97%) rename {maven-project => maven-model-builder}/src/main/java/org/apache/maven/profiles/ProfileActivationException.java (100%) rename {maven-project => maven-model-builder}/src/main/java/org/apache/maven/profiles/ProfileManager.java (93%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManagerInfo.java rename maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModelFactory.java => maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/DefaultMatcher.java (65%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/FileMatcher.java rename {maven-project-builder/src/main/java/org/apache/maven/project/builder/profile => maven-model-builder/src/main/java/org/apache/maven/profiles/matchers}/JdkMatcher.java (58%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/ProfileMatcher.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/PropertyMatcher.java rename {maven-project => maven-model-builder}/src/main/mdo/profiles.mdo (100%) rename {maven-project-builder => maven-model-builder}/src/main/resources/org/apache/maven/project/pom-4.0.0.xml (100%) rename {maven-project-builder => maven-model-builder}/src/test/projects/enforcer/enforcer-api/pom.xml (100%) rename {maven-project-builder => maven-model-builder}/src/test/projects/enforcer/enforcer-rules/pom.xml (100%) rename {maven-project-builder => maven-model-builder}/src/test/projects/enforcer/maven-enforcer-plugin/pom.xml (100%) rename {maven-project-builder => maven-model-builder}/src/test/projects/enforcer/pom.xml (100%) rename {maven-project-builder => maven-model-builder}/src/test/resources/test.txt (100%) delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/DataSourceRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/JoinRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModel.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModelFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/PomTransformer.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRemovalRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/AlwaysJoinModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ArtifactModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ExclusionModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/IdModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginExecutionIdModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginReportSetIdModelContainerFactory.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ActiveProfileMatcher.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ByDefaultMatcher.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/FileMatcher.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/OperatingSystemMatcher.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileContext.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileUri.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/PropertyMatcher.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultDependencyScopeTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultExecutionIdTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyManagementDataSourceRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DuplicateFiltersTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ExecutionRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingGroupIdTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingVersionTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ModulesNotInheritedTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NameNotInheritedTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginExecutionTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/OverideConfigTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/PackagingNotInheritedTransformerRule.java delete mode 100644 maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/RelativePathNotInheritedTransformerRule.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModel.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModelFactory.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/EnforcerPomTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/PluginSpecTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/DefaultModelContainer.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/FileMatcherTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/JdkMatcherTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/ProfileContextTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/PropertyMatcherTest.java delete mode 100644 maven-project-builder/src/test/java/org/apache/maven/project/builder/rules/ExecutionRuleTest.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/BaseProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/BuildProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/DependenciesProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/DependencyProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/ModelListener.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/ModelProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/ModuleProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/ParentProcessor.java delete mode 100644 maven-project/src/main/java/org/apache/maven/project/processor/Processor.java create mode 100644 maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java delete mode 100644 maven-project/src/test/java/org/apache/maven/project/processor/ModelProcessorTest.java delete mode 100644 maven-project/src/test/java/org/apache/maven/project/processor/ModuleTest.java create mode 100644 maven-project/src/test/resources-project-builder/baseurl-interpolation/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/boolean-interpolation/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/build-extension-inheritance/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/complete-model/w-parent/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/complete-model/wo-parent/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml create mode 100644 maven-project/src/test/resources-project-builder/dependency-inheritance/pom.xml rename {maven-project-builder => maven-project/src/test/resources-project-builder/dependency-inheritance/sub}/pom.xml (85%) create mode 100644 maven-project/src/test/resources-project-builder/distribution-management/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/empty-scm/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/jdk-activation/pom.xml rename maven-project/src/test/resources-project-builder/plugin-config-append/{ => no-profile}/pom.xml (100%) rename maven-project/src/test/resources-project-builder/plugin-config-append/{ => no-profile}/subproject/pom.xml (100%) create mode 100644 maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/plugin-management-inheritance/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/pom-inheritance/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/pom-inheritance/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/profile-default-deactivation/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/profile-injection-order/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/profile-plugins/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/properties-inheritance/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/properties-inheritance/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/properties-no-duplication/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/repo-inheritance/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/reporting-plugin-config/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/unc-path/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/unc-path/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/url-append/child/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/url-append/parent/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml create mode 100644 maven-project/src/test/resources-project-builder/url-no-decoding/pom.xml create mode 100644 maven-repository/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java create mode 100644 maven-repository/src/main/java/org/apache/maven/repository/MetadataGraph.java create mode 100644 maven-repository/src/main/java/org/apache/maven/repository/MetadataGraphNode.java rename {maven-project => maven-repository}/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java (84%) create mode 100644 maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java create mode 100644 maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java create mode 100644 maven-toolchain/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java diff --git a/README.bootstrap.mercury.txt b/README.bootstrap.mercury.txt new file mode 100644 index 0000000000..fe034fac6f --- /dev/null +++ b/README.bootstrap.mercury.txt @@ -0,0 +1,36 @@ +BOOTSTRAPPING BASICS +----------------------- + +You'll need: + +- Java 1.5 +- Ant 1.6.5 or later + +First, give Ant a location into which the completed Maven distro should be installed: + + export M2_HOME=$HOME/apps/maven/apache-maven-3.0-SNAPSHOT + +Then, run Ant: + + ant -f build-mercury.xml + +You can use additiona options on ant command line: + +-Dmaven.repo.update.policy={never|always|daily} +-Dmaven.repo.system={mercury|legacy} +-Dmaven.home=$HOME/apps/maven/apache-maven-3.0-SNAPSHOT + +if you'd like to debug the bootstrap from Eclipse, uncomment the debugging options in the build-mercury.xml around +line 310, then use the following commands: + +For the first time - run the following, it will update the local repo + +ant -f build-mercury.xml -Dmaven.repo.update.policy=always -Dmaven.repo.system=mercury + +then you can run + +ant -f build-mercury.xml -Dmaven.repo.update.policy=never -Dmaven.repo.system=mercury + +not to bother with repo updates + + \ No newline at end of file diff --git a/README.bootstrap.txt b/README.bootstrap.txt index 0ca9b0bb50..76a42a018a 100644 --- a/README.bootstrap.txt +++ b/README.bootstrap.txt @@ -8,7 +8,7 @@ You'll need: First, give Ant a location into which the completed Maven distro should be installed: - export M2_HOME=$HOME/apps/maven/apache-maven-2.1-SNAPSHOT + export M2_HOME=$HOME/apps/maven/apache-maven-3.0-SNAPSHOT Then, run Ant: diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml index 59b6dbdd85..77b2f8d775 100644 --- a/apache-maven/pom.xml +++ b/apache-maven/pom.xml @@ -1,4 +1,5 @@ + + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT + apache-maven + Maven Distribution + org.apache.maven @@ -82,6 +88,7 @@ ${mercuryVersion} + @@ -97,6 +104,7 @@ + standard diff --git a/build-mercury.xml b/build-mercury.xml index 354a9a5cb9..b76109cbb3 100644 --- a/build-mercury.xml +++ b/build-mercury.xml @@ -67,7 +67,13 @@ END SNIPPET: ant-bootstrap --> + + + + @@ -87,15 +93,61 @@ END SNIPPET: ant-bootstrap --> + + + + + + + + + + + + + + + maven.repo.system is ${maven.repo.system}, flip: legacy-hint=${legacy-hint}, mercury-hint=${mercury-hint} + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + @@ -121,10 +173,10 @@ END SNIPPET: ant-bootstrap --> mercury.classpath=${mc} ======================================================================== - + @@ -209,14 +261,15 @@ END SNIPPET: ant-bootstrap --> + - + - + @@ -244,12 +297,22 @@ END SNIPPET: ant-bootstrap --> - + + diff --git a/build.xml b/build.xml index 50562cf004..1e4d5c5170 100644 --- a/build.xml +++ b/build.xml @@ -78,8 +78,8 @@ END SNIPPET: ant-bootstrap --> - - + + @@ -165,7 +165,7 @@ END SNIPPET: ant-bootstrap --> - + diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml index 6f1ba8a823..ba025334b1 100644 --- a/maven-compat/pom.xml +++ b/maven-compat/pom.xml @@ -1,4 +1,5 @@ + + + 4.0.0 + org.apache.maven maven 3.0-SNAPSHOT - 4.0.0 + maven-compat + Maven Compat + org.apache.maven @@ -46,6 +52,7 @@ test + diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java b/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java index 3bce207c9a..582cceee43 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java @@ -324,6 +324,11 @@ public class DefaultWagonManager public void getArtifact( Artifact artifact, List remoteRepositories, TransferListener downloadMonitor, boolean force ) throws TransferFailedException, ResourceDoesNotExistException { + if(remoteRepositories == null) + { + throw new IllegalArgumentException("remoteRepositories: null"); + } + for ( ArtifactRepository repository : remoteRepositories ) { try diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java b/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java index 83d0d6f346..ce9ddf2ce7 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java @@ -88,4 +88,6 @@ public interface WagonManager void addAuthenticationInfo( String repositoryId, String username, String password, String privateKey, String passphrase ); + void addProxy( String protocol, String host, int port, String username, String password, String nonProxyHosts ); + } diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java index d19e7268e6..4e4d7461f6 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java @@ -55,4 +55,9 @@ public class IncludesArtifactFilter } return matched; } + + public List getPatterns() + { + return patterns; + } } diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java index c16c1abf86..a3445502c3 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java @@ -39,9 +39,13 @@ public class ScopeArtifactFilter private final boolean providedScope; private final boolean systemScope; + + private final String scope; public ScopeArtifactFilter( String scope ) { + this.scope = scope; + if ( Artifact.SCOPE_COMPILE.equals( scope ) ) { systemScope = true; @@ -111,4 +115,9 @@ public class ScopeArtifactFilter return true; } } + + public String getScope() + { + return scope; + } } diff --git a/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java b/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java index 3621d5b29f..3b9f82152d 100644 --- a/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java +++ b/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java @@ -26,6 +26,7 @@ import java.util.List; import org.apache.maven.model.Build; import org.apache.maven.model.Model; +import org.apache.maven.model.Reporting; import org.apache.maven.model.Resource; import org.codehaus.plexus.component.annotations.Component; @@ -77,6 +78,13 @@ public class DefaultPathTranslator build.setTestOutputDirectory( alignToBaseDirectory( build.getTestOutputDirectory(), basedir ) ); } + + Reporting reporting = model.getReporting(); + + if ( reporting != null ) + { + reporting.setOutputDirectory( alignToBaseDirectory( reporting.getOutputDirectory(), basedir ) ); + } } public String alignToBaseDirectory( String path, File basedir ) @@ -204,6 +212,13 @@ public class DefaultPathTranslator build.setTestOutputDirectory( unalignFromBaseDirectory( build.getTestOutputDirectory(), basedir ) ); } + + Reporting reporting = model.getReporting(); + + if ( reporting != null ) + { + reporting.setOutputDirectory( unalignFromBaseDirectory( reporting.getOutputDirectory(), basedir ) ); + } } public String unalignFromBaseDirectory( String directory, File basedir ) diff --git a/maven-core/pom.xml b/maven-core/pom.xml index 723b17ed1a..95ef82e180 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -11,14 +11,18 @@ --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-core + Maven Core + @@ -39,7 +43,7 @@ org.apache.maven - maven-project-builder + maven-model-builder - - org.apache.maven.wagon - wagon-file - test - - - easymock - easymock - test - + diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 3f20a241b1..eb4892db8b 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -211,7 +211,7 @@ public class DefaultMaven File basedir = file.getParentFile(); List moduleFiles = new ArrayList(); - + for ( String name : project.getModules() ) { if ( StringUtils.isEmpty( StringUtils.trim( name ) ) ) diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java index facb5ea791..9539d324e1 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java @@ -67,6 +67,8 @@ public class DefaultMavenExecutionRequest private File globalSettingsFile; + private File userToolchainsFile; + // ---------------------------------------------------------------------------- // Request // ---------------------------------------------------------------------------- @@ -130,6 +132,7 @@ public class DefaultMavenExecutionRequest copy.setProjectPresent( original.isProjectPresent() ); copy.setUserSettingsFile( original.getUserSettingsFile() ); copy.setGlobalSettingsFile( original.getGlobalSettingsFile() ); + copy.setUserToolchainsFile( original.getUserToolchainsFile() ); copy.setBaseDirectory( new File( original.getBaseDirectory() ) ); copy.setGoals( original.getGoals() ); copy.setRecursive( original.isRecursive() ); @@ -611,7 +614,7 @@ public class DefaultMavenExecutionRequest return this; } - // Settin10gs files + // Settings files public File getUserSettingsFile() { @@ -637,6 +640,18 @@ public class DefaultMavenExecutionRequest return this; } + public File getUserToolchainsFile() + { + return userToolchainsFile; + } + + public MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile ) + { + this.userToolchainsFile = userToolchainsFile; + + return this; + } + public MavenExecutionRequest addRemoteRepository( ArtifactRepository repository ) { if ( remoteRepositories == null ) diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java index bf5a52e481..3c3d919fce 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java @@ -212,5 +212,8 @@ public interface MavenExecutionRequest MavenExecutionRequest setRemoteRepositories( List repositories ); List getRemoteRepositories(); + File getUserToolchainsFile(); + MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile ); + ProjectBuilderConfiguration getProjectBuildingConfiguration(); } diff --git a/maven-core/src/main/java/org/apache/maven/listeners/BuildExtensionListener.java b/maven-core/src/main/java/org/apache/maven/listeners/BuildExtensionListener.java index d529548f9a..affad9d271 100644 --- a/maven-core/src/main/java/org/apache/maven/listeners/BuildExtensionListener.java +++ b/maven-core/src/main/java/org/apache/maven/listeners/BuildExtensionListener.java @@ -2,17 +2,13 @@ package org.apache.maven.listeners; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.execution.MavenSession; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelProperty; +import org.apache.maven.model.Extension; +import org.apache.maven.model.Model; +import org.apache.maven.model.ProjectUri; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Configuration; @@ -43,81 +39,17 @@ public class BuildExtensionListener @Requirement PlexusPluginManager pluginManager; - private List buildExtensions = new ArrayList(); - - public void fire(List modelContainers) - throws DataSourceException - { - if ( !inBuild ) - { - return; - } - - for ( ModelContainer mc : modelContainers ) - { - if ( hasExtension( mc ) ) - { - buildExtensions.add( new BuildExtension( mc.getProperties() ) ); - } - } + private List buildExtensions = new ArrayList(); + + public void fire(Model model) + { + buildExtensions.addAll(new ArrayList(model.getBuild().getExtensions())); } public List getUris() { return Arrays.asList( ProjectUri.Build.Extensions.Extension.xUri ); } - - public Collection getModelContainerFactories() - { - return Arrays.asList( (ModelContainerFactory) new ArtifactModelContainerFactory() ); - } - - private static boolean hasExtension( ModelContainer container ) - { - for ( ModelProperty mp : container.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Build.Extensions.Extension.xUri ) ) - { - return true; - } - } - return false; - } - - private static class BuildExtension - { - private String groupId; - - private String artifactId; - - private String version; - - public BuildExtension( String groupId, String artifactId, String version ) - { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - } - - BuildExtension( List modelProperties ) - { - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().equals( ProjectUri.Build.Extensions.Extension.groupId ) ) - { - groupId = mp.getValue(); - } - else if ( mp.getUri().equals( ProjectUri.Build.Extensions.Extension.artifactId ) ) - { - artifactId = mp.getValue(); - } - else if ( mp.getUri().equals( ProjectUri.Build.Extensions.Extension.version ) ) - { - version = mp.getValue(); - } - } - } - } /** * Take the extension elements that were found during the POM construction process and now @@ -129,11 +61,16 @@ public class BuildExtensionListener * @param session Maven session used as the execution context for the current Maven project. */ public void processModelContainers( MavenSession session ) - { - for ( BuildExtension be : buildExtensions ) + { + if(!inBuild) + { + return; + } + + for ( Extension be : buildExtensions ) { PluginResolutionRequest request = new PluginResolutionRequest() - .setPluginMetadata( new PluginMetadata( be.groupId, be.artifactId, be.version ) ) + .setPluginMetadata( new PluginMetadata( be.getGroupId(), be.getArtifactId(), be.getVersion() ) ) .addLocalRepository( session.getRequest().getLocalRepositoryPath() ) .setRemoteRepositories( convertToMercuryRepositories( session.getRequest().getRemoteRepositories() ) ); diff --git a/maven-core/src/main/java/org/apache/maven/listeners/MavenModelEventListener.java b/maven-core/src/main/java/org/apache/maven/listeners/MavenModelEventListener.java index d122a6624b..8e180d96ec 100644 --- a/maven-core/src/main/java/org/apache/maven/listeners/MavenModelEventListener.java +++ b/maven-core/src/main/java/org/apache/maven/listeners/MavenModelEventListener.java @@ -1,7 +1,8 @@ package org.apache.maven.listeners; import org.apache.maven.execution.MavenSession; -import org.apache.maven.shared.model.ModelEventListener; +import org.apache.maven.model.ModelEventListener; + public interface MavenModelEventListener extends ModelEventListener diff --git a/maven-core/src/main/mdo/settings.mdo b/maven-core/src/main/mdo/settings.mdo index 99afcb914f..409054e5e5 100644 --- a/maven-core/src/main/mdo/settings.mdo +++ b/maven-core/src/main/mdo/settings.mdo @@ -292,28 +292,19 @@ */ public synchronized Proxy getActiveProxy() { - if(activeProxy == null) + if (activeProxy == null) { - java.util.List proxies = getProxies(); + java.util.List proxies = getProxies(); if ( proxies != null && !proxies.isEmpty() ) { - if ( proxies.size() > 1 ) + for ( Proxy proxy : proxies ) { - for ( java.util.Iterator it = proxies.iterator(); it.hasNext(); ) + if ( proxy.isActive() ) { - Proxy proxy = (Proxy) it.next(); - if ( proxy.isActive() ) - { - activeProxy = proxy; - break; - } + activeProxy = proxy; + break; } } - else - { - // If we only have one proxy, use it as the active one. - activeProxy = (Proxy) proxies.get( 0 ); - } } } @@ -464,7 +455,7 @@ active 1.0.0 false - false + true modelProperties = new ArrayList(); - modelProperties.add( new ModelProperty( ProjectUri.Build.Extensions.Extension.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Build.Extensions.Extension.groupId, "org.apache.maven.wagon" ) ); - modelProperties.add( new ModelProperty( ProjectUri.Build.Extensions.Extension.artifactId, "wagon-webdav" ) ); - modelProperties.add( new ModelProperty( ProjectUri.Build.Extensions.Extension.version, "1.0-beta-2" ) ); - ModelContainer container = new TestModelContainer( modelProperties ); - + Extension extension = new Extension(); + extension.setGroupId("org.apache.maven.wagon" ); + extension.setArtifactId("wagon-webdav" ); + extension.setVersion( "1.0-beta-2" ); + + Build build = new Build(); + build.addExtension(extension); + + Model model = new Model(); + model.setBuild(build); + // Fire the event. - listener.fire( Arrays.asList( container ) ); + listener.fire( model ); try { @@ -55,7 +53,7 @@ public class BuildExtensionListenerTest listener.processModelContainers( newMavenSession() ); // Now we should be able to find the extension. - // lookup( Wagon.class, "dav" ); + lookup( Wagon.class, "dav" ); } private MavenSession newMavenSession() @@ -75,29 +73,4 @@ public class BuildExtensionListenerTest return session; } - public class TestModelContainer - implements ModelContainer - { - List modelProperties; - - public TestModelContainer( List properties ) - { - this.modelProperties = properties; - } - - public List getProperties() - { - return new ArrayList( modelProperties ); - } - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - return null; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return null; - } - } } diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java b/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java new file mode 100644 index 0000000000..b60158aa90 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java @@ -0,0 +1,173 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.*; +import java.util.Iterator; + +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.jxpath.JXPathNotFoundException; +import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl; +import org.apache.maven.model.PomClassicDomainModel; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +public class PomTestWrapper +{ + private PomClassicDomainModel domainModel; + + private File pomFile; + + private JXPathContext context; + + private MavenProject mavenProject; + + static + { + JXPathContextReferenceImpl.addNodePointerFactory( new Xpp3DomPointerFactory() ); + } + + public PomTestWrapper( PomClassicDomainModel domainModel ) + throws IOException + { + this( null, domainModel ); + } + + public PomTestWrapper( File pomFile, PomClassicDomainModel domainModel ) + throws IOException + { + if ( domainModel == null ) + { + throw new IllegalArgumentException( "domainModel: null" ); + } + this.domainModel = domainModel; + this.pomFile = pomFile; + try { + context = JXPathContext.newContext( new MavenXpp3Reader().read(domainModel.getInputStream())); + } catch (XmlPullParserException e) { + throw new IOException(e.getMessage()); + } + } + + public PomTestWrapper( File pomFile, MavenProject mavenProject ) + throws IOException + { + if ( mavenProject == null ) + { + throw new IllegalArgumentException( "mavenProject: null" ); + } + this.mavenProject = mavenProject; + this.pomFile = pomFile; + context = JXPathContext.newContext( mavenProject.getModel() ); + } + + public PomTestWrapper( MavenProject mavenProject ) + throws IOException + { + if ( mavenProject == null ) + { + throw new IllegalArgumentException( "mavenProject: null" ); + } + this.mavenProject = mavenProject; + context = JXPathContext.newContext( mavenProject.getModel() ); + } + + public PomTestWrapper( File file ) + throws IOException + { + if ( file == null ) + { + throw new IllegalArgumentException( "file: null" ); + } + + this.domainModel = new PomClassicDomainModel( file ); + try { + context = JXPathContext.newContext( new MavenXpp3Reader().read(domainModel.getInputStream())); + } catch (XmlPullParserException e) { + throw new IOException(e.getMessage()); + } + } + + public MavenProject getMavenProject() + { + return mavenProject; + } + + public PomClassicDomainModel getDomainModel() + { + if ( domainModel == null && mavenProject != null ) + { + try + { + domainModel = new PomClassicDomainModel( mavenProject.getModel() ); + int lineageCount = 1; + for ( MavenProject parent = mavenProject.getParent(); parent != null; parent = parent.getParent() ) + { + lineageCount++; + } + domainModel.setLineageCount( lineageCount ); + } + catch ( IOException e ) + { + + } + } + + return this.domainModel; + } + + public File getBasedir() + { + return ( pomFile != null ) ? pomFile.getParentFile() : null; + } + + public void setValueOnModel( String expression, Object value ) + { + context.setValue( expression, value ); + } + + public Iterator getIteratorForXPathExpression( String expression ) + { + return context.iterate( expression ); + } + + public boolean containsXPathExpression( String expression ) + { + return context.getValue( expression ) != null; + } + + public Object getValue( String expression ) + { + try + { + return context.getValue( expression ); + } + catch ( JXPathNotFoundException e ) + { + return null; + } + } + + public boolean xPathExpressionEqualsValue( String expression, String value ) + { + return context.getValue( expression ) != null && context.getValue( expression ).equals( value ); + } +} diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java new file mode 100644 index 0000000000..73faa7d0bd --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java @@ -0,0 +1,90 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.jxpath.ri.QName; +import org.apache.commons.jxpath.ri.model.NodeIterator; +import org.apache.commons.jxpath.ri.model.NodePointer; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * An attribute iterator for JXPath to support Xpp3Dom. + * + * @author Benjamin Bentmann + * @version $Id: Xpp3DomAttributeIterator.java 747943 2009-02-25 22:28:48Z bentmann $ + */ +class Xpp3DomAttributeIterator + implements NodeIterator +{ + + private NodePointer parent; + + private Xpp3Dom node; + + private List> attributes; + + private Map.Entry attribute; + + private int position; + + public Xpp3DomAttributeIterator( NodePointer parent, QName qname ) + { + this.parent = parent; + this.node = (Xpp3Dom) parent.getNode(); + + Map map = new LinkedHashMap(); + for ( String name : this.node.getAttributeNames() ) + { + if ( name.equals( qname.getName() ) || "*".equals( qname.getName() ) ) + { + String value = this.node.getAttribute( name ); + map.put( name, value ); + } + } + this.attributes = new ArrayList>( map.entrySet() ); + } + + public NodePointer getNodePointer() + { + if ( position == 0 ) + { + setPosition( 1 ); + } + return ( attribute == null ) ? null : new Xpp3DomAttributePointer( parent, attribute ); + } + + public int getPosition() + { + return position; + } + + public boolean setPosition( int position ) + { + this.position = position; + attribute = ( position > 0 && position <= attributes.size() ) ? attributes.get( position - 1 ) : null; + return attribute != null; + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java new file mode 100644 index 0000000000..e1aa29f36b --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java @@ -0,0 +1,105 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Map; + +import org.apache.commons.jxpath.ri.QName; +import org.apache.commons.jxpath.ri.model.NodePointer; + +/** + * An attribute pointer for JXPath to support Xpp3Dom. + * + * @author Benjamin Bentmann + */ +class Xpp3DomAttributePointer + extends NodePointer +{ + + private Map.Entry attrib; + + public Xpp3DomAttributePointer( NodePointer parent, Map.Entry attrib ) + { + super( parent ); + this.attrib = attrib; + } + + @Override + public int compareChildNodePointers( NodePointer pointer1, NodePointer pointer2 ) + { + // should never happen because attributes have no children + return 0; + } + + @Override + public Object getValue() + { + return attrib.getValue(); + } + + @Override + public Object getBaseValue() + { + return attrib; + } + + @Override + public Object getImmediateNode() + { + return attrib; + } + + @Override + public int getLength() + { + return 1; + } + + @Override + public QName getName() + { + return new QName( null, attrib.getKey() ); + } + + @Override + public boolean isActual() + { + return true; + } + + @Override + public boolean isCollection() + { + return false; + } + + @Override + public boolean isLeaf() + { + return true; + } + + @Override + public void setValue( Object value ) + { + throw new UnsupportedOperationException(); + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java new file mode 100644 index 0000000000..d34e2a9a04 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java @@ -0,0 +1,161 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.jxpath.ri.Compiler; +import org.apache.commons.jxpath.ri.compiler.NodeNameTest; +import org.apache.commons.jxpath.ri.compiler.NodeTest; +import org.apache.commons.jxpath.ri.compiler.NodeTypeTest; +import org.apache.commons.jxpath.ri.model.NodeIterator; +import org.apache.commons.jxpath.ri.model.NodePointer; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * A node iterator for JXPath to support Xpp3Dom. + * + * @author Benjamin Bentmann + * @version $Id: Xpp3DomNodeIterator.java 737056 2009-01-23 15:35:43Z bentmann $ + */ +class Xpp3DomNodeIterator + implements NodeIterator +{ + + private NodePointer parent; + + private NodeTest test; + + private Xpp3Dom node; + + private Xpp3Dom[] children; + + private List filteredChildren = new ArrayList(); + + private int filteredIndex; + + private Xpp3Dom child; + + private int position; + + public Xpp3DomNodeIterator( NodePointer parent, NodeTest test, boolean reverse, NodePointer startWith ) + { + this.parent = parent; + this.node = (Xpp3Dom) parent.getNode(); + this.children = this.node.getChildren(); + if ( startWith != null ) + { + for ( ; filteredIndex < children.length; filteredIndex++ ) + { + if ( startWith.equals( children[filteredIndex] ) ) + { + filteredIndex++; + break; + } + } + } + this.test = test; + if ( reverse ) + { + throw new UnsupportedOperationException(); + } + } + + public NodePointer getNodePointer() + { + if ( position == 0 ) + { + setPosition( 1 ); + } + return ( child == null ) ? null : new Xpp3DomNodePointer( parent, child ); + } + + public int getPosition() + { + return position; + } + + public boolean setPosition( int position ) + { + this.position = position; + filterChildren( position ); + child = ( position > 0 && position <= filteredChildren.size() ) ? filteredChildren.get( position - 1 ) : null; + return child != null; + } + + private void filterChildren( int position ) + { + for ( ; position > filteredChildren.size() && filteredIndex < children.length; filteredIndex++ ) + { + Xpp3Dom child = children[filteredIndex]; + if ( testNode( child ) ) + { + filteredChildren.add( child ); + } + } + } + + private boolean testNode( Xpp3Dom node ) + { + if ( test == null ) + { + return true; + } + if ( test instanceof NodeNameTest ) + { + String nodeName = node.getName(); + if ( StringUtils.isEmpty( nodeName ) ) + { + return false; + } + + NodeNameTest nodeNameTest = (NodeNameTest) test; + String namespaceURI = nodeNameTest.getNamespaceURI(); + boolean wildcard = nodeNameTest.isWildcard(); + String testName = nodeNameTest.getNodeName().getName(); + String testPrefix = nodeNameTest.getNodeName().getPrefix(); + if ( wildcard && testPrefix == null ) + { + return true; + } + if ( wildcard || testName.equals( nodeName ) ) + { + return StringUtils.isEmpty( namespaceURI ) || StringUtils.isEmpty( testPrefix ); + } + return false; + } + if ( test instanceof NodeTypeTest ) + { + switch ( ( (NodeTypeTest) test ).getNodeType() ) + { + case Compiler.NODE_TYPE_NODE: + return true; + case Compiler.NODE_TYPE_TEXT: + return node.getValue() != null; + default: + return false; + } + } + return false; + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java new file mode 100644 index 0000000000..46b87c110c --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java @@ -0,0 +1,156 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.jxpath.ri.QName; +import org.apache.commons.jxpath.ri.compiler.NodeTest; +import org.apache.commons.jxpath.ri.model.NodeIterator; +import org.apache.commons.jxpath.ri.model.NodePointer; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * A node pointer for JXPath to support Xpp3Dom. + * + * @author Benjamin Bentmann + * @version $Id: Xpp3DomNodePointer.java 747943 2009-02-25 22:28:48Z bentmann $ + */ +class Xpp3DomNodePointer + extends NodePointer +{ + + private Xpp3Dom node; + + public Xpp3DomNodePointer( Xpp3Dom node ) + { + super( null ); + this.node = node; + } + + public Xpp3DomNodePointer( NodePointer parent, Xpp3Dom node ) + { + super( parent ); + this.node = node; + } + + @Override + public int compareChildNodePointers( NodePointer pointer1, NodePointer pointer2 ) + { + Xpp3Dom node1 = (Xpp3Dom) pointer1.getBaseValue(); + Xpp3Dom node2 = (Xpp3Dom) pointer2.getBaseValue(); + if ( node1 == node2 ) + { + return 0; + } + for ( int i = 0; i < node.getChildCount(); i++ ) + { + Xpp3Dom child = node.getChild( i ); + if ( child == node1 ) + { + return -1; + } + if ( child == node2 ) + { + return 1; + } + } + return 0; + } + + @Override + public Object getValue() + { + return getValue(node); + } + + private static Object getValue( Xpp3Dom node ) + { + if ( node.getValue() != null ) + { + return node.getValue().trim(); + } + else + { + List children = new ArrayList(); + for ( int i = 0; i < node.getChildCount(); i++ ) + { + children.add( getValue( node.getChild( i ) ) ); + } + return children; + } + } + + @Override + public Object getBaseValue() + { + return node; + } + + @Override + public Object getImmediateNode() + { + return node; + } + + @Override + public int getLength() + { + return 1; + } + + @Override + public QName getName() + { + return new QName( null, node.getName() ); + } + + @Override + public boolean isCollection() + { + return false; + } + + @Override + public boolean isLeaf() + { + return node.getChildCount() <= 0; + } + + @Override + public void setValue( Object value ) + { + throw new UnsupportedOperationException(); + } + + @Override + public NodeIterator childIterator( NodeTest test, boolean reverse, NodePointer startWith ) + { + return new Xpp3DomNodeIterator( this, test, reverse, startWith ); + } + + @Override + public NodeIterator attributeIterator( QName qname ) + { + return new Xpp3DomAttributeIterator( this, qname ); + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java new file mode 100644 index 0000000000..8262c95562 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java @@ -0,0 +1,62 @@ +package org.apache.maven.project.harness; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; + +import org.apache.commons.jxpath.ri.QName; +import org.apache.commons.jxpath.ri.model.NodePointer; +import org.apache.commons.jxpath.ri.model.NodePointerFactory; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * A node pointer factory for JXPath to support Xpp3Dom. + * + * @author Benjamin Bentmann + * @version $Id: Xpp3DomPointerFactory.java 737056 2009-01-23 15:35:43Z bentmann $ + */ +class Xpp3DomPointerFactory + implements NodePointerFactory +{ + + public int getOrder() + { + return 200; + } + + public NodePointer createNodePointer( QName name, Object object, Locale locale ) + { + if ( object instanceof Xpp3Dom ) + { + return new Xpp3DomNodePointer( (Xpp3Dom) object ); + } + return null; + } + + public NodePointer createNodePointer( NodePointer parent, QName name, Object object ) + { + if ( object instanceof Xpp3Dom ) + { + return new Xpp3DomNodePointer( parent, (Xpp3Dom) object ); + } + return null; + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java new file mode 100644 index 0000000000..05055d1644 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java @@ -0,0 +1,124 @@ +package org.apache.maven.settings; + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.util.List; + +import org.apache.maven.artifact.repository.DefaultArtifactRepository; +import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; +import org.apache.maven.model.Profile; +import org.apache.maven.profiles.DefaultProfileManager; +import org.apache.maven.profiles.ProfileActivationContext; +import org.apache.maven.profiles.ProfileManager; +import org.apache.maven.project.DefaultMavenProjectBuilder; +import org.apache.maven.project.DefaultProjectBuilderConfiguration; +import org.apache.maven.project.MavenProjectBuilder; +import org.apache.maven.project.ProjectBuilderConfiguration; +import org.apache.maven.project.harness.PomTestWrapper; +import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader; +import org.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +public class PomConstructionWithSettingsTest + extends PlexusTestCase +{ + private static String BASE_DIR = "src/test"; + + private static String BASE_POM_DIR = BASE_DIR + "/resources-settings"; + + private DefaultMavenProjectBuilder mavenProjectBuilder; + + private File testDirectory; + + protected void setUp() + throws Exception + { + testDirectory = new File( getBasedir(), BASE_POM_DIR ); + mavenProjectBuilder = (DefaultMavenProjectBuilder) lookup( MavenProjectBuilder.class ); + } + + public void testSettingsNoPom() throws Exception + { + PomTestWrapper pom = buildPom( "settings-no-pom" ); + assertEquals( "local-profile-prop-value", pom.getValue( "properties/local-profile-prop" ) ); + } + + /**MNG-4107 */ + public void testPomAndSettingsInterpolation() throws Exception + { + PomTestWrapper pom = buildPom( "test-pom-and-settings-interpolation" ); + assertEquals("applied", pom.getValue( "properties/settingsProfile" ) ); + assertEquals("applied", pom.getValue( "properties/pomProfile" ) ); + assertEquals("settings", pom.getValue( "properties/pomVsSettings" ) ); + assertEquals("settings", pom.getValue( "properties/pomVsSettingsInterpolated" ) ); + } + + /**MNG-4107 */ + public void testRepositories() throws Exception + { + PomTestWrapper pom = buildPom( "repositories" ); + assertEquals("maven-core-it-0", pom.getValue( "repositories[1]/id" )); + System.out.println(pom.getDomainModel().asString()); + } + + private PomTestWrapper buildPom( String pomPath ) + throws Exception + { + File pomFile = new File( testDirectory + File.separator + pomPath , "pom.xml" ); + File settingsFile = new File( testDirectory + File.separator + pomPath, "settings.xml" ); + + Settings settings = readSettingsFile(settingsFile); + + ProfileActivationContext pCtx = new ProfileActivationContext(null, true); + ProfileManager profileManager = new DefaultProfileManager(pCtx); + + for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() ) + { + Profile profile = SettingsUtils.convertFromSettingsProfile( rawProfile ); + + profileManager.addProfile( profile ); + } + + List settingsActiveProfileIds = settings.getActiveProfiles(); + + if ( settingsActiveProfileIds != null ) + { + for ( String profileId : settingsActiveProfileIds ) + { + profileManager.getProfileActivationContext().setActive( profileId ); + } + } + + ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration(); + config.setLocalRepository(new DefaultArtifactRepository("default", "", new DefaultRepositoryLayout())); + + config.setGlobalProfileManager(profileManager); + return new PomTestWrapper( pomFile, mavenProjectBuilder.build( pomFile, config ) ); + } + + private static Settings readSettingsFile(File settingsFile) + throws IOException, XmlPullParserException + { + Settings settings = null; + + Reader reader = null; + + try + { + reader = ReaderFactory.newXmlReader( settingsFile ); + + SettingsXpp3Reader modelReader = new SettingsXpp3Reader(); + + settings = modelReader.read( reader ); + } + finally + { + IOUtil.close( reader ); + } + + return settings; + } +} diff --git a/maven-core/src/test/resources-settings/repositories/pom.xml b/maven-core/src/test/resources-settings/repositories/pom.xml new file mode 100644 index 0000000000..97023414fb --- /dev/null +++ b/maven-core/src/test/resources-settings/repositories/pom.xml @@ -0,0 +1,29 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4107 + test + 1.0-SNAPSHOT + jar + diff --git a/maven-core/src/test/resources-settings/repositories/settings.xml b/maven-core/src/test/resources-settings/repositories/settings.xml new file mode 100644 index 0000000000..6f96f0b6f8 --- /dev/null +++ b/maven-core/src/test/resources-settings/repositories/settings.xml @@ -0,0 +1,55 @@ + + + + + + + + maven-core-it-repo + + + maven-core-it-0 + @baseurl@/repo-0 + + ignore + + + false + + + + + + maven-core-it-1 + @baseurl@/repo-1 + + ignore + + + ignore + + + + + + + maven-core-it-repo + + diff --git a/maven-core/src/test/resources-settings/settings-no-pom/pom.xml b/maven-core/src/test/resources-settings/settings-no-pom/pom.xml new file mode 100644 index 0000000000..ee62782619 --- /dev/null +++ b/maven-core/src/test/resources-settings/settings-no-pom/pom.xml @@ -0,0 +1,13 @@ + + + + 4.0.0 + + org.apache.maven.its.mng3099 + maven-mng3099-plugin + 1 + maven-plugin + + maven-mng3099-plugin + Tests properties injected as a result of active profiles in the user settings file. + \ No newline at end of file diff --git a/maven-core/src/test/resources-settings/settings-no-pom/settings.xml b/maven-core/src/test/resources-settings/settings-no-pom/settings.xml new file mode 100644 index 0000000000..b03bb53f85 --- /dev/null +++ b/maven-core/src/test/resources-settings/settings-no-pom/settings.xml @@ -0,0 +1,20 @@ + + + + + + local-profile + + local-profile-prop-value + + + + + + local-profile + + + diff --git a/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml b/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml new file mode 100644 index 0000000000..4d2f61d961 --- /dev/null +++ b/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml @@ -0,0 +1,78 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4107 + test + 1.0-SNAPSHOT + jar + + Maven Integration Test :: MNG-4107 + + Test that POM interpolation uses the property values from the dominant profile source (POM vs. profiles.xml + vs. settings.xml). This boils down to the proper order of profile injection and interpolation, i.e. + interpolate after profiles from all sources are injected. + + + + + ${pomVsSettings} + + + + + pom + + true + + + applied + pom + + + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/pom.properties + + project/properties + + + + + + + + diff --git a/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml b/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml new file mode 100644 index 0000000000..2d42d495c5 --- /dev/null +++ b/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml @@ -0,0 +1,35 @@ + + + + + + + + settings + + true + + + applied + settings + + + + diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml index 5cb452aed2..0c3078db7a 100644 --- a/maven-embedder/pom.xml +++ b/maven-embedder/pom.xml @@ -1,4 +1,5 @@ + + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT + maven-embedder + Maven Embedder + org.apache.maven @@ -64,10 +70,11 @@ easymock - commons-jxpath - commons-jxpath + commons-jxpath + commons-jxpath + diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java index ff987622a4..8045cd9f69 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java @@ -76,6 +76,8 @@ public class CLIManager public static final String ALTERNATE_GLOBAL_SETTINGS = "gs"; + public static final char ALTERNATE_USER_TOOLCHAINS = 't'; + public static final String FAIL_FAST = "ff"; public static final String FAIL_AT_END = "fae"; @@ -111,6 +113,7 @@ public class CLIManager options.addOption( OptionBuilder.withLongOpt( "lax-checksums" ).withDescription( "Warn if checksums don't match" ).create( CHECKSUM_WARNING_POLICY ) ); options.addOption( OptionBuilder.withLongOpt( "settings" ).withDescription( "Alternate path for the user settings file" ).hasArg().create( ALTERNATE_USER_SETTINGS ) ); options.addOption( OptionBuilder.withLongOpt( "global-settings" ).withDescription( "Alternate path for the global settings file" ).hasArg().create( ALTERNATE_GLOBAL_SETTINGS ) ); + options.addOption( OptionBuilder.withLongOpt( "toolchains" ).withDescription( "Alternate path for the user toolchains file" ).hasArg().create( ALTERNATE_USER_TOOLCHAINS ) ); options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription( "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) ); options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription( "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) ); options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription( "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) ); diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIRequestUtils.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIRequestUtils.java index a3fc6228fd..eefd43561d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIRequestUtils.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIRequestUtils.java @@ -22,7 +22,6 @@ package org.apache.maven.cli; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.StringTokenizer; @@ -30,6 +29,7 @@ import java.util.Map.Entry; import org.apache.commons.cli.CommandLine; import org.apache.maven.MavenTransferListener; +import org.apache.maven.embedder.MavenEmbedder; import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequest; import org.codehaus.plexus.util.cli.CommandLineUtils; @@ -77,7 +77,7 @@ public final class CLIRequestUtils // // ---------------------------------------------------------------------- - List goals = commandLine.getArgList(); + List goals = commandLine.getArgList(); boolean recursive = true; @@ -139,9 +139,9 @@ public final class CLIRequestUtils // Profile Activation // ---------------------------------------------------------------------- - List activeProfiles = new ArrayList(); + List activeProfiles = new ArrayList(); - List inactiveProfiles = new ArrayList(); + List inactiveProfiles = new ArrayList(); if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) ) { @@ -222,6 +222,16 @@ public final class CLIRequestUtils Properties userProperties = new Properties(); populateProperties( commandLine, executionProperties, userProperties ); + File userToolchainsFile; + if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) ) + { + userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) ); + } + else + { + userToolchainsFile = MavenEmbedder.DEFAULT_USER_TOOLCHAINS_FILE; + } + MavenExecutionRequest request = new DefaultMavenExecutionRequest() .setBaseDirectory( baseDirectory ) .setGoals( goals ) @@ -239,7 +249,9 @@ public final class CLIRequestUtils .setTransferListener( transferListener ) // default: batch mode which goes along with interactive .setUpdateSnapshots( updateSnapshots ) // default: false .setNoSnapshotUpdates( noSnapshotUpdates ) // default: false - .setGlobalChecksumPolicy( globalChecksumPolicy ); // default: warn + .setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn + .setUserToolchainsFile( userToolchainsFile ); + if ( alternatePomFile != null ) { @@ -261,10 +273,8 @@ public final class CLIRequestUtils try { Properties envVars = CommandLineUtils.getSystemEnvVars(); - Iterator i = envVars.entrySet().iterator(); - while ( i.hasNext() ) + for ( Entry e : envVars.entrySet() ) { - Entry e = (Entry) i.next(); executionProperties.setProperty( "env." + e.getKey().toString(), e.getValue().toString() ); } } diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java index 9e4ee0b253..d9fb599f58 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java @@ -83,6 +83,8 @@ public class MavenEmbedder public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/settings.xml" ); + public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" ); + // ---------------------------------------------------------------------------- // // ---------------------------------------------------------------------------- diff --git a/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java b/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java index 21e2bc13cd..1680ccf5fe 100644 --- a/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java +++ b/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java @@ -29,10 +29,12 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.embedder.Configuration; import org.apache.maven.embedder.MavenEmbedderException; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.model.Model; import org.apache.maven.model.Profile; import org.apache.maven.model.Repository; import org.apache.maven.profiles.DefaultProfileManager; import org.apache.maven.profiles.ProfileActivationContext; +import org.apache.maven.profiles.ProfileActivationException; import org.apache.maven.profiles.ProfileManager; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.settings.MavenSettingsBuilder; @@ -41,6 +43,7 @@ import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.settings.SettingsUtils; +import org.apache.maven.toolchain.ToolchainsBuilder; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; @@ -71,6 +74,9 @@ public class DefaultMavenExecutionRequestPopulator @Requirement private RepositorySystem repositorySystem; + @Requirement + private ToolchainsBuilder toolchainsBuilder; + // 2009-03-05 Oleg: this component is defined sub-classed in this package @Requirement(hint = "maven") private SecDispatcher securityDispatcher; @@ -84,6 +90,8 @@ public class DefaultMavenExecutionRequestPopulator localRepository( request, configuration ); + toolchains( request, configuration ); + artifactTransferMechanism( request, configuration ); profileManager( request, configuration ); @@ -150,21 +158,41 @@ public class DefaultMavenExecutionRequestPopulator Profile profile = SettingsUtils.convertFromSettingsProfile( rawProfile ); profileManager.addProfile( profile ); + } - // We need to convert profile repositories to artifact repositories - - for ( Repository r : profile.getRepositories() ) + // We need to convert profile repositories to artifact repositories + try + { + for ( Profile profile : profileManager.getActiveProfiles() ) { - try + for ( Repository r : profile.getRepositories() ) { - request.addRemoteRepository( repositorySystem.buildArtifactRepository( r ) ); + try + { + request.addRemoteRepository( repositorySystem.buildArtifactRepository( r ) ); + } + catch ( InvalidRepositoryException e ) + { + throw new MavenEmbedderException( "Cannot create remote repository " + r.getId(), e ); + } } - catch ( InvalidRepositoryException e ) + for ( Repository r : profile.getPluginRepositories() ) { - throw new MavenEmbedderException( "Cannot create remote repository " + r.getId(), e ); - } + try + { + request.addRemoteRepository( repositorySystem.buildArtifactRepository( r ) ); + } + catch ( InvalidRepositoryException e ) + { + throw new MavenEmbedderException( "Cannot create remote repository " + r.getId(), e ); + } + } } } + catch ( ProfileActivationException e ) + { + throw new MavenEmbedderException( "Cannot determine active profiles", e ); + } } injectDefaultRepositories( request ); @@ -391,9 +419,15 @@ public class DefaultMavenExecutionRequestPopulator activationContext.setExplicitlyActiveProfileIds( request.getActiveProfiles() ); activationContext.setExplicitlyInactiveProfileIds( request.getInactiveProfiles() ); - ProfileManager globalProfileManager = new DefaultProfileManager( container, activationContext ); + ProfileManager globalProfileManager = new DefaultProfileManager( activationContext ); request.setProfileManager( globalProfileManager ); request.setProfileActivationContext( activationContext ); } + + private void toolchains( MavenExecutionRequest request, Configuration configuration ) + { + toolchainsBuilder.setUserToolchainsFile( request.getUserToolchainsFile() ); + } + } diff --git a/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderTest.java b/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderTest.java index 131018c2b6..cff492bfc8 100644 --- a/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderTest.java +++ b/maven-embedder/src/test/java/org/apache/maven/embedder/MavenEmbedderTest.java @@ -354,18 +354,19 @@ public class MavenEmbedderTest artifacts.iterator().next(); } + /**TODO - FIX public void testProjectReading_FromChildLevel_ScmInheritanceCalculations() throws Exception { File pomFile = new File( basedir, "src/test/projects/readProject-withScmInheritance/modules/child1/pom.xml" ); MavenProject project = mavenEmbedder.readProject( pomFile ); - + assertNotNull(project.getScm()); assertEquals( "http://host/viewer?path=/trunk/parent/child1", project.getScm().getUrl() ); assertEquals( "scm:svn:http://host/trunk/parent/child1", project.getScm().getConnection() ); assertEquals( "scm:svn:https://host/trunk/parent/child1", project.getScm().getDeveloperConnection() ); } - +*/ public void testProjectReading_SkipMissingModuleSilently() throws Exception { diff --git a/maven-mercury/pom.xml b/maven-mercury/pom.xml index a4c9ce31cb..8808597ffd 100644 --- a/maven-mercury/pom.xml +++ b/maven-mercury/pom.xml @@ -11,13 +11,16 @@ --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-mercury + Maven Mercury @@ -34,7 +37,7 @@ org.apache.maven - maven-project-builder + maven-model-builder @@ -42,11 +45,6 @@ plexus-component-annotations - - org.sonatype.spice - model-builder - - org.apache.maven.mercury @@ -85,6 +83,12 @@ test + + commons-cli + commons-cli + test + + junit junit @@ -99,14 +103,14 @@ org.codehaus.plexus plexus-component-metadata - - - - generate-metadata - generate-test-metadata - - - + + + + generate-metadata + generate-test-metadata + + + diff --git a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDependencyProcessor.java b/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDependencyProcessor.java index eb6e80a6ae..6708ce2e6f 100644 --- a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDependencyProcessor.java +++ b/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDependencyProcessor.java @@ -21,7 +21,6 @@ package org.apache.maven.mercury; import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -30,14 +29,11 @@ import org.apache.maven.mercury.builder.api.DependencyProcessor; import org.apache.maven.mercury.builder.api.DependencyProcessorException; import org.apache.maven.mercury.builder.api.MetadataReader; import org.apache.maven.mercury.builder.api.MetadataReaderException; -import org.apache.maven.project.builder.PomInterpolatorTag; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelTransformerContext; +import org.apache.maven.model.DomainModel; +import org.apache.maven.model.ProcessorContext; +import org.apache.maven.model.interpolator.DefaultInterpolator; +import org.apache.maven.model.interpolator.InterpolatorProperty; +import org.apache.maven.model.interpolator.PomInterpolatorTag; import org.codehaus.plexus.component.annotations.Component; /** @@ -49,9 +45,13 @@ import org.codehaus.plexus.component.annotations.Component; * */ @Component( role=DependencyProcessor.class, hint="maven" ) -public final class MavenDependencyProcessor +public class MavenDependencyProcessor implements DependencyProcessor { + + /** + * Over-ride this method to change how dependencies are obtained + */ public List getDependencies( ArtifactMetadata bmd, MetadataReader mdReader, Map system, Map user ) throws MetadataReaderException, DependencyProcessorException @@ -66,20 +66,7 @@ public final class MavenDependencyProcessor throw new IllegalArgumentException( "mdReader: null" ); } - List interpolatorProperties = new ArrayList(); - interpolatorProperties.add( new InterpolatorProperty( "${mavenVersion}", "3.0-SNAPSHOT", - PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); - - if ( system != null ) - { - interpolatorProperties.addAll( - InterpolatorProperty.toInterpolatorProperties( system, PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); - } - if ( user != null ) - { - interpolatorProperties.addAll( - InterpolatorProperty.toInterpolatorProperties( user, PomInterpolatorTag.USER_PROPERTIES.name() ) ); - } + List interpolatorProperties = createInterpolatorProperties(system, user); List domainModels = new ArrayList(); try @@ -98,14 +85,14 @@ public final class MavenDependencyProcessor MavenDomainModel domainModel = new MavenDomainModel( superBytes ); domainModel.setMostSpecialized(true); domainModels.add( domainModel ); - +/*TODO: Profiles Collection activeProfiles = domainModel.getActiveProfileContainers( interpolatorProperties ); for ( ModelContainer mc : activeProfiles ) { domainModels.add( new MavenDomainModel( transformProfiles( mc.getProperties() ) ) ); } - +*/ List parentModels = getParentsOfDomainModel( domainModel, mdReader ); if ( parentModels == null ) @@ -120,24 +107,35 @@ public final class MavenDependencyProcessor throw new MetadataReaderException( "Failed to create domain model. Message = " + e.getMessage(), e ); } - PomTransformer transformer = new PomTransformer( new MavenDomainModelFactory() ); - ModelTransformerContext ctx = - new ModelTransformerContext( PomTransformer.MODEL_CONTAINER_INFOS ); + try { + return new MavenDomainModel(new DefaultInterpolator().interpolateDomainModel(ProcessorContext.build(domainModels, null), + interpolatorProperties)).getDependencyMetadata(); + } catch (IOException e) { + throw new DependencyProcessorException(); + } - try + } + + protected final List createInterpolatorProperties(Map system, Map user) + { + List interpolatorProperties = new ArrayList(); + interpolatorProperties.add( new InterpolatorProperty( "${mavenVersion}", "3.0-SNAPSHOT", + PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); + + if ( system != null ) { - MavenDomainModel model = - ( (MavenDomainModel) ctx.transform( domainModels, transformer, transformer, null, - interpolatorProperties, null ) ); - return model.getDependencyMetadata(); + interpolatorProperties.addAll( + InterpolatorProperty.toInterpolatorProperties( system, PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); } - catch ( IOException e ) + if ( user != null ) { - throw new MetadataReaderException( "Unable to transform model", e ); + interpolatorProperties.addAll( + InterpolatorProperty.toInterpolatorProperties( user, PomInterpolatorTag.USER_PROPERTIES.name() ) ); } + return interpolatorProperties; } - private static List getParentsOfDomainModel( MavenDomainModel domainModel, MetadataReader mdReader ) + protected final List getParentsOfDomainModel( MavenDomainModel domainModel, MetadataReader mdReader ) throws IOException, MetadataReaderException, DependencyProcessorException { List domainModels = new ArrayList(); @@ -156,20 +154,4 @@ public final class MavenDependencyProcessor } return domainModels; } - - private static List transformProfiles( List modelProperties ) - { - List properties = new ArrayList(); - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.Profiles.Profile.xUri ) - && !mp.getUri().equals( ProjectUri.Profiles.Profile.id ) - && !mp.getUri().startsWith( ProjectUri.Profiles.Profile.Activation.xUri ) ) - { - properties.add( new ModelProperty( mp.getUri().replace( ProjectUri.Profiles.Profile.xUri, - ProjectUri.xUri ), mp.getResolvedValue() ) ); - } - } - return properties; - } } diff --git a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModel.java b/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModel.java index 131fda11bf..98f268cbf6 100644 --- a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModel.java +++ b/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModel.java @@ -21,44 +21,19 @@ package org.apache.maven.mercury; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.List; import org.apache.maven.mercury.artifact.ArtifactMetadata; -import org.apache.maven.project.builder.PomClassicDomainModel; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.project.builder.factories.ExclusionModelContainerFactory; -import org.apache.maven.project.builder.profile.ProfileContext; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelDataSource; -import org.apache.maven.shared.model.ModelMarshaller; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Parent; +import org.apache.maven.model.PomClassicDomainModel; -/** - * Provides a wrapper for the maven model. - */ public final class MavenDomainModel extends PomClassicDomainModel { - /** - * Bytes containing the underlying model - */ - private final List modelProperties; - - /** - * History of joins and deletes of model properties - */ - private String eventHistory; - private ArtifactMetadata parentMetadata; /** @@ -69,99 +44,74 @@ public final class MavenDomainModel public MavenDomainModel( byte[] bytes ) throws IOException { - this( new ByteArrayInputStream( bytes ) ); + super( new ByteArrayInputStream( bytes ) ); } - /** - * Constructor - * - * @throws IOException if there is a problem constructing the model - */ - public MavenDomainModel( InputStream inputStream ) - throws IOException + + public MavenDomainModel(PomClassicDomainModel model) + throws IOException { - this( ModelMarshaller.marshallXmlToModelProperties( inputStream, ProjectUri.baseUri, PomTransformer.URIS ) ); - } - - /** - * Constructor - * - * @throws IOException if there is a problem constructing the model - */ - public MavenDomainModel( List modelProperties ) - throws IOException - { - super(modelProperties); - this.modelProperties = new ArrayList( modelProperties ); - } - + super(model.getModel()); + } + public boolean hasParent() { - // TODO: Expensive call if no parent return getParentMetadata() != null; } public List getDependencyMetadata() - throws DataSourceException { List metadatas = new ArrayList(); - ModelDataSource source = new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - for ( ModelContainer modelContainer : source.queryFor( ProjectUri.Dependencies.Dependency.xUri ) ) + for(Dependency d: model.getDependencies()) { - metadatas.add( transformContainerToMetadata( modelContainer ) ); + ArtifactMetadata metadata = new ArtifactMetadata(); + metadata.setArtifactId(d.getArtifactId()); + metadata.setClassifier(d.getClassifier()); + metadata.setGroupId(d.getGroupId()); + metadata.setScope( (d.getScope() == null) ? "runtime" : d.getScope()); + metadata.setVersion(d.getVersion()); + metadata.setOptional(d.isOptional()); + + if( "test-jar".equals( d.getType() ) ) + { + metadata.setType( "jar" ); + metadata.setClassifier( "tests" ); + } + else + { + metadata.setType( d.getType() ); + } + + List exclusions = new ArrayList(); + for( Exclusion e : d.getExclusions() ) + { + ArtifactMetadata md = new ArtifactMetadata(); + md.setArtifactId(e.getArtifactId()); + md.setGroupId(e.getGroupId()); + exclusions.add(md); + } + metadata.setExclusions(exclusions); + metadatas.add(metadata); } - + return metadatas; } - public Collection getActiveProfileContainers( List properties ) - throws DataSourceException - { - ModelDataSource dataSource = new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - return new ProfileContext( dataSource, null, null, properties ).getActiveProfiles(); - } - public ArtifactMetadata getParentMetadata() { - if ( parentMetadata != null ) + if(parentMetadata == null) { - return copyArtifactBasicMetadata( parentMetadata ); + Parent parent = model.getParent(); + if(parent != null) + { + parentMetadata = new ArtifactMetadata(); + parentMetadata.setArtifactId( parent.getArtifactId() ); + parentMetadata.setVersion( parent.getVersion() ); + parentMetadata.setGroupId( parent.getGroupId() ); + } } - - String groupId = null, artifactId = null, version = null; - - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().equals( ProjectUri.Parent.version ) ) - { - version = mp.getResolvedValue(); - } - else if ( mp.getUri().equals( ProjectUri.Parent.artifactId ) ) - { - artifactId = mp.getResolvedValue(); - } - else if ( mp.getUri().equals( ProjectUri.Parent.groupId ) ) - { - groupId = mp.getResolvedValue(); - } - if ( groupId != null && artifactId != null && version != null ) - { - break; - } - } - - if ( groupId == null || artifactId == null || version == null ) - { - return null; - } - parentMetadata = new ArtifactMetadata(); - parentMetadata.setArtifactId( artifactId ); - parentMetadata.setVersion( version ); - parentMetadata.setGroupId( groupId ); - - return copyArtifactBasicMetadata( parentMetadata ); + return (parentMetadata != null) ? copyArtifactBasicMetadata( parentMetadata ) : null; } private ArtifactMetadata copyArtifactBasicMetadata( ArtifactMetadata metadata ) @@ -172,100 +122,4 @@ public final class MavenDomainModel amd.setVersion( metadata.getVersion() ); return amd; } - - /** - * @see org.apache.maven.shared.model.DomainModel#getEventHistory() - */ - public String getEventHistory() - { - return eventHistory; - } - - /** - * @see org.apache.maven.shared.model.DomainModel#setEventHistory(String) - */ - public void setEventHistory( String eventHistory ) - { - if ( eventHistory == null ) - { - throw new IllegalArgumentException( "eventHistory: null" ); - } - this.eventHistory = eventHistory; - } - - public List getModelProperties() - throws IOException - { - return new ArrayList( modelProperties ); - } - - private ArtifactMetadata transformContainerToMetadata( ModelContainer container ) - throws DataSourceException - { - List modelProperties = container.getProperties(); - - ArtifactMetadata metadata = new ArtifactMetadata(); - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.groupId ) ) - { - metadata.setGroupId( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.artifactId ) ) - { - metadata.setArtifactId( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.version ) ) - { - metadata.setVersion( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.classifier ) ) - { - metadata.setClassifier( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.scope ) ) - { - metadata.setScope( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.type ) ) - { - metadata.setType( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.optional ) ) - { - metadata.setOptional( mp.getResolvedValue() ); - } - } - - if ( metadata.getScope() == null ) - { - metadata.setScope( "runtime" ); - } - - ModelDataSource dataSource = new DefaultModelDataSource( container.getProperties(), Arrays.asList( new ArtifactModelContainerFactory(), - new ExclusionModelContainerFactory() ) ); - List exclusions = new ArrayList(); - - for ( ModelContainer exclusion : dataSource.queryFor( ProjectUri.Dependencies.Dependency.Exclusions.Exclusion.xUri ) ) - { - ArtifactMetadata meta = new ArtifactMetadata(); - exclusions.add( meta ); - - for ( ModelProperty mp : exclusion.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.Exclusions.Exclusion.artifactId ) ) - { - meta.setArtifactId( mp.getResolvedValue() ); - } - else if ( mp.getUri().equals( ProjectUri.Dependencies.Dependency.Exclusions.Exclusion.groupId ) ) - { - meta.setGroupId( mp.getResolvedValue() ); - } - } - - } - metadata.setExclusions( exclusions ); - - return metadata; - } } diff --git a/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessor.java b/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessor.java deleted file mode 100644 index d419059a03..0000000000 --- a/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.apache.maven.mercury; - -import java.util.List; -import java.util.Map; - -import org.apache.maven.mercury.artifact.ArtifactMetadata; -import org.apache.maven.mercury.builder.api.MetadataReader; -import org.apache.maven.mercury.builder.api.MetadataReaderException; -import org.apache.maven.shared.model.ModelProperty; - -public interface PomProcessor -{ - List getRawPom(ArtifactMetadata bmd, MetadataReader mdReader, Map env, - Map sysProps) - throws MetadataReaderException, PomProcessorException; -} diff --git a/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessorException.java b/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessorException.java deleted file mode 100644 index ad523233c7..0000000000 --- a/maven-mercury/src/main/java/org/apache/maven/mercury/PomProcessorException.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.apache.maven.mercury; - -public class PomProcessorException - extends Exception -{ - static final long serialVersionUID = 980457843528974352L; - - /** - * Default constructor - */ - public PomProcessorException() - { - super(); - } - - /** - * Constructor - * - * @param message exception message - */ - public PomProcessorException( String message ) - { - super( message ); - } - - /** - * Constructor - * - * @param message exception message - */ - public PomProcessorException( String message, Exception e ) - { - super( message, e ); - } - -} diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml new file mode 100644 index 0000000000..019a1718bc --- /dev/null +++ b/maven-model-builder/pom.xml @@ -0,0 +1,65 @@ + + + + + + 4.0.0 + + + org.apache.maven + maven + 3.0-SNAPSHOT + + + maven-model-builder + 3.0-SNAPSHOT + + Maven Model Builder + + + + org.codehaus.plexus + plexus-utils + + + org.codehaus.plexus + plexus-component-annotations + + + org.apache.maven + maven-model + + + org.codehaus.woodstox + wstx-asl + + + stax + stax-api + + + junit + junit + 4.4 + test + + + + + + + org.codehaus.plexus + plexus-component-metadata + + + + + diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/DomainModel.java b/maven-model-builder/src/main/java/org/apache/maven/model/DomainModel.java new file mode 100644 index 0000000000..6ee7cadd44 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/DomainModel.java @@ -0,0 +1,8 @@ +package org.apache.maven.model; + +public interface DomainModel { + + boolean isMostSpecialized(); + + void setMostSpecialized(boolean isMostSpecialized); +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/ModelEventListener.java b/maven-model-builder/src/main/java/org/apache/maven/model/ModelEventListener.java new file mode 100644 index 0000000000..b8de7d8cbe --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/ModelEventListener.java @@ -0,0 +1,14 @@ +package org.apache.maven.model; + +import java.util.List; + +import org.apache.maven.model.Model; + +public interface ModelEventListener { + + void fire(Model model); + + List getUris(); + +} + diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/ModelListener.java b/maven-model-builder/src/main/java/org/apache/maven/model/ModelListener.java new file mode 100644 index 0000000000..49cc5ef78d --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/ModelListener.java @@ -0,0 +1,29 @@ +package org.apache.maven.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +public interface ModelListener +{ + void register( Object xmlNode ); + + void fire( Object object ); + + boolean isRegistered( Object object ); +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/PomClassicDomainModel.java b/maven-model-builder/src/main/java/org/apache/maven/model/PomClassicDomainModel.java new file mode 100644 index 0000000000..d11278919b --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/PomClassicDomainModel.java @@ -0,0 +1,288 @@ +package org.apache.maven.model; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; + +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.WriterFactory; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +public class PomClassicDomainModel implements DomainModel +{ + + /** + * Bytes containing the underlying model + */ + private byte[] inputBytes; + + private String id; + + private File file; + + private File parentFile; + + private File projectDirectory; + + private int lineageCount; + + private boolean isMostSpecialized = false; + + private String parentGroupId = null, parentArtifactId = null, parentVersion = null, parentId = null, parentRelativePath; + + protected Model model; + + public Model getModel() throws IOException + { + return model; + } + + private void initializeProperties(Model model) + { + String groupId = null, artifactId = null, version = null; + + groupId = model.getGroupId(); + artifactId = model.getArtifactId(); + version = model.getVersion(); + + if( model.getParent() != null) + { + parentArtifactId =model.getParent().getArtifactId(); + parentGroupId = model.getParent().getGroupId(); + parentVersion = model.getParent().getVersion(); + parentRelativePath = model.getParent().getRelativePath(); + + if( groupId == null && parentGroupId != null) + { + groupId = parentGroupId; + } + if( artifactId == null && parentArtifactId != null) + { + artifactId = parentArtifactId; + } + if( version == null && parentVersion != null ) + { + version = parentVersion; + } + + if(parentGroupId != null && parentArtifactId != null && parentVersion != null) + { + parentId = parentGroupId + ":" + parentArtifactId + ":" + parentVersion; + } + } + + if(parentRelativePath == null) + { + parentRelativePath = ".." + File.separator + "pom.xml"; + } + + id = groupId + ":" + artifactId + ":" + version; + } + + public PomClassicDomainModel( File file ) + throws IOException + { + this( new FileInputStream( file ) ); + this.file = file; + } + + public PomClassicDomainModel( InputStream is ) + throws IOException + { + this.inputBytes = IOUtil.toByteArray( is); + + MavenXpp3Reader reader = new MavenXpp3Reader(); + try + { + model = reader.read( new ByteArrayInputStream( inputBytes ), false ) ; + } + catch ( XmlPullParserException e ) + { + throw new IOException( e.getMessage() ); + } + + initializeProperties( model ); + } + + public PomClassicDomainModel(Model model) throws IOException { + this (model, false); + } + + public PomClassicDomainModel(Model model, boolean b) throws IOException { + this.model = model; + this.isMostSpecialized = b; + + + initializeProperties( model ); + + } + + public File getParentFile() + { + return parentFile; + } + + public void setParentFile( File parentFile ) + { + this.parentFile = parentFile; + } + + public String getParentGroupId() { + return parentGroupId; + } + + public String getParentArtifactId() { + return parentArtifactId; + } + + public String getParentVersion() { + return parentVersion; + } + + /** + * This should only be set for projects that are in the build. Setting for poms in the repo may cause unstable behavior. + * + * @param projectDirectory + */ + public void setProjectDirectory(File projectDirectory) + { + this.projectDirectory = projectDirectory; + } + + public File getProjectDirectory() + { + return projectDirectory; + } + + public boolean isPomInBuild() + { + return projectDirectory != null; + } + + public String getParentId() throws IOException + { + return parentId; + } + + public String getRelativePathOfParent() + { + return parentRelativePath; + } + + public String getId() throws IOException + { + return id; + } + + public boolean matchesParentOf( PomClassicDomainModel domainModel ) throws IOException + { + if ( domainModel == null ) + { + throw new IllegalArgumentException( "domainModel: null" ); + } + + return getId().equals(domainModel.getParentId()); + } + + /** + * Returns XML model as string + * + * @return XML model as string + */ + public String asString() throws IOException + { + return IOUtil.toString( ReaderFactory.newXmlReader( getInputStream() ) ); + } + + /** + * @see org.apache.maven.shared.model.InputStreamDomainModel#getInputStream() + */ + public InputStream getInputStream() throws IOException + { + if(inputBytes != null) + { + byte[] copy = new byte[inputBytes.length]; + System.arraycopy( inputBytes, 0, copy, 0, inputBytes.length ); + return new ByteArrayInputStream( copy ); + } + else + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Writer out = null; + MavenXpp3Writer writer = new MavenXpp3Writer(); + try + { + out = WriterFactory.newXmlWriter( baos ); + writer.write( out, model ); + } + finally + { + if ( out != null ) + { + out.close(); + } + } + inputBytes = baos.toByteArray(); + return new ByteArrayInputStream(inputBytes); + } + } + + /** + * @return file of pom. May be null. + */ + public File getFile() + { + return file; + } + + public int getLineageCount() + { + return lineageCount; + } + + public void setLineageCount( int lineageCount ) + { + this.lineageCount = lineageCount; + } + + /** + * Returns true if this.asString.equals(o.asString()), otherwise false. + * + * @param o domain model + * @return true if this.asString.equals(o.asString()), otherwise false. + */ + public boolean equals( Object o ) + { + try { + return o instanceof PomClassicDomainModel && getId().equals( ( (PomClassicDomainModel) o ).getId() ); + } catch (IOException e) { + return false; + } + } + + public boolean isMostSpecialized() + { + return isMostSpecialized; + } + + public void setMostSpecialized( boolean isMostSpecialized ) + { + this.isMostSpecialized = isMostSpecialized; + } + + @Override + public String toString() + { + return String.valueOf( id ); + } + + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/Processor.java b/maven-model-builder/src/main/java/org/apache/maven/model/Processor.java new file mode 100644 index 0000000000..c75f669538 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/Processor.java @@ -0,0 +1,36 @@ +package org.apache.maven.model; + +import java.util.List; + +import org.apache.maven.model.Model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +public interface Processor +{ + void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ); + + Object getParent(); + + Object getChild(); + + List getParentModels(); + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/ProcessorContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/ProcessorContext.java new file mode 100644 index 0000000000..cf7d786d3a --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/ProcessorContext.java @@ -0,0 +1,352 @@ +package org.apache.maven.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Profile; +import org.apache.maven.model.Resource; +import org.apache.maven.model.processors.BuildProcessor; +import org.apache.maven.model.processors.CiManagementProcessor; +import org.apache.maven.model.processors.ContributorsProcessor; +import org.apache.maven.model.processors.DependencyManagementProcessor; +import org.apache.maven.model.processors.DevelopersProcessor; +import org.apache.maven.model.processors.DistributionManagementProcessor; +import org.apache.maven.model.processors.IssueManagementProcessor; +import org.apache.maven.model.processors.LicensesProcessor; +import org.apache.maven.model.processors.MailingListProcessor; +import org.apache.maven.model.processors.ModelProcessor; +import org.apache.maven.model.processors.ModuleProcessor; +import org.apache.maven.model.processors.OrganizationProcessor; +import org.apache.maven.model.processors.ParentProcessor; +import org.apache.maven.model.processors.PluginsManagementProcessor; +import org.apache.maven.model.processors.PrerequisitesProcessor; +import org.apache.maven.model.processors.ProfilePropertiesProcessor; +import org.apache.maven.model.processors.ProfilesModuleProcessor; +import org.apache.maven.model.processors.ProfilesProcessor; +import org.apache.maven.model.processors.PropertiesProcessor; +import org.apache.maven.model.processors.ReportingProcessor; +import org.apache.maven.model.processors.RepositoriesProcessor; +import org.apache.maven.model.processors.ScmProcessor; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +public class ProcessorContext +{ + + /** + * Parent domain models on bottom. + * + * @param domainModels + * @param listeners + * @return + * @throws IOException + */ + public static PomClassicDomainModel build( List domainModels, List listeners ) + throws IOException + { + PomClassicDomainModel child = null; + for ( DomainModel domainModel : domainModels ) + { + if(domainModel.isMostSpecialized()) + { + child = (PomClassicDomainModel) domainModel; + } + } + if(child == null) + { + throw new IOException("Could not find child model"); + } + + List processors = + Arrays. asList( new BuildProcessor( new ArrayList() ), new ModuleProcessor(), + new PropertiesProcessor(), new ParentProcessor(), new OrganizationProcessor(), + new MailingListProcessor(), new IssueManagementProcessor(), + new CiManagementProcessor(), new ReportingProcessor(), + new RepositoriesProcessor(), new DistributionManagementProcessor(), + new LicensesProcessor(), new ScmProcessor(), new PrerequisitesProcessor(), + new ContributorsProcessor(), new DevelopersProcessor(), new ProfilesProcessor() ); + Model target = processModelsForInheritance( convertDomainModelsToMavenModels( domainModels ), processors ); + if(listeners != null) + { + for(ModelEventListener listener : listeners) + { + listener.fire(target); + } + } + PomClassicDomainModel domainModel = new PomClassicDomainModel( target, child.isMostSpecialized() ); + domainModel.setProjectDirectory(child.getProjectDirectory()); + domainModel.setParentFile(child.getParentFile()); + + return domainModel; + } + + public static PomClassicDomainModel mergeProfilesIntoModel(Collection profiles, PomClassicDomainModel domainModel) throws IOException + { + List profileModels = new ArrayList(); + List externalProfileModels = new ArrayList(); + + for(Profile profile : profiles) + { + if("pom".equals(profile.getSource())) + { + profileModels.add( attachProfileNodesToModel(profile) ); + } + else + { + externalProfileModels.add(attachProfileNodesToModel(profile)); + } + } + profileModels.addAll(externalProfileModels);//external takes precedence + + Model model = domainModel.getModel(); + profileModels.add( 0, model ); + List processors = + Arrays. asList( new BuildProcessor( new ArrayList() ), new ProfilesModuleProcessor(), + new ProfilePropertiesProcessor(), new ParentProcessor(), + new OrganizationProcessor(), new MailingListProcessor(), + new IssueManagementProcessor(), new CiManagementProcessor(), + new ReportingProcessor(), new RepositoriesProcessor(), + new DistributionManagementProcessor(), new LicensesProcessor(), + new ScmProcessor(), new PrerequisitesProcessor(), new ContributorsProcessor(), + new DevelopersProcessor(), new ProfilesProcessor() ); + + //Remove the plugin management and dependency management so they aren't applied again with the profile processing + PluginManagement mng = null; + if( model.getBuild() != null) + { + mng = model.getBuild().getPluginManagement(); + model.getBuild().setPluginManagement( null ); + } + + DependencyManagement depMng = model.getDependencyManagement(); + + Model target = processModelsForInheritance(profileModels, processors); + + PluginsManagementProcessor pmp = new PluginsManagementProcessor(); + if( mng != null ) + { + if(target.getBuild().getPluginManagement() != null) + { + pmp.process(null, mng.getPlugins(), target.getBuild().getPluginManagement().getPlugins(), false); + } + else + { + target.getBuild().setPluginManagement( mng ); + } + } + + //TODO: Merge Dependency Management + target.setDependencyManagement( depMng ); + + PomClassicDomainModel targetModel = new PomClassicDomainModel( target, domainModel.isMostSpecialized()); + targetModel.setParentFile(domainModel.getParentFile()); + targetModel.setProjectDirectory(domainModel.getProjectDirectory()); + return targetModel; + } + + private static Model attachProfileNodesToModel(Profile profile) + { + Profile p = copyOfProfile(profile); + + Model model = new Model(); + model.setModules( p.getModules() ); + model.setDependencies(p.getDependencies()); + model.setDependencyManagement( p.getDependencyManagement()); + model.setDistributionManagement( p.getDistributionManagement() ); + model.setProperties( p.getProperties() ); + model.setModules( new ArrayList(p.getModules() ) ); + model.setRepositories(p.getRepositories()); + model.setPluginRepositories(p.getPluginRepositories()); + model.setReporting(p.getReporting()); + BuildProcessor proc = new BuildProcessor( new ArrayList()); + proc.processWithProfile( p.getBuild(), model); + return model; + } + + private static List convertDomainModelsToMavenModels(List domainModels) throws IOException + { + List models = new ArrayList(); + for(DomainModel domainModel : domainModels) + { + PomClassicDomainModel dm = (PomClassicDomainModel) domainModel; + if(dm.getModel() != null) + { + if(dm.isMostSpecialized()) + { + models.add(0, dm.getModel() ); + } + else + { + models.add( dm.getModel() ); + } + + } + else + { + throw new IOException( "model: null" ); + } + + } + + return models; + } + + private static Model processModelsForInheritance(List models, List processors) + { + ModelProcessor modelProcessor = new ModelProcessor( processors ); + Collections.reverse( models ); + + int length = models.size(); + Model target = new Model(); + if(length == 1) + { + modelProcessor.process( null, models.get( 0 ), target, true ); + + } else if( length == 2) + { + modelProcessor.process( models.get( 0 ), models.get( 1 ), target, true ); + } + else { + for ( int i = 0; i < length - 1; i++ ) + { + if(i == 0) + { + modelProcessor.process( null, models.get( 0 ), target, false ); + } + else if ( i < length - 2 ) + { + modelProcessor.process( models.get( i ), models.get( i + 1 ), target, false ); + } + else + { + modelProcessor.process( models.get( i ), models.get( i + 1 ), target, true ); + } + } + } + + // Dependency Management + DependencyManagementProcessor depProc = new DependencyManagementProcessor(); + if ( target.getDependencyManagement() != null ) + { + depProc.process( null, new ArrayList( target.getDependencyManagement().getDependencies() ), + target.getDependencies(), true ); + } + + // Plugin Management + + PluginsManagementProcessor procMng = new PluginsManagementProcessor(); + if ( target.getBuild() != null && target.getBuild().getPluginManagement() != null) + { + procMng.process( null, new ArrayList( target.getBuild().getPluginManagement().getPlugins() ), + target.getBuild().getPlugins(), true ); + } + + return target; + + } + + public static Profile copyOfProfile(Profile profile) + { + Profile p = new Profile(); + p.setModules( new ArrayList(profile.getModules()) ); + p.setDependencies(new ArrayList(profile.getDependencies())); + p.setDependencyManagement( profile.getDependencyManagement()); + p.setDistributionManagement( profile.getDistributionManagement() ); + p.setProperties( profile.getProperties() ); + p.setBuild( copyBuild(profile.getBuild()) ); + p.setId( profile.getId() ); + p.setActivation( profile.getActivation() ); + p.setRepositories(profile.getRepositories()); + p.setPluginRepositories(profile.getPluginRepositories()); + p.setReporting(profile.getReporting()); + return p; + } + + private static BuildBase copyBuild(BuildBase base) + { + if(base == null) + { + return null; + } + + BuildBase b = new BuildBase(); + b.setDefaultGoal( base.getDefaultGoal() ); + b.setDirectory( base.getDirectory() ); + b.setFilters( new ArrayList(base.getFilters()) ); + b.setFinalName( base.getFinalName() ); + b.setPluginManagement( copyPluginManagement(base.getPluginManagement()) ); + b.setPlugins( copyPlugins(base.getPlugins()) ); + b.setResources( new ArrayList(base.getResources()) ); + b.setTestResources( new ArrayList(base.getTestResources()) ); + return b; + } + + private static PluginManagement copyPluginManagement(PluginManagement mng) + { + if(mng == null) + { + return null; + } + + PluginManagement pm = new PluginManagement(); + pm.setPlugins(copyPlugins(mng.getPlugins())); + return pm; + } + + private static List copyPlugins(List plugins) + { + List ps = new ArrayList(); + for(Plugin p : plugins) + { + ps.add( copyPlugin(p) ); + } + return ps; + } + + private static Plugin copyPlugin(Plugin plugin) + { + Plugin p = new Plugin(); + p.setArtifactId( plugin.getArtifactId() ); + if(plugin.getConfiguration() != null) + { + p.setConfiguration( new Xpp3Dom((Xpp3Dom) plugin.getConfiguration()) ); + } + + p.setDependencies( new ArrayList(plugin.getDependencies()) ); + p.setExecutions( new ArrayList(plugin.getExecutions()) ); + p.setGoals( plugin.getGoals() ); + p.setGroupId( plugin.getGroupId() ); + p.setInherited( plugin.getInherited() ); + p.setVersion( plugin.getVersion() ); + return p; + + } +} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/ProjectUri.java b/maven-model-builder/src/main/java/org/apache/maven/model/ProjectUri.java similarity index 99% rename from maven-project-builder/src/main/java/org/apache/maven/project/builder/ProjectUri.java rename to maven-model-builder/src/main/java/org/apache/maven/model/ProjectUri.java index a44c2da7d4..1ff548c95f 100644 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/ProjectUri.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/ProjectUri.java @@ -1,4 +1,4 @@ -package org.apache.maven.project.builder; +package org.apache.maven.model; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/DefaultInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/DefaultInterpolator.java new file mode 100644 index 0000000000..e125e4a85a --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/DefaultInterpolator.java @@ -0,0 +1,811 @@ +package org.apache.maven.model.interpolator; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; +import org.apache.maven.model.PomClassicDomainModel; +import org.apache.maven.model.ProjectUri; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Resource; +import org.codehaus.plexus.component.annotations.Component; + +@Component(role=Interpolator.class) +public class DefaultInterpolator implements Interpolator { + + public String interpolateXmlString(String xml, + List interpolatorProperties) throws IOException + { + List modelProperties = marshallXmlToModelProperties( new ByteArrayInputStream( xml.getBytes() ), ProjectUri.baseUri, URIS ); + + Map aliases = new HashMap(); + aliases.put( "project.", "pom." ); + + List ips = new ArrayList( interpolatorProperties ); + ips.addAll( createInterpolatorProperties( modelProperties, ProjectUri.baseUri, aliases, PomInterpolatorTag.PROJECT_PROPERTIES.name()) ); + + for ( ModelProperty mp : modelProperties ) + { + if ( mp.getUri().startsWith( ProjectUri.properties ) && mp.getValue() != null ) + { + String uri = mp.getUri(); + ips.add( new InterpolatorProperty( "${" + uri.substring( uri.lastIndexOf( "/" ) + 1, uri.length() ) + "}", mp.getValue() ) ); + } + } + + interpolateModelProperties( modelProperties, ips ); + return unmarshalModelPropertiesToXml( modelProperties, ProjectUri.baseUri ); + } + + public PomClassicDomainModel interpolateDomainModel( PomClassicDomainModel dm, List interpolatorProperties ) + throws IOException { + + if (dm == null) { + throw new IllegalArgumentException("dm: null"); + } + if (!containsProjectVersion(interpolatorProperties)) { + aliases.put("\\$\\{project.version\\}", "\\$\\{version\\}"); + } + //TODO: Insert customized logic for parsing + List modelProperties = getModelProperties(dm.getInputStream()); + + if ("jar".equals(dm.getModel().getPackaging())) { + modelProperties.add(new ModelProperty(ProjectUri.packaging, "jar")); + } + + List firstPassModelProperties = new ArrayList(); + List secondPassModelProperties = new ArrayList(); + + ModelProperty buildProperty = new ModelProperty(ProjectUri.Build.xUri, + null); + + for ( ModelProperty mp : modelProperties ) + { + if ( mp.getValue() != null && !mp.getUri().contains( "#property" ) && !mp.getUri().contains( "#collection" ) ) + { + if ( ( !buildProperty.isParentOf( mp ) && !mp.getUri().equals( ProjectUri.Reporting.outputDirectory ) || mp.getUri().equals( + ProjectUri.Build.finalName ) ) ) + { + firstPassModelProperties.add( mp ); + } + else + { + secondPassModelProperties.add( mp ); + } + } + } + + List standardInterpolatorProperties = new ArrayList(); + + if (dm.isPomInBuild()) { + String basedir = dm.getProjectDirectory().getAbsolutePath(); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${project.basedir}", basedir, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${basedir}", basedir, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${pom.basedir}", basedir, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + + String baseuri = dm.getProjectDirectory().toURI().toString(); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${project.baseUri}", baseuri, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${pom.baseUri}", baseuri, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + } + + for (ModelProperty mp : modelProperties) { + if (mp.getUri().startsWith(ProjectUri.properties) + && mp.getValue() != null) { + String uri = mp.getUri(); + standardInterpolatorProperties.add(new InterpolatorProperty( + "${" + + uri.substring(uri.lastIndexOf("/") + 1, uri + .length()) + "}", mp.getValue(), + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + } + } + + // FIRST PASS - Withhold using build directories as interpolator + // properties + List ips1 = new ArrayList( + interpolatorProperties); + ips1.addAll(standardInterpolatorProperties); + ips1.addAll(createInterpolatorProperties( + firstPassModelProperties, ProjectUri.baseUri, aliases, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + Collections.sort(ips1, new Comparator() { + public int compare(InterpolatorProperty o, InterpolatorProperty o1) { + if (o.getTag() == null || o1.getTag() == null) { + return 0; + } + return PomInterpolatorTag.valueOf(o.getTag()).compareTo( + PomInterpolatorTag.valueOf(o1.getTag())); + } + }); + + interpolateModelProperties(modelProperties, ips1); + + // SECOND PASS - Set absolute paths on build directories + if (dm.isPomInBuild()) { + String basedir = dm.getProjectDirectory().getAbsolutePath(); + Map buildDirectories = new HashMap(); + for (ModelProperty mp : secondPassModelProperties) { + if (mp.getUri().startsWith(ProjectUri.Build.xUri) + || mp.getUri().equals( + ProjectUri.Reporting.outputDirectory)) { + File file = new File(mp.getResolvedValue()); + if (!file.isAbsolute() + && !mp.getResolvedValue().startsWith( + "${project.build.") + && !mp.getResolvedValue().equals( + "${project.basedir}")) { + buildDirectories.put(mp, new ModelProperty(mp.getUri(), + new File(basedir, file.getPath()) + .getAbsolutePath())); + } + } + } + for (Map.Entry e : buildDirectories + .entrySet()) { + secondPassModelProperties.remove(e.getKey()); + secondPassModelProperties.add(e.getValue()); + } + } + + // THIRD PASS - Use build directories as interpolator properties + List ips2 = new ArrayList( + interpolatorProperties); + ips2.addAll(standardInterpolatorProperties); + ips2.addAll(createInterpolatorProperties( + secondPassModelProperties, ProjectUri.baseUri, aliases, + PomInterpolatorTag.PROJECT_PROPERTIES.name())); + ips2.addAll(interpolatorProperties); + Collections.sort(ips2, new Comparator() { + public int compare(InterpolatorProperty o, InterpolatorProperty o1) { + if (o.getTag() == null || o1.getTag() == null) { + return 0; + } + + return PomInterpolatorTag.valueOf(o.getTag()).compareTo( + PomInterpolatorTag.valueOf(o1.getTag())); + } + }); + + interpolateModelProperties(modelProperties, ips2); + + try + { + String xml = unmarshalModelPropertiesToXml( modelProperties, ProjectUri.baseUri ); + PomClassicDomainModel domainModel = new PomClassicDomainModel( new ByteArrayInputStream ( xml.getBytes( "UTF-8" ))); + if ( dm.getProjectDirectory() != null ) + { + alignPaths(domainModel.getModel(), dm.getProjectDirectory()); + } + return domainModel; + } + catch ( IOException e ) + { + throw new IllegalStateException( "Unmarshalling of model properties failed", e ); + } + + + + /* + for(ModelProperty mp : modelProperties) + { + if((mp.getValue() != null) && !mp.getValue().equals(mp.getResolvedValue())) + { + if(mp.getUri().equals(ProjectUri.version)) + { + + } + } + } + */ + } + /** + * Post-processes the paths of build directories by aligning relative paths to the project directory and normalizing + * file separators to the platform-specific separator. + * + * @param model The model to process, must not be {@code null}. + * @param basedir The project directory, must not be {@code null}. + */ + private static void alignPaths( Model model, File basedir ) + { + Build build = model.getBuild(); + if ( build != null ) + { + build.setDirectory( getAlignedPathFor( build.getDirectory(), basedir ) ); + build.setOutputDirectory( getAlignedPathFor( build.getOutputDirectory(), basedir ) ); + build.setTestOutputDirectory( getAlignedPathFor( build.getTestOutputDirectory(), basedir ) ); + build.setSourceDirectory( getAlignedPathFor( build.getSourceDirectory(), basedir ) ); + build.setTestSourceDirectory( getAlignedPathFor( build.getTestSourceDirectory(), basedir ) ); + build.setScriptSourceDirectory( getAlignedPathFor( build.getScriptSourceDirectory(), basedir ) ); + + for ( Resource r : build.getResources() ) + { + r.setDirectory( getAlignedPathFor( r.getDirectory(), basedir ) ); + } + + for ( Resource r : build.getTestResources() ) + { + r.setDirectory( getAlignedPathFor( r.getDirectory(), basedir ) ); + } + + List filters = new ArrayList(); + for ( String f : build.getFilters() ) + { + filters.add( getAlignedPathFor( f, basedir ) ); + } + build.setFilters( filters ); + } + + Reporting reporting = model.getReporting(); + if ( reporting != null ) + { + reporting.setOutputDirectory( getAlignedPathFor( reporting.getOutputDirectory(), basedir ) ); + } + + } + + private static String getAlignedPathFor(String path, File basedir) + { + if ( path != null ) + { + File file = new File( path ); + if ( file.isAbsolute() ) + { + // path was already absolute, just normalize file separator and we're done + path = file.getPath(); + } + else if ( file.getPath().startsWith( File.separator ) ) + { + // drive-relative Windows path, don't align with project directory but with drive root + path = file.getAbsolutePath(); + } + else + { + // an ordinary relative path, align with project directory + path = new File( new File( basedir, path ).toURI().normalize() ).getAbsolutePath(); + } + } + return path; + } + private static void interpolateModelProperties(List modelProperties, + List interpolatorProperties ) + { + if (modelProperties == null) { + throw new IllegalArgumentException("modelProperties: null"); + } + + if (interpolatorProperties == null) { + throw new IllegalArgumentException("interpolatorProperties: null"); + } + + List unresolvedProperties = new ArrayList(); + for (ModelProperty mp : modelProperties) { + if (!mp.isResolved()) { + unresolvedProperties.add(mp); + } + } + + LinkedHashSet ips = new LinkedHashSet(); + ips.addAll(interpolatorProperties); + boolean continueInterpolation = true; + while (continueInterpolation) { + continueInterpolation = false; + for (InterpolatorProperty ip : ips) { + for (ModelProperty mp : unresolvedProperties) { + if (mp.resolveWith(ip) && !continueInterpolation) { + continueInterpolation = true; + break; + } + } + } + } + } + + private static List createInterpolatorProperties(List modelProperties, + String baseUriForModel, + Map aliases, + String interpolatorTag) + { + if (modelProperties == null) { + throw new IllegalArgumentException("modelProperties: null"); + } + + if (baseUriForModel == null) { + throw new IllegalArgumentException("baseUriForModel: null"); + } + + List interpolatorProperties = new ArrayList(); + + for (ModelProperty mp : modelProperties) { + InterpolatorProperty ip = mp + .asInterpolatorProperty(baseUriForModel); + if (ip != null) { + ip.setTag(interpolatorTag); + interpolatorProperties.add(ip); + for (Map.Entry a : aliases.entrySet()) { + interpolatorProperties.add(new InterpolatorProperty(ip + .getKey().replaceAll(a.getKey(), a.getValue()), ip + .getValue().replaceAll(a.getKey(), a.getValue()), + interpolatorTag)); + } + } + } + + List ips = new ArrayList(); + for (InterpolatorProperty ip : interpolatorProperties) { + if (!ips.contains(ip)) { + ips.add(ip); + } + } + return ips; + } + + private static List getModelProperties(InputStream is) throws IOException + { + Set s = new HashSet(); + //TODO: Should add all collections from ProjectUri + s.addAll(URIS); + s.add(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri); + s.add(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.xUri); + s.add(ProjectUri.Dependencies.Dependency.Exclusions.xUri); + s.add(ProjectUri.Build.Plugins.Plugin.Executions.xUri); + s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI); + s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.xUri); + s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration); + s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.configuration); + //TODO: More profile info + s.add(ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Executions.xUri); + s.add(ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.Dependency.Exclusions.xUri); + s.add(ProjectUri.Profiles.Profile.Dependencies.Dependency.Exclusions.xUri); + s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri); + s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.Goals.xURI); + s.add(ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.xUri); + s.add(ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration); + s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.configuration); + s.add(ProjectUri.Profiles.Profile.properties); + s.add(ProjectUri.Profiles.Profile.modules); + s.add(ProjectUri.Profiles.Profile.Dependencies.xUri); + s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.configuration); + + return new ArrayList(marshallXmlToModelProperties(is, ProjectUri.baseUri, s )); + } + + /** + * Returns XML string unmarshalled from the specified list of model properties + * + * @param modelProperties the model properties to unmarshal. May not be null or empty + * @param baseUri the base uri of every model property. May not be null or empty. + * @return XML string unmarshalled from the specified list of model properties + * @throws IOException if there was a problem with unmarshalling + */ + private static String unmarshalModelPropertiesToXml( List modelProperties, String baseUri ) + throws IOException + { + if ( modelProperties == null || modelProperties.isEmpty() ) + { + throw new IllegalArgumentException( "modelProperties: null or empty" ); + } + + if ( baseUri == null || baseUri.trim().length() == 0 ) + { + throw new IllegalArgumentException( "baseUri: null or empty" ); + } + + final int basePosition = baseUri.length(); + + StringBuffer sb = new StringBuffer(); + List lastUriTags = new ArrayList(); + for ( ModelProperty mp : modelProperties ) + { + String uri = mp.getUri(); + if ( uri.contains( "#property" ) ) + { + continue; + } + + //String val = (mp.getResolvedValue() != null) ? "\"" + mp.getResolvedValue() + "\"" : null; + // System.out.println("new ModelProperty(\"" + mp.getUri() +"\" , " + val +"),"); + if ( !uri.startsWith( baseUri ) ) + { + throw new IllegalArgumentException( + "Passed in model property that does not match baseUri: Property URI = " + uri + ", Base URI = " + + baseUri ); + } + + List tagNames = getTagNamesFromUri( basePosition, uri ); + + for ( int i = lastUriTags.size() - 1; i >= 0 && i >= tagNames.size() - 1; i-- ) + { + sb.append( toEndTag( lastUriTags.get( i ) ) ); + } + + String tag = tagNames.get( tagNames.size() - 1 ); + + List attributes = new ArrayList(); + for(int peekIndex = modelProperties.indexOf( mp ) + 1; peekIndex < modelProperties.size(); peekIndex++) + { + if ( peekIndex <= modelProperties.size() - 1 ) + { + ModelProperty peekProperty = modelProperties.get( peekIndex ); + if ( peekProperty.getUri().contains( "#property" ) ) + { + attributes.add(peekProperty); + } + else + { + break; + } + } + else + { + break; + } + } + + sb.append( toStartTag( tag, attributes ) ); + + if ( mp.getResolvedValue() != null ) + { + sb.append( mp.getResolvedValue() ); + } + + lastUriTags = tagNames; + } + + for ( int i = lastUriTags.size() - 1; i >= 1; i-- ) + { + sb.append( toEndTag( lastUriTags.get( i ) ) ); + } + + return sb.toString(); + } + + /** + * Returns list of tag names parsed from the specified uri. All #collection parts of the tag are removed from the + * tag names. + * + * @param basePosition the base position in the specified URI to start the parse + * @param uri the uri to parse for tag names + * @return list of tag names parsed from the specified uri + */ + private static List getTagNamesFromUri( int basePosition, String uri ) + { + return Arrays.asList( uri.substring( basePosition ).replaceAll( "#collection", "" ) + .replaceAll("#set", "").split( "/" ) ); + } + + /** + * Returns the XML formatted start tag for the specified value and the specified attribute. + * + * @param value the value to use for the start tag + * @param attributes the attribute to use in constructing of start tag + * @return the XML formatted start tag for the specified value and the specified attribute + */ + private static String toStartTag( String value, List attributes ) + { + StringBuffer sb = new StringBuffer(); //TODO: Support more than one attribute + sb.append( "\r\n<" ).append( value ); + if ( attributes != null ) + { + for(ModelProperty attribute : attributes) + { + sb.append( " " ).append( + attribute.getUri().substring( attribute.getUri().indexOf( "#property/" ) + 10 ) ).append( "=\"" ) + .append( attribute.getResolvedValue() ).append( "\" " ); + } + } + sb.append( ">" ); + return sb.toString(); + } + + /** + * Returns XML formatted end tag for the specified value. + * + * @param value the value to use for the end tag + * @return xml formatted end tag for the specified value + */ + private static String toEndTag( String value ) + { + if ( value.trim().length() == 0 ) + { + return ""; + } + StringBuffer sb = new StringBuffer(); + sb.append( "" ); + return sb.toString(); + } + + + private static final Set URIS = Collections.unmodifiableSet(new HashSet( Arrays.asList( ProjectUri.Build.Extensions.xUri, + ProjectUri.Build.PluginManagement.Plugins.xUri, + ProjectUri.Build.PluginManagement.Plugins.Plugin.configuration, + ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri, + ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.xURI, + ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri, + ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.Dependency.Exclusions.xUri, + ProjectUri.Build.Plugins.xUri, + ProjectUri.properties, + ProjectUri.Build.Plugins.Plugin.configuration, + ProjectUri.Reporting.Plugins.xUri, + ProjectUri.Reporting.Plugins.Plugin.configuration, + ProjectUri.Build.Plugins.Plugin.Dependencies.xUri, + ProjectUri.Build.Resources.xUri, + ProjectUri.Build.Resources.Resource.includes, + ProjectUri.Build.Resources.Resource.excludes, + ProjectUri.Build.TestResources.xUri, + ProjectUri.Build.Filters.xUri, + ProjectUri.CiManagement.Notifiers.xUri, + ProjectUri.Contributors.xUri, + ProjectUri.Dependencies.xUri, + ProjectUri.DependencyManagement.Dependencies.xUri, + ProjectUri.Developers.xUri, + ProjectUri.Developers.Developer.roles, + ProjectUri.Licenses.xUri, + ProjectUri.MailingLists.xUri, + ProjectUri.Modules.xUri, + ProjectUri.PluginRepositories.xUri, + ProjectUri.Profiles.xUri, + ProjectUri.Profiles.Profile.Build.Plugins.xUri, + ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Dependencies.xUri, + ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri, + ProjectUri.Profiles.Profile.Build.Resources.xUri, + ProjectUri.Profiles.Profile.Build.TestResources.xUri, + ProjectUri.Profiles.Profile.Dependencies.xUri, + ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.xUri, + ProjectUri.Profiles.Profile.PluginRepositories.xUri, + ProjectUri.Profiles.Profile.Reporting.Plugins.xUri, + ProjectUri.Profiles.Profile.Repositories.xUri, + ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.xUri, + ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri, + ProjectUri.Reporting.Plugins.xUri, + ProjectUri.Repositories.xUri) )); + + /** + * Returns list of model properties transformed from the specified input stream. + * + * @param inputStream input stream containing the xml document. May not be null. + * @param baseUri the base uri of every model property. May not be null or empty. + * @param collections set of uris that are to be treated as a collection (multiple entries). May be null. + * @return list of model properties transformed from the specified input stream. + * @throws IOException if there was a problem doing the transform + */ + private static List marshallXmlToModelProperties( InputStream inputStream, String baseUri, + Set collections ) + throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("inputStream: null"); + } + + if (baseUri == null || baseUri.trim().length() == 0) { + throw new IllegalArgumentException("baseUri: null"); + } + + if (collections == null) { + collections = Collections.emptySet(); + } + + List modelProperties = new ArrayList(); + XMLInputFactory xmlInputFactory = new com.ctc.wstx.stax.WstxInputFactory(); + xmlInputFactory.setProperty( + XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE); + xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, + Boolean.FALSE); + + Uri uri = new Uri(baseUri); + String tagName = baseUri; + StringBuilder tagValue = new StringBuilder(256); + + int depth = 0; + int depthOfTagValue = depth; + XMLStreamReader xmlStreamReader = null; + try { + xmlStreamReader = xmlInputFactory + .createXMLStreamReader(inputStream); + + Map attributes = new HashMap(); + for (;; xmlStreamReader.next()) { + int type = xmlStreamReader.getEventType(); + switch (type) { + + case XMLStreamConstants.CDATA: + case XMLStreamConstants.CHARACTERS: { + if (depth == depthOfTagValue) { + tagValue.append(xmlStreamReader.getTextCharacters(), + xmlStreamReader.getTextStart(), xmlStreamReader + .getTextLength()); + } + break; + } + + case XMLStreamConstants.START_ELEMENT: { + if (!tagName.equals(baseUri)) { + String value = null; + if (depth < depthOfTagValue) { + value = tagValue.toString().trim(); + } + modelProperties.add(new ModelProperty(tagName, value)); + if (!attributes.isEmpty()) { + for (Map.Entry e : attributes + .entrySet()) { + modelProperties.add(new ModelProperty(e + .getKey(), e.getValue())); + } + attributes.clear(); + } + } + + depth++; + tagName = uri.getUriFor(xmlStreamReader.getName() + .getLocalPart(), depth); + if (collections.contains(tagName + "#collection")) { + tagName = tagName + "#collection"; + uri.addTag(xmlStreamReader.getName().getLocalPart() + + "#collection"); + } else if (collections.contains(tagName + "#set")) { + tagName = tagName + "#set"; + uri.addTag(xmlStreamReader.getName().getLocalPart() + + "#set"); + } else { + uri.addTag(xmlStreamReader.getName().getLocalPart()); + } + tagValue.setLength(0); + depthOfTagValue = depth; + } + case XMLStreamConstants.ATTRIBUTE: { + for (int i = 0; i < xmlStreamReader.getAttributeCount(); i++) { + + attributes.put(tagName + + "#property/" + + xmlStreamReader.getAttributeName(i) + .getLocalPart(), xmlStreamReader + .getAttributeValue(i)); + } + break; + } + case XMLStreamConstants.END_ELEMENT: { + depth--; + break; + } + case XMLStreamConstants.END_DOCUMENT: { + modelProperties.add(new ModelProperty(tagName, tagValue + .toString().trim())); + if (!attributes.isEmpty()) { + for (Map.Entry e : attributes + .entrySet()) { + modelProperties.add(new ModelProperty(e.getKey(), e + .getValue())); + } + attributes.clear(); + } + return modelProperties; + } + } + } + } catch (XMLStreamException e) { + throw new IOException(":" + e.toString()); + } finally { + if (xmlStreamReader != null) { + try { + xmlStreamReader.close(); + } catch (XMLStreamException e) { + e.printStackTrace(); + } + } + try { + inputStream.close(); + } catch (IOException e) { + + } + } + } + + private static final Map aliases = new HashMap(); + + private static void addProjectAlias( String element, boolean leaf ) + { + String suffix = leaf ? "\\}" : "\\."; + aliases.put( "\\$\\{project\\." + element + suffix, "\\$\\{" + element + suffix ); + } + + static + { + aliases.put( "\\$\\{project\\.", "\\$\\{pom\\." ); + addProjectAlias( "modelVersion", true ); + addProjectAlias( "groupId", true ); + addProjectAlias( "artifactId", true ); + addProjectAlias( "version", true ); + addProjectAlias( "packaging", true ); + addProjectAlias( "name", true ); + addProjectAlias( "description", true ); + addProjectAlias( "inceptionYear", true ); + addProjectAlias( "url", true ); + addProjectAlias( "parent", false ); + addProjectAlias( "prerequisites", false ); + addProjectAlias( "organization", false ); + addProjectAlias( "build", false ); + addProjectAlias( "reporting", false ); + addProjectAlias( "scm", false ); + addProjectAlias( "distributionManagement", false ); + addProjectAlias( "issueManagement", false ); + addProjectAlias( "ciManagement", false ); + } + + private static boolean containsProjectVersion( List interpolatorProperties ) + { + InterpolatorProperty versionInterpolatorProperty = + new ModelProperty( ProjectUri.version, "" ).asInterpolatorProperty( ProjectUri.baseUri ); + for ( InterpolatorProperty ip : interpolatorProperties ) + { + if ( ip.equals( versionInterpolatorProperty ) ) + { + return true; + } + } + return false; + } + /** + * Class for storing information about URIs. + */ + private static class Uri + { + + List uris; + + Uri( String baseUri ) + { + uris = new LinkedList(); + uris.add( baseUri ); + } + + String getUriFor( String tag, int depth ) + { + setUrisToDepth( depth ); + StringBuffer sb = new StringBuffer(); + for ( String tagName : uris ) + { + sb.append( tagName ).append( "/" ); + } + sb.append( tag ); + return sb.toString(); + } + + void addTag( String tag ) + { + uris.add( tag ); + } + + void setUrisToDepth( int depth ) + { + uris = new LinkedList( uris.subList( 0, depth ) ); + } + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/Interpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/Interpolator.java new file mode 100644 index 0000000000..63c2972db7 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/Interpolator.java @@ -0,0 +1,17 @@ +package org.apache.maven.model.interpolator; + +import java.io.IOException; +import java.util.List; + +import org.apache.maven.model.PomClassicDomainModel; + +public interface Interpolator +{ + + String interpolateXmlString( String xml, List interpolatorProperties ) + throws IOException; + + PomClassicDomainModel interpolateDomainModel( PomClassicDomainModel dm, List interpolatorProperties ) + throws IOException ; + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/InterpolatorProperty.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/InterpolatorProperty.java new file mode 100644 index 0000000000..f82197f68c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/InterpolatorProperty.java @@ -0,0 +1,175 @@ +package org.apache.maven.model.interpolator; + +import java.util.*; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Provides interpolator property information. + */ +public final class InterpolatorProperty +{ + /** + * The key (or name) of the property + */ + private final String key; + + /** + * The value of the property + */ + private final String value; + + /** + * Metadata tag (general use) + */ + private String tag; + + + /** + * Constructor + * + * @param key the key (or name) of the property. May not be null + * @param value the value of the property. May not be null. + */ + public InterpolatorProperty( String key, String value ) + { + this(key, value, null); + } + + public InterpolatorProperty( String key, String value, String tag ) + { + if ( key == null ) + { + throw new IllegalArgumentException( "key: null" ); + } + + if ( value == null ) + { + throw new IllegalArgumentException( "value: null" ); + } + this.key = key; + this.value = value; + this.tag = tag; + + } + + /** + * Returns key (or name) of property. + * + * @return key (or name) of property + */ + public String getKey() + { + return key; + } + + /** + * Returns value of property. + * + * @return value of property + */ + public String getValue() + { + return value; + } + + public String getTag() + { + return tag; + } + + public void setTag(String tag) + { + this.tag = tag; + } + public static List toInterpolatorProperties( Map properties, String tag ) + { + if( properties == null ) + { + throw new IllegalArgumentException( "properties: null" ); + } + + List interpolatorProperties = new ArrayList(); + for ( Map.Entry e : properties.entrySet() ) + { + interpolatorProperties.add( new InterpolatorProperty( "${" + e.getKey() +"}", e.getValue(), tag) ); + } + return interpolatorProperties; + } + + /** + * Returns true if key values match, otherwise returns false. + * + * @param o interpolator property to compare + * @return true if key values match, otherwise returns false + */ + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + + InterpolatorProperty that = (InterpolatorProperty) o; + + if ( !key.equals( that.key ) ) + { + return false; + } + + return true; + } + + /** + * Returns hash code of interpolator property key. + * + * @return hash code of interpolator property key + */ + public int hashCode() + { + return key.hashCode(); + } + + public String toString() + { + return "Key = " + key + ", Value = " + value + ", Hash = " + + this.hashCode(); + } + + public static List toInterpolatorProperties( Properties properties, String tag ) + { + if( properties == null ) + { + throw new IllegalArgumentException( "properties: null" ); + } + + List interpolatorProperties = new ArrayList(); + for ( Map.Entry e : properties.entrySet() ) + { + interpolatorProperties.add( new InterpolatorProperty( "${" + e.getKey() +"}", (String) e.getValue(), tag) ); + } + return interpolatorProperties; + } +} + diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/ModelProperty.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/ModelProperty.java new file mode 100644 index 0000000000..8b2f5f9671 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/ModelProperty.java @@ -0,0 +1,255 @@ +package org.apache.maven.model.interpolator; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * Maps a URI to a string value, which may be null. This class is immutable. + */ +final class ModelProperty +{ + + /** + * A pattern used for finding pom, project and env properties + */ + private static final Pattern EXPRESSION_PATTERN = Pattern.compile( "\\$\\{(pom\\.|project\\.|env\\.)?([^}]+)\\}" ); + + /** + * URI of the resource + */ + private final String uri; + + /** + * Value associated with the uri + */ + private final String value; + + /** + * The count of '/' within this model property's uri, which is the depth of its XML nodes. + */ + private final int depth; + + /** + * Value of this model property after interpolation + */ + private String resolvedValue; + + /** + * List of unresolved expressions within this model property's value + */ + private final List unresolvedExpressions; + + /** + * Constructor + * + * @param uri URI of the resource. May not be null + * @param value Value associated with specified uri. Value may be null if uri does not map to primitive type. + */ + public ModelProperty( String uri, String value ) + { + if ( uri == null ) + { + throw new IllegalArgumentException( "uri" ); + } + this.uri = uri; + this.value = value; + resolvedValue = value; + + unresolvedExpressions = new ArrayList(); + if ( value != null ) + { + Matcher matcher = EXPRESSION_PATTERN.matcher( value ); + while ( matcher.find() ) + { + unresolvedExpressions.add( matcher.group( 0 ) ); + } + } + + String uriWithoutProperty; + int index = uri.lastIndexOf( "/" ); + if(index > -1) { + uriWithoutProperty = uri.substring( 0, uri.lastIndexOf( "/" ) ); + if(uriWithoutProperty.endsWith("#property") || uriWithoutProperty.endsWith("combine.children") ) + { + uriWithoutProperty = uriWithoutProperty.substring( 0, uriWithoutProperty.lastIndexOf( "/" ) ); + } + } + else + { + uriWithoutProperty = uri; + } + + depth = uriWithoutProperty.split( "/" ).length; + } + + /** + * Returns URI key + * + * @return URI key + */ + public String getUri() + { + return uri; + } + + /** + * Returns value for the URI key. Value may be null. + * + * @return value for the URI key. Value may be null + */ + public String getValue() + { + return value; + } + + /** + * Value of this model property after interpolation. CDATA section will be added if needed. + * + * @return value of this model property after interpolation + */ + public String getResolvedValue() + { + if( !uri.contains("#property") && resolvedValue != null && !resolvedValue.startsWith (""; + } + return resolvedValue; + } + + /** + * Returns true if model property is completely interpolated, otherwise returns false. + * + * @return true if model property is completely interpolated, otherwise returns false + */ + public boolean isResolved() + { + return unresolvedExpressions.isEmpty(); + } + + /** + * Returns copy of the uninterpolated model property + * + * @return copy of the uninterpolated model property + */ + public ModelProperty createCopyOfOriginal() + { + return new ModelProperty( uri, value ); + } + + /** + * Returns the count of '/' within this model property's uri, which is the depth of its XML nodes. + * + * @return the count of '/' within this model property's uri, which is the depth of its XML nodes + */ + public int getDepth() + { + return depth; + } + + /** + * Returns true if this model property is a direct parent of the specified model property, otherwise returns false. + * + * @param modelProperty the model property + * @return true if this model property is a direct parent of the specified model property, otherwise returns false + */ + public boolean isParentOf( ModelProperty modelProperty ) + { + if ( Math.abs( depth - modelProperty.getDepth() ) > 1 ) + { + return false; + } + if ( uri.equals( modelProperty.getUri() ) || uri.startsWith( modelProperty.getUri() ) ) + { + return false; + } + return ( modelProperty.getUri().startsWith( uri ) ); + } + + /** + * Returns this model property as an interpolator property, allowing the interpolation of model elements within + * other model elements. + * + * @param baseUri the base uri of the model property + * @return this model property as an interpolator property, allowing the interpolation of model elements within + * other model elements + */ + public InterpolatorProperty asInterpolatorProperty( String baseUri ) + { + if ( uri.contains( "#collection" ) || uri.contains("#set") || value == null ) + { + return null; + } + String key = "${" + uri.replace( baseUri + "/", "" ).replace( "/", "." ) + "}"; + return new InterpolatorProperty( key, value ); + } + + /** + * Resolves any unresolved model property expressions using the specified interpolator property + * + * @param property the interpolator property used to resolve + */ + public boolean resolveWith( InterpolatorProperty property ) + { + if ( property == null ) + { + throw new IllegalArgumentException( "property: null" ); + } + if ( isResolved() ) + { + return false; + } + boolean resolved = false; + for ( String expression : unresolvedExpressions ) + { + if ( property.getKey().equals( expression ) ) + { + resolved = true; + resolvedValue = resolvedValue.replace( property.getKey(), property.getValue() ); + unresolvedExpressions.clear(); + Matcher matcher = EXPRESSION_PATTERN.matcher( resolvedValue ); + while ( matcher.find() ) + { + unresolvedExpressions.add( matcher.group( 0 ) ); + } + break; + } + } + return resolved; + } + + public String toCode() { + String val = (value != null) ? "\"" + value + "\"" : null; + return "mpz.add(new ModelProperty(\"" + uri + "\", " + val +"));"; + } + + public String toString() + { + return "Uri = " + uri + ", Value = " + value + ", Resolved Value = " + resolvedValue + ", Hash = " + + this.hashCode(); + } +} + + diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomInterpolatorTag.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/PomInterpolatorTag.java similarity index 70% rename from maven-project-builder/src/main/java/org/apache/maven/project/builder/PomInterpolatorTag.java rename to maven-model-builder/src/main/java/org/apache/maven/model/interpolator/PomInterpolatorTag.java index 5f7693550e..18c1057e8f 100644 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomInterpolatorTag.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolator/PomInterpolatorTag.java @@ -1,4 +1,4 @@ -package org.apache.maven.project.builder; +package org.apache.maven.model.interpolator; public enum PomInterpolatorTag diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/BaseProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/BaseProcessor.java new file mode 100644 index 0000000000..1ceba9f289 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/BaseProcessor.java @@ -0,0 +1,177 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.maven.model.Model; +import org.apache.maven.model.Processor; + +public abstract class BaseProcessor implements Processor +{ + + Object parent; + + Object child; + + Collection processors; + + private List parentModels; + + + public BaseProcessor( Collection processors ) + { + if ( processors == null ) + { + throw new IllegalArgumentException( "processors: null" ); + } + + this.processors = processors; + parentModels = new ArrayList(); + } + + /** + * Ordered from least specialized to most specialized. + */ + public List getParentModels() + { + return parentModels; + } + + public BaseProcessor() + { + this(new ArrayList()); + } + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + if ( target == null ) + { + throw new IllegalArgumentException( "target: null" ); + } + + this.parent = parent; + this.child = child; + if(parent instanceof Model) + { + parentModels.add( (Model) parent ); + } + for ( Processor processor : processors ) + { + processor.process( parent, child, target, isChildMostSpecialized ); + } + + } + + public Object getChild() + { + return child; + } + + public Object getParent() + { + return parent; + } + + protected String normalizeUriWithRelativePath(String u, String artifactId, Model parent) + { + if(u == null) + { + return null; + } + try + { + String slashes = getSlashes(new URI(u).getRawSchemeSpecificPart()); + URI uri = new URI(u + "/" + + getModulePathAdjustment(parent, artifactId)); + + String normalized = uri.normalize().toASCIIString(); + if("file".equals(uri.getScheme()))//UNC Paths + { + normalized = normalized.replaceFirst("/", slashes); + } + return normalized; + } + catch (URISyntaxException e) { + + } + return null; + } + + private static String getSlashes(String uri) + { + StringBuilder sb = new StringBuilder(); + for(byte b : uri.getBytes()) + { + if(b == 47) + { + sb.append("/"); + } + else + { + break; + } + } + return sb.toString(); + } + + private String getModulePathAdjustment(Model moduleProject, + String artifactId) { + + Map moduleAdjustments = new HashMap(); + List modules = moduleProject.getModules(); + if (modules != null) { + for (Iterator it = modules.iterator(); it.hasNext();) { + String modulePath = it.next(); + String moduleName = modulePath; + + if (moduleName.endsWith("/") || moduleName.endsWith("\\")) { + moduleName = moduleName.substring(0, + moduleName.length() - 1); + } + + int lastSlash = moduleName.lastIndexOf('/'); + + if (lastSlash < 0) { + lastSlash = moduleName.lastIndexOf('\\'); + } + + String adjustment = null; + + if (lastSlash > -1) { + moduleName = moduleName.substring(lastSlash + 1); + adjustment = modulePath.substring(0, lastSlash); + } + + moduleAdjustments.put(moduleName, adjustment); + } + } + String adjust = moduleAdjustments.get(artifactId); + return (adjust != null) ? adjust + "/" + artifactId : "/" + artifactId; + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/BuildProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/BuildProcessor.java new file mode 100644 index 0000000000..99f2832ead --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/BuildProcessor.java @@ -0,0 +1,264 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.Extension; +import org.apache.maven.model.Model; +import org.apache.maven.model.ModelEventListener; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Processor; +import org.apache.maven.model.Resource; + +public class BuildProcessor + extends BaseProcessor +{ + private List listeners; + + public BuildProcessor( Collection processors ) + { + super( processors ); + listeners = new ArrayList(); + } + + public BuildProcessor( Collection processors, List listeners) + { + super( processors ); + listeners = (listeners == null) ? new ArrayList() : new ArrayList(listeners); + } + + public void processWithProfile( BuildBase build, Model target ) + { + processBuild(null, build, target, false, true ); + } + + private void processBuild(Model p, BuildBase build, Model t, boolean isChildMostSpecialized, boolean isProfile) + { + + if(t.getBuild() == null) + { + t.setBuild( new Build() ); + } + + PluginsProcessor pluginsProcessor = new PluginsProcessor(); + if(build == null && !( p == null || p.getBuild() == null)) + { + copy(p.getBuild(), t.getBuild(), isProfile); + copyFilters(p.getBuild(), t.getBuild()); + pluginsProcessor.process( p.getBuild().getPlugins(), null, t.getBuild().getPlugins(), isChildMostSpecialized ); + inheritManagement(p.getBuild().getPluginManagement(), null, t.getBuild()); + } + else if(build != null && !( p == null || p.getBuild() == null)) + { + copy(p.getBuild(), t.getBuild(), isProfile); + copy(build, t.getBuild(), isProfile); + + copyFilters(build, t.getBuild()); + copyFilters(p.getBuild(), t.getBuild()); + + pluginsProcessor.process( p.getBuild().getPlugins(), build.getPlugins(), t.getBuild().getPlugins(), isChildMostSpecialized ); + inheritManagement(p.getBuild().getPluginManagement(), build.getPluginManagement(), t.getBuild()); + } + else if(build != null ) + { + copy(build, t.getBuild(), isProfile); + copyFilters(build, t.getBuild()); + pluginsProcessor.process( null, build.getPlugins(), t.getBuild().getPlugins(), isChildMostSpecialized ); + inheritManagement(null, build.getPluginManagement(), t.getBuild()); + } + } + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + processBuild(p, c.getBuild(), t, isChildMostSpecialized, false ); + } + + private static void inheritManagement(PluginManagement parent, PluginManagement child, Build target) + { + PluginsProcessor proc = new PluginsProcessor(); + List p = (parent == null) ? new ArrayList() : parent.getPlugins(); + List c = (child == null) ? new ArrayList() : child.getPlugins(); + + if(!c.isEmpty() || !p.isEmpty()) + { + if(target.getPluginManagement() == null) + { + target.setPluginManagement( new PluginManagement() ); + } + proc.process( p, c, target.getPluginManagement().getPlugins(), false ); + } + } + + private static void copyFilters(BuildBase source, Build target) + { + List filters = new ArrayList(target.getFilters()); + for(String filter : source.getFilters()) + { + if(!filters.contains( filter )) + { + filters.add( filter ); + } + } + + // SortedSet s = new TreeSet( new ArrayList( target.getFilters() ) ); + // s.addAll( source.getFilters() ); + // List l = Arrays.asList(s.toArray( new String[s.size()]) ); + + target.setFilters( filters ); + } + + private static void copy(BuildBase source, Build target, boolean isProfile) + { + if(source.getFinalName() != null) + { + target.setFinalName( source.getFinalName() ); + } + + if(source.getDefaultGoal() != null) + { + target.setDefaultGoal( source.getDefaultGoal() ); + } + + if(source.getDirectory() != null) + { + target.setDirectory( source.getDirectory() ); + } + + if(!source.getResources().isEmpty()) + { + List resources = new ArrayList(); + for(Resource resource : source.getResources()) + { + Resource r = new Resource(); + r.setDirectory( resource.getDirectory()); + r.setFilteringValue( resource.getFilteringValue() ); + r.setMergeId( resource.getMergeId() ); + r.setTargetPath( resource.getTargetPath() ); + r.setExcludes( new ArrayList(resource.getExcludes()) ); + r.setIncludes( new ArrayList(resource.getIncludes()) ); + resources.add( r ); + } + target.setResources( resources ); + } + + if(!source.getTestResources().isEmpty()) + { + List resources = new ArrayList(); + for(Resource resource : source.getTestResources()) + { + Resource r = new Resource(); + r.setDirectory( resource.getDirectory()); + r.setFiltering( resource.isFiltering() ); + r.setMergeId( resource.getMergeId() ); + r.setTargetPath( resource.getTargetPath() ); + r.setExcludes( new ArrayList(resource.getExcludes()) ); + r.setIncludes( new ArrayList(resource.getIncludes()) ); + resources.add( r ); + } + target.setTestResources( resources ); + } + if(!isProfile) + { + copyBuild((Build) source, target); + } + } + + private static void copyBuild(Build source, Build target) + { + if(source.getOutputDirectory() != null) + { + target.setOutputDirectory( source.getOutputDirectory() ); + } + + if(source.getScriptSourceDirectory() != null) + { + target.setScriptSourceDirectory( source.getScriptSourceDirectory() ); + } + + if(source.getSourceDirectory() != null) + { + target.setSourceDirectory( source.getSourceDirectory() ); + } + + if(source.getTestOutputDirectory() != null) + { + target.setTestOutputDirectory( source.getTestOutputDirectory() ); + } + + if(source.getTestSourceDirectory() != null) + { + target.setTestSourceDirectory( source.getTestSourceDirectory() ); + } + /* + List childDependencies = + new ArrayList(dependencies.subList( length - 1 , dependencies.size() ) ); + dependencies.removeAll( childDependencies ); + dependencies.addAll( 0, childDependencies ); + */ + int i = target.getExtensions().size(); + + List m = new ArrayList(); + for(Extension extension : source.getExtensions()) + { + Extension match = isMatch(extension, target.getExtensions()); + if(match != null) + { + match.setArtifactId( extension.getArtifactId() ); + match.setGroupId( extension.getGroupId() ); + match.setVersion( extension.getVersion() ); + m.add( match ); + } + else + { + Extension e = new Extension(); + e.setArtifactId( extension.getArtifactId() ); + e.setGroupId( extension.getGroupId() ); + e.setVersion( extension.getVersion() ); + m.add( e ); + } + } + target.getExtensions().removeAll( m ); + target.getExtensions().addAll( 0, m ); + } + + private static Extension isMatch(Extension extension, List extensions) + { + for(Extension e : extensions) + { + if(e.getGroupId().equals( extension.getGroupId() ) && e.getArtifactId().equals( extension.getArtifactId() )) + { + return e; + } + } + return null; + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/CiManagementProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/CiManagementProcessor.java new file mode 100644 index 0000000000..60fe4e97f8 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/CiManagementProcessor.java @@ -0,0 +1,89 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.Model; +import org.apache.maven.model.Notifier; + +public class CiManagementProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if ( c.getCiManagement() != null ) + { + CiManagement childMng = c.getCiManagement(); + CiManagement mng = new CiManagement(); + + mng.setSystem( childMng.getSystem() ); + mng.setUrl( childMng.getUrl() ); + t.setCiManagement( mng ); + addNotifiers( c.getCiManagement().getNotifiers(), t.getCiManagement() ); + } + else if ( p != null && p.getCiManagement() != null ) + { + CiManagement parentMng = p.getCiManagement(); + CiManagement mng = new CiManagement(); + + mng.setSystem( parentMng.getSystem() ); + mng.setUrl( parentMng.getUrl() ); + t.setCiManagement( mng ); + addNotifiers( p.getCiManagement().getNotifiers(), t.getCiManagement() ); + } + } + + private static void addNotifiers( List notifiers, CiManagement ciManagement ) + { + if ( notifiers == null ) + { + return; + } + List n = new ArrayList(); + + for ( Notifier notifier : notifiers ) + { + Notifier notifierCopy = new Notifier(); + + Properties properties = new Properties(); + properties.putAll( notifier.getConfiguration() ); + notifierCopy.setConfiguration( properties ); + + notifierCopy.setAddress( notifier.getAddress() ); + notifierCopy.setSendOnError( notifier.isSendOnError() ); + notifierCopy.setSendOnFailure( notifier.isSendOnFailure() ); + notifierCopy.setSendOnSuccess( notifier.isSendOnSuccess() ); + notifierCopy.setSendOnWarning( notifier.isSendOnWarning() ); + notifierCopy.setType( notifier.getType() ); + n.add( notifierCopy ); + + } + ciManagement.getNotifiers().addAll( n ); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ContributorsProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ContributorsProcessor.java new file mode 100644 index 0000000000..fe58fdc760 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ContributorsProcessor.java @@ -0,0 +1,70 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.maven.model.Contributor; +import org.apache.maven.model.Model; + +public class ContributorsProcessor + extends BaseProcessor +{ + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model p = (Model) parent; + Model c = (Model) child; + Model t = (Model) target; + + if ( !c.getContributors().isEmpty() ) + { + copyContributors( c.getContributors(), t ); + } + else if ( p != null && !p.getContributors().isEmpty() ) + { + copyContributors( p.getContributors(), t ); + } + } + + private static void copyContributors( List contributors, Model target ) + { + for ( Contributor contributor : contributors ) + { + Contributor copy = new Contributor(); + copy.setName( contributor.getName() ); + copy.setEmail( contributor.getEmail() ); + copy.setUrl( contributor.getUrl() ); + copy.setOrganization( contributor.getOrganization() ); + copy.setOrganizationUrl( contributor.getOrganizationUrl() ); + copy.setTimezone( contributor.getTimezone() ); + copy.setRoles( new ArrayList( contributor.getRoles() ) ); + Properties props = new Properties(); + props.putAll( contributor.getProperties() ); + copy.setProperties( props ); + target.addContributor( copy ); + } + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependenciesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependenciesProcessor.java new file mode 100644 index 0000000000..a2602fe3c6 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependenciesProcessor.java @@ -0,0 +1,92 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.maven.model.Dependency; + + +public class DependenciesProcessor + extends BaseProcessor +{ + private boolean isDependencyManagement; + + public DependenciesProcessor() {} + + public DependenciesProcessor(boolean isDependencyManagement) { + this.isDependencyManagement = isDependencyManagement; + } + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + List c = (child != null) ? (List) child : new ArrayList() ; + List p = null; + + if ( parent != null ) + { + p = (List) parent; + } + List dependencies = (List) target; + + DependencyProcessor processor = new DependencyProcessor(isDependencyManagement); + if ( ( p == null || p.isEmpty() ) && !c.isEmpty() ) + { + for ( Dependency dependency : c ) + { + processor.process( null, dependency, dependencies, isChildMostSpecialized ); + } + } + else + { + if ( !c.isEmpty() ) + { + + for ( Dependency parentDependency : p ) + { + processor.process( parentDependency, null, dependencies, isChildMostSpecialized ); + } + + int length = dependencies.size(); + + for ( Dependency childDependency : c ) + { + processor.process( null, childDependency, dependencies, isChildMostSpecialized ); + } + + //Move elements so child dependencies are first + List childDependencies = + new ArrayList(dependencies.subList( length - 1 , dependencies.size() ) ); + dependencies.removeAll( childDependencies ); + dependencies.addAll( 0, childDependencies ); + } + else if( p != null) + { + for ( Dependency d2 : p ) + { + processor.process( d2, null, dependencies, isChildMostSpecialized ); + } + } + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyManagementProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyManagementProcessor.java new file mode 100644 index 0000000000..b162384f7e --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyManagementProcessor.java @@ -0,0 +1,132 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; + +public class DependencyManagementProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + List depManagement = (List ) child; + List targetDependencies = (List) target; + + for(Dependency depMng : depManagement) + { + for(Dependency targetDep : targetDependencies) + { + if(match(depMng, targetDep)) + { + copy(depMng, targetDep ); + } + } + } + } + + private static void copy( Dependency dependency, Dependency targetDependency ) + { + if ( targetDependency.getArtifactId() == null ) + { + targetDependency.setArtifactId( dependency.getArtifactId() ); + } + + if ( targetDependency.getClassifier() == null ) + { + targetDependency.setClassifier( dependency.getClassifier() ); + } + + if ( targetDependency.getGroupId() == null ) + { + targetDependency.setGroupId( dependency.getGroupId() ); + } + + if ( targetDependency.getScope() == null ) + { + targetDependency.setScope( dependency.getScope() ); + } + + if ( targetDependency.getSystemPath() == null ) + { + targetDependency.setSystemPath( dependency.getSystemPath() ); + } + + if ( targetDependency.getType() == null ) + { + targetDependency.setType( dependency.getType() ); + } + + if ( targetDependency.getVersion() == null ) + { + targetDependency.setVersion( dependency.getVersion() ); + } + + if ( !dependency.getExclusions().isEmpty() ) + { + List targetExclusions = targetDependency.getExclusions(); + for ( Exclusion e : dependency.getExclusions() ) + { + if ( !containsExclusion( e, targetExclusions ) ) + { + Exclusion e1 = new Exclusion(); + e1.setArtifactId( e.getArtifactId() ); + e1.setGroupId( e.getGroupId() ); + targetDependency.addExclusion( e1 ); + } + } + } + + targetDependency.setOptional( dependency.isOptional() ); + } + + private static boolean containsExclusion( Exclusion exclusion, List exclusions ) + { + if(exclusions == null || exclusions.isEmpty()) + { + return false; + } + + for ( Exclusion e : exclusions ) + { + if ( e.getGroupId().equals( exclusion.getGroupId() ) + && e.getArtifactId().equals( exclusion.getArtifactId() ) ) + { + return true; + } + } + return false; + } + + private boolean match( Dependency d1, Dependency d2 ) + { + return getId( d1 ).equals( getId( d2 ) ); + } + + private String getId( Dependency d ) + { + StringBuilder sb = new StringBuilder(); + sb.append( d.getGroupId() ).append( ":" ).append( d.getArtifactId() ); + return sb.toString(); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyProcessor.java new file mode 100644 index 0000000000..4088077b98 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DependencyProcessor.java @@ -0,0 +1,225 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; + +public class DependencyProcessor + extends BaseProcessor +{ + private boolean isDependencyManagement; + + public DependencyProcessor(){ } + + public DependencyProcessor(boolean isDependencyManagement) + { + this.isDependencyManagement = isDependencyManagement; + } + /* + * Process children first + */ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + List t = (List) target; + + if ( parent == null && child == null ) + { + return; + } + else if ( parent == null && child != null ) + { + boolean isAdd = true; + Dependency targetDependency = contains((Dependency) child, t); + if(targetDependency == null) + { + targetDependency = new Dependency(); + } + else + { + isAdd = false; + } + + if(!isAdd) + { + t.remove( targetDependency ); + } + + copy( (Dependency) child, targetDependency); + + t.add( targetDependency ); + + } + else if ( parent != null && child == null ) + { + boolean isAdd = true; + Dependency targetDependency = contains((Dependency) parent, t); + if(targetDependency == null) + { + targetDependency = new Dependency(); + } + else + { + isAdd = false; + } + copy( (Dependency) parent, targetDependency); + if(isAdd) t.add( targetDependency ); + } + else + // JOIN + { + Dependency targetDependency = new Dependency(); + copy( (Dependency) parent, targetDependency ); + copy( (Dependency) child, targetDependency); + /* + if( isMatch( (Dependency) child, (Dependency) parent)) + { + copy( (Dependency) child, targetDependency); + } + else + { + copy( (Dependency) parent, targetDependency ); + copy( (Dependency) child, targetDependency); + } +*/ + t.add( targetDependency ); + } + } + + private static boolean isMatch(Dependency d1, Dependency d2) + { + return d1.getGroupId().equals(d2.getGroupId()) && d1.getArtifactId().equals(d2.getArtifactId()); + } + + private Dependency contains(Dependency d1, List dependencies) + { + for(Dependency d : dependencies) + { + if( match(d, d1)) + { + return d; + } + } + return null; + } + + private boolean match( Dependency d1, Dependency d2 ) + { + // TODO: Version ranges ? + return getId( d1 ).equals( getId( d2 ) ); + + } + + private String getId( Dependency d ) + { + StringBuilder sb = new StringBuilder(); + + sb.append( d.getGroupId() ).append( ":" ).append( d.getArtifactId() ); + sb.append( ":" ).append( + d.getType() == null ? "jar" + : d.getType() ).append( + ":" ).append( + d.getClassifier() ); + + return sb.toString(); + } + + private boolean isMatch(Object source, Object target, boolean isDependencyManagement) + { + return (source != null && !isDependencyManagement) || target == null; + } + + private void copy( Dependency source, Dependency targetDependency) + { + if ( isMatch(source.getArtifactId(), targetDependency.getArtifactId(), isDependencyManagement) ) + { + targetDependency.setArtifactId( source.getArtifactId() ); + } + + if ( isMatch(source.getClassifier(), targetDependency.getClassifier(), isDependencyManagement) ) + { + targetDependency.setClassifier( source.getClassifier() ); + } + + if ( isMatch(source.getGroupId(), targetDependency.getGroupId(), isDependencyManagement) ) + { + targetDependency.setGroupId( source.getGroupId() ); + } + + if (isMatch(source.getScope(), targetDependency.getScope(), isDependencyManagement) ) + { + targetDependency.setScope( source.getScope() ); + } + + if ( isMatch(source.getSystemPath(), targetDependency.getSystemPath(), isDependencyManagement) ) + { + targetDependency.setSystemPath( source.getSystemPath() ); + } + + if ( isMatch(source.getType(), targetDependency.getType(), isDependencyManagement)) + { + targetDependency.setType( source.getType() ); + } + + if ( isMatch(source.getVersion(), targetDependency.getVersion(), isDependencyManagement) ) + { + targetDependency.setVersion( source.getVersion() ); + } + + if ( !source.getExclusions().isEmpty() ) + { + List targetExclusions = targetDependency.getExclusions(); + for ( Exclusion e : source.getExclusions() ) + { + if ( !containsExclusion( e, targetExclusions ) ) + { + Exclusion e1 = new Exclusion(); + e1.setArtifactId( e.getArtifactId() ); + e1.setGroupId( e.getGroupId() ); + targetDependency.addExclusion( e1 ); + } + } + } + + targetDependency.setOptional( source.isOptional() ); + } + + private static boolean containsExclusion( Exclusion exclusion, List exclusions ) + { + if(exclusions == null || exclusions.isEmpty()) + { + return false; + } + + for ( Exclusion e : exclusions ) + { + if ( e.getGroupId().equals( exclusion.getGroupId() ) + && e.getArtifactId().equals( exclusion.getArtifactId() ) ) + { + return true; + } + } + return false; + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/DevelopersProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DevelopersProcessor.java new file mode 100644 index 0000000000..2b31e20966 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DevelopersProcessor.java @@ -0,0 +1,71 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.maven.model.Developer; +import org.apache.maven.model.Model; + +public class DevelopersProcessor + extends BaseProcessor +{ + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model p = (Model) parent; + Model c = (Model) child; + Model t = (Model) target; + + if ( !c.getDevelopers().isEmpty() ) + { + copyDevelopers( c.getDevelopers(), t ); + } + else if ( p != null && !p.getDevelopers().isEmpty() ) + { + copyDevelopers( p.getDevelopers(), t ); + } + } + + private static void copyDevelopers( List developers, Model target ) + { + for ( Developer developer : developers ) + { + Developer copy = new Developer(); + copy.setId( developer.getId() ); + copy.setName( developer.getName() ); + copy.setEmail( developer.getEmail() ); + copy.setUrl( developer.getUrl() ); + copy.setOrganization( developer.getOrganization() ); + copy.setOrganizationUrl( developer.getOrganizationUrl() ); + copy.setTimezone( developer.getTimezone() ); + copy.setRoles( new ArrayList( developer.getRoles() ) ); + Properties props = new Properties(); + props.putAll( developer.getProperties() ); + copy.setProperties( props ); + target.addDeveloper( copy ); + } + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/DistributionManagementProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DistributionManagementProcessor.java new file mode 100644 index 0000000000..3c9727c5b7 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/DistributionManagementProcessor.java @@ -0,0 +1,163 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.DeploymentRepository; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.Model; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.Site; + +public class DistributionManagementProcessor + extends BaseProcessor +{ + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if ( t.getDependencyManagement() == null + && ( p != null && p.getDistributionManagement() != null || c.getDistributionManagement() != null ) ) + { + t.setDistributionManagement( new DistributionManagement() ); + } + + if ( c.getDistributionManagement() != null ) + { + if ( p != null && p.getDistributionManagement() != null ) + { + copy( p.getDistributionManagement(), t.getDistributionManagement(), false, c.getArtifactId(), p ); + } + copy( c.getDistributionManagement(), t.getDistributionManagement(), isChildMostSpecialized, + c.getArtifactId(), p ); + } + else if ( p != null && p.getDistributionManagement() != null ) + { + copy( p.getDistributionManagement(), t.getDistributionManagement(), false, c.getArtifactId(), p ); + } + else if(t.getDistributionManagement() != null && t.getDistributionManagement().getSite() != null) + { + copySite( t.getDistributionManagement().getSite(), t.getDistributionManagement().getSite(), false, c.getArtifactId(), p ); + // copy( t.getDistributionManagement(), t.getDistributionManagement(), isChildMostSpecialized, c.getArtifactId() ); + } + } + + private void copy( DistributionManagement source, DistributionManagement target, boolean isChild, + String artifactId, Model parent ) + { + if ( source.getDownloadUrl() != null ) + { + target.setDownloadUrl( source.getDownloadUrl() ); + } + + if ( isChild && source.getRelocation() != null ) + { + Relocation sourceRelocation = source.getRelocation(); + Relocation r = new Relocation(); + r.setArtifactId( sourceRelocation.getArtifactId() ); + r.setGroupId( sourceRelocation.getGroupId() ); + r.setMessage( sourceRelocation.getMessage() ); + r.setVersion( sourceRelocation.getVersion() ); + target.setRelocation( r ); + } + + if ( source.getStatus() != null ) + { + target.setStatus( source.getStatus() ); + } + + if ( source.getRepository() != null ) + { + target.setRepository( new DeploymentRepository() ); + copyRepository( source.getRepository(), target.getRepository() ); + } + + if ( source.getSnapshotRepository() != null ) + { + target.setSnapshotRepository( new DeploymentRepository() ); + copyRepository( source.getSnapshotRepository(), target.getSnapshotRepository() ); + } + + if ( source.getSite() != null ) + { + target.setSite( new Site() ); + copySite( source.getSite(), target.getSite(), isChild, artifactId, parent ); + } + } + + private void copyRepository( DeploymentRepository source, DeploymentRepository target ) + { + if ( source.getId() != null ) + { + target.setId( source.getId() ); + } + + if ( source.getLayout() != null ) + { + target.setLayout( source.getLayout() ); + } + + if ( source.getUrl() != null ) + { + target.setUrl( source.getUrl() ); + } + + if ( source.getName() != null ) + { + target.setName( source.getName() ); + } + + target.setUniqueVersion( source.isUniqueVersion() ); + } + + private void copySite( Site source, Site target, boolean isChild, String artifactId, Model parent ) + { + if ( source.getId() != null ) + { + target.setId( source.getId() ); + } + + if ( source.getName() != null ) + { + target.setName( source.getName() ); + } + + if ( target.getUrl() == null ) + { + if ( isChild ) + { + target.setUrl( source.getUrl() ); + } + else + { + target.setUrl(normalizeUriWithRelativePath(source.getUrl(), artifactId, parent)); + } + } + else + { + target.setUrl( target.getUrl() + (target.getUrl().endsWith("/") ? "" : "/")+ artifactId ); + } + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/IssueManagementProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/IssueManagementProcessor.java new file mode 100644 index 0000000000..68296a6a1f --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/IssueManagementProcessor.java @@ -0,0 +1,54 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.Model; + +public class IssueManagementProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if ( c.getIssueManagement() != null ) + { + IssueManagement childMng = c.getIssueManagement(); + IssueManagement mng = new IssueManagement(); + + mng.setSystem( childMng.getSystem() ); + mng.setUrl( childMng.getUrl() ); + t.setIssueManagement( mng ); + } + else if ( p != null && p.getIssueManagement() != null ) + { + IssueManagement parentMng = p.getIssueManagement(); + IssueManagement mng = new IssueManagement(); + + mng.setSystem( parentMng.getSystem() ); + mng.setUrl( parentMng.getUrl() ); + t.setIssueManagement( mng ); + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/LicensesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/LicensesProcessor.java new file mode 100644 index 0000000000..76971ef65c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/LicensesProcessor.java @@ -0,0 +1,59 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.License; +import org.apache.maven.model.Model; + +public class LicensesProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if(c.getLicenses().isEmpty() && p != null) + { + for(License license : p.getLicenses()) + { + License l = new License(); + l.setUrl( license.getUrl()); + l.setDistribution( license.getDistribution() ); + l.setComments( license.getComments() ); + l.setName( license.getName() ); + t.addLicense( l ); + } + } + else if(isChildMostSpecialized ) + { + for(License license : c.getLicenses()) + { + License l = new License(); + l.setUrl( license.getUrl()); + l.setDistribution( license.getDistribution() ); + l.setComments( license.getComments() ); + l.setName( license.getName() ); + t.addLicense( l ); + } + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/MailingListProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/MailingListProcessor.java new file mode 100644 index 0000000000..d4ad2d4046 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/MailingListProcessor.java @@ -0,0 +1,64 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.MailingList; +import org.apache.maven.model.Model; + +public class MailingListProcessor + extends BaseProcessor +{ + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if ( !c.getMailingLists().isEmpty() ) + { + copyMailingLists( c.getMailingLists(), t ); + } + else if ( p != null && !p.getMailingLists().isEmpty() ) + { + copyMailingLists( p.getMailingLists(), t ); + } + } + + private static void copyMailingLists( List mailingLists, Model target ) + { + List targetList = target.getMailingLists(); + for ( MailingList mailingList : mailingLists ) + { + MailingList listCopy = new MailingList(); + listCopy.setArchive( mailingList.getArchive() ); + listCopy.setName( mailingList.getName() ); + listCopy.setOtherArchives( new ArrayList( mailingList.getOtherArchives() ) ); + listCopy.setPost( mailingList.getPost() ); + listCopy.setSubscribe( mailingList.getSubscribe() ); + listCopy.setUnsubscribe( mailingList.getUnsubscribe() ); + targetList.add( listCopy ); + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModelProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModelProcessor.java new file mode 100644 index 0000000000..9d75918b0c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModelProcessor.java @@ -0,0 +1,177 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Model; +import org.apache.maven.model.Processor; + +/* + * hold original pom + * Track where a property is from + */ +public class ModelProcessor + extends BaseProcessor +{ + + public ModelProcessor( Collection processors ) + { + super( processors ); + } + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model c = (Model) child; + Model t = (Model) target; + Model p = null; + if ( parent != null ) + { + p = (Model) parent; + } + + // Version + if ( c.getVersion() == null ) + { + if ( c.getParent() != null ) + { + t.setVersion( c.getParent().getVersion() ); + } + } + else + { + t.setVersion( c.getVersion() ); + } + + // GroupId + if ( c.getGroupId() == null ) + { + if ( c.getParent() != null ) + { + t.setGroupId( c.getParent().getGroupId() ); + } + } + else + { + t.setGroupId( c.getGroupId() ); + } + + // ArtifactId + if ( c.getArtifactId() == null ) + { + if ( c.getParent() != null ) + { + t.setArtifactId( c.getParent().getArtifactId() ); + } + } + else + { + t.setArtifactId( c.getArtifactId() ); + } + + t.setModelVersion( c.getModelVersion() ); + if(c.getPackaging() != null) + { + t.setPackaging( c.getPackaging() ); + } + else + { + t.setPackaging( "jar" ); + } + + if ( isChildMostSpecialized ) + { + t.setName( c.getName() ); + } + + if(c.getDescription() != null) + { + t.setDescription( c.getDescription() ); + } + else if(p != null && p.getDescription() != null) + { + t.setDescription(p.getDescription()); + } + + if ( c.getInceptionYear() != null ) + { + t.setInceptionYear( c.getInceptionYear() ); + } + else if ( p != null ) + { + t.setInceptionYear( p.getInceptionYear() ); + } + + if ( c.getUrl() != null ) + { + t.setUrl( c.getUrl() ); + } + else if(p != null && p.getUrl() != null) + { + t.setUrl( normalizeUriWithRelativePath(p.getUrl(), t.getArtifactId(), p) ); + } + else if (t.getUrl() != null) + { + t.setUrl( t.getUrl() + "/" + t.getArtifactId() ); + } + + //Dependencies + List deps = new ArrayList(); + DependenciesProcessor dependenciesProcessor = new DependenciesProcessor(); + dependenciesProcessor.process( (p != null) ? p.getDependencies() : null, c.getDependencies(), deps, isChildMostSpecialized ); + + if(deps.size() > 0) + { + t.setDependencies(deps); + // t.getDependencies().addAll( deps ); + } + + //Dependency Management + List mngDeps = new ArrayList(); + dependenciesProcessor.process( (p != null && p.getDependencyManagement() != null) ? p.getDependencyManagement().getDependencies(): null, + (c.getDependencyManagement() != null) ? c.getDependencyManagement().getDependencies(): null, mngDeps, isChildMostSpecialized ); + if(mngDeps.size() > 0) + { + if(t.getDependencyManagement() == null) + { + t.setDependencyManagement( new DependencyManagement() ); + } + t.getDependencyManagement().getDependencies().addAll( mngDeps ); + } + } + + private static List getParentNames(List models) + { + List names = new ArrayList(); + for(Model m : models) + { + names.add(m.getArtifactId()); + } + Collections.reverse(names); + return names; + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModuleProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModuleProcessor.java new file mode 100644 index 0000000000..61367c0d35 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ModuleProcessor.java @@ -0,0 +1,43 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; + +import org.apache.maven.model.Model; + +public class ModuleProcessor + extends BaseProcessor +{ + /** + * No parent + */ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + if ( isChildMostSpecialized ) + { + Model t = (Model) target; + Model c = (Model) child; + t.setModules( new ArrayList( c.getModules() ) ); + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/OrganizationProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/OrganizationProcessor.java new file mode 100644 index 0000000000..3bd7831325 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/OrganizationProcessor.java @@ -0,0 +1,54 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Model; +import org.apache.maven.model.Organization; + +public class OrganizationProcessor + extends BaseProcessor +{ + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + + if ( c.getOrganization() != null ) + { + copy( c.getOrganization(), t ); + } + else if ( p != null && p.getOrganization() != null ) + { + copy( p.getOrganization(), t ); + } + } + + private static void copy( Organization source, Model target ) + { + Organization o = new Organization(); + o.setName( source.getName() ); + o.setUrl( source.getUrl() ); + + target.setOrganization( o ); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ParentProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ParentProcessor.java new file mode 100644 index 0000000000..c3a003a127 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ParentProcessor.java @@ -0,0 +1,48 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Model; +import org.apache.maven.model.Parent; + +public class ParentProcessor + extends BaseProcessor +{ + + public ParentProcessor() + { + } + + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + if ( c.getParent() != null ) + { + Parent p = new Parent(); + p.setGroupId( c.getParent().getGroupId() ); + p.setArtifactId( c.getParent().getArtifactId() ); + p.setVersion( c.getParent().getVersion() ); + p.setRelativePath( c.getParent().getRelativePath() ); + t.setParent( p ); + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginProcessor.java new file mode 100644 index 0000000000..4d1de25fae --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginProcessor.java @@ -0,0 +1,359 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +public class PluginProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + List t = (List) target; + + if ( parent == null && child == null ) + { + return; + } + else if ( parent == null && child != null ) + { + + boolean isAdd = true; + Plugin targetPlugin = find((Plugin) child, t); + if(targetPlugin == null) + { + targetPlugin = new Plugin(); + } + else + { + isAdd = false; + } + + copy( (Plugin) child, targetPlugin, true ); + copyDependencies( new ArrayList(), + new ArrayList(( (Plugin) child).getDependencies() ), targetPlugin, true ); + if(isAdd) t.add( targetPlugin ); + } + else if ( parent != null && child == null ) + { + boolean isAdd = true; + Plugin targetPlugin = find((Plugin) parent, t); + if(targetPlugin == null) + { + targetPlugin = new Plugin(); + } + else + { + isAdd = false; + } + + copy( (Plugin) parent, targetPlugin, false ); + copyDependencies( new ArrayList(( (Plugin) parent).getDependencies() ), new ArrayList(), + targetPlugin, true ); + if(isAdd) t.add( targetPlugin ); + } + else + // JOIN + { + if( match( (Plugin) parent, (Plugin) child) ) + { + boolean isAdd = true; + Plugin targetPlugin = find((Plugin) parent, t); + if(targetPlugin == null) + { + targetPlugin = new Plugin(); + } + else + { + isAdd = false; + } + copy( (Plugin) parent, targetPlugin, false ); + copy( (Plugin) child, targetPlugin, true ); + copyDependencies( new ArrayList(( (Plugin) parent).getDependencies() ), + new ArrayList(( (Plugin) child).getDependencies() ), targetPlugin, true ); + if(isAdd) t.add( targetPlugin ); + } + else + { + Plugin targetPlugin = new Plugin(); + copy( (Plugin) parent, targetPlugin, false ); + copy( (Plugin) child, targetPlugin, true ); + + copyDependencies( new ArrayList(( (Plugin) parent).getDependencies() ), + new ArrayList(( (Plugin) child).getDependencies() ), targetPlugin, true ); + // copyDependencies( (Plugin) parent, targetPlugin, false ); + t.add( targetPlugin ); + } + } + } + + public void process( Plugin parent, List t, boolean isChildMostSpecialized ) + { + if (parent == null) { + return; + } + + boolean isAdd = true; + Plugin targetPlugin = find((Plugin) parent, t); + if (targetPlugin == null) { + targetPlugin = new Plugin(); + } else { + isAdd = false; + } + + copy2((Plugin) parent, targetPlugin, false); + copyDependencies(new ArrayList(((Plugin) parent) + .getDependencies()), new ArrayList(), targetPlugin, + true); + if (isAdd) + t.add(targetPlugin); + } + + private static Plugin find(Plugin p1, List plugins) + { + for(Plugin t : plugins) + { + if(match(p1, t)){ + return t; + } + } + + return null; + } + + private static boolean match( Plugin d1, Plugin d2 ) + { + return getId( d1 ).equals( getId( d2 )); + } + + private static String getId( Plugin d ) + { + StringBuilder sb = new StringBuilder(); + sb.append( (d.getGroupId() != null) ? d.getGroupId() : "org.apache.maven.plugins").append( ":" ).append( d.getArtifactId() ).append( ":" ); + return sb.toString(); + } + + + private static void copyDependencies(List parent, List child, Plugin target, boolean isChild) + { + if(parent.isEmpty() && child.isEmpty()) + { + return; + } + DependenciesProcessor proc = new DependenciesProcessor(); + proc.process( parent, child, target.getDependencies(), isChild ); + } + + /** + * Don't overwrite values + * + * @param source + * @param target + * @param isChild + */ + private static void copy2(Plugin source, Plugin target, boolean isChild) + { + if(!isChild && source.getInherited() != null && !source.getInherited().equalsIgnoreCase( "true" )) + { + return; + } + + if(target.getArtifactId() == null) + { + target.setArtifactId( source.getArtifactId() ); + } + + if(target.getGroupId() == null) + { + target.setGroupId( source.getGroupId() ); + } + + if(target.getInherited() == null) + { + target.setInherited( source.getInherited() ); + } + + if(target.getVersion() == null) + { + target.setVersion( source.getVersion() ); + } + + for( PluginExecution pe : source.getExecutions()) + { + PluginExecution idMatch = contains(pe, target.getExecutions()); + if(idMatch != null)//Join + { + copyPluginExecution(pe, idMatch, isChild); + } + else + { + PluginExecution targetPe = new PluginExecution(); + copyPluginExecution(pe, targetPe, isChild); + target.addExecution( targetPe ); + } + + } + + if(source.getConfiguration() != null) + { + //TODO: Not copying + if(target.getConfiguration() != null) + { + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) source.getConfiguration(), (Xpp3Dom) target.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + + } + + // p2.setConfiguration( configuration ) merge nodes + //Goals + target.setExtensions(source.isExtensions()); + + } + + private static void copy(Plugin source, Plugin target, boolean isChild) + { + if(!isChild && source.getInherited() != null && !source.getInherited().equalsIgnoreCase( "true" )) + { + return; + } + + if(source.getArtifactId() != null) + { + target.setArtifactId( source.getArtifactId() ); + } + + target.setGroupId( source.getGroupId() ); + + if(source.getInherited() != null) + { + target.setInherited( source.getInherited() ); + } + + if(source.getVersion() != null) + { + target.setVersion( source.getVersion() ); + } + + for( PluginExecution pe : source.getExecutions()) + { + PluginExecution idMatch = contains(pe, target.getExecutions()); + if(idMatch != null)//Join + { + copyPluginExecution(pe, idMatch, isChild); + } + else + { + PluginExecution targetPe = new PluginExecution(); + copyPluginExecution(pe, targetPe, isChild); + target.addExecution( targetPe ); + } + + } + + if(source.getConfiguration() != null) + { + //TODO: Not copying + if(target.getConfiguration() != null) + { + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) source.getConfiguration(), (Xpp3Dom) target.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + + } + + // p2.setConfiguration( configuration ) merge nodes + //Goals + target.setExtensions(source.isExtensions()); + + } + + private static PluginExecution contains(PluginExecution pe, List executions) + { + String executionId = (pe.getId() != null) ? pe.getId() : ""; + for(PluginExecution e : executions) + { + String id = (e.getId() != null) ? e.getId() : ""; + if(executionId.equals( id )) + { + return e; + } + } + return null; + } + + private static void copyPluginExecution(PluginExecution source, PluginExecution target, boolean isChild) + { + if(!isChild && source.getInherited() != null && !source.getInherited().equalsIgnoreCase( "true" )) + { + return; + } + target.setId( source.getId() ); + + if(isChild && source.getInherited() != null) + { + target.setInherited( source.getInherited() ); + } + + if(source.getPhase() != null) + { + target.setPhase( source.getPhase() ); + } + + List targetGoals = new ArrayList(target.getGoals()); + List setGoals = new ArrayList(); + for(String goal : source.getGoals()) + { + if(targetGoals.contains( goal )) + { + targetGoals.remove( goal ); + } + } + setGoals.addAll( source.getGoals() ); + setGoals.addAll( targetGoals ); + target.setGoals( setGoals ); + + if(source.getConfiguration() != null) + { + if(target.getConfiguration() != null) + { + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) source.getConfiguration(), (Xpp3Dom) target.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + } + + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsManagementProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsManagementProcessor.java new file mode 100644 index 0000000000..068d7f162c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsManagementProcessor.java @@ -0,0 +1,189 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * Used for applying plugin management to the pom (not for inheritance). + * + */ +public class PluginsManagementProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + List pluginManagement = (List ) child; + List targetPlugin = (List) target; + + for(Plugin depMng : pluginManagement) + { + for(Plugin targetDep : targetPlugin) + { //PluginManagement is first in ordering + if(match(depMng, targetDep) ) + { + copy(depMng, targetDep ); + } + } + } + } + + private static boolean match( Plugin d1, Plugin d2 ) + { + return getId( d1 ).equals( getId( d2 ) ) ; + } + + private static String getId( Plugin d ) + { + StringBuilder sb = new StringBuilder(); + sb.append( d.getGroupId() ).append( ":" ).append( d.getArtifactId() ); + return sb.toString(); + } + + private static void copy(Plugin source, Plugin target) + { + if(target.getArtifactId() == null) + { + target.setArtifactId( source.getArtifactId() ); + } + + target.setGroupId( source.getGroupId() ); + + if(target.getInherited() == null) + { + target.setInherited( source.getInherited() ); + } + + if(target.getVersion() == null) + { + target.setVersion( source.getVersion() ); + } + + List executions = new ArrayList(); + for( PluginExecution pe : source.getExecutions()) + { + PluginExecution idMatch = contains(pe, target.getExecutions()); + if(idMatch != null)//Join + { + copyPluginExecution(pe, idMatch); + target.getExecutions().remove( idMatch ); + executions.add( idMatch ); + } + else + { + PluginExecution targetPe = new PluginExecution(); + copyPluginExecution(pe, targetPe); + executions.add( targetPe ); + } + } + + executions.addAll( target.getExecutions() ); + target.setExecutions( executions ); + + DependenciesProcessor proc = new DependenciesProcessor(true); + if(target.getDependencies().isEmpty()) + { + + proc.process( new ArrayList(), new ArrayList(source.getDependencies()), target.getDependencies(), false ); + } + else + { + proc.process( new ArrayList(source.getDependencies()), new ArrayList(), target.getDependencies(), false ); + } + + if(source.getConfiguration() != null) + { + //TODO: Not copying + if(target.getConfiguration() != null) + { + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) target.getConfiguration(), (Xpp3Dom) source.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + } + + target.setExtensions(source.isExtensions()); + + } + + private static PluginExecution contains(PluginExecution pe, List executions) + { + String executionId = (pe.getId() != null) ? pe.getId() : ""; + for(PluginExecution e : executions) + { + String id = (e.getId() != null) ? e.getId() : ""; + if(executionId.equals( id )) + { + return e; + } + } + return null; + } + + private static void copyPluginExecution(PluginExecution source, PluginExecution target) + { + if(target.getId() != null) + { + target.setId( source.getId() ); + } + + if ( target.getInherited() == null ) + { + target.setInherited( source.getInherited() ); + } + + if ( target.getPhase() == null ) + { + target.setPhase( source.getPhase() ); + } + + List goals = new ArrayList(target.getGoals()); + for(String goal : source.getGoals()) + { + if(!goals.contains( goal )) + { + goals.add( goal ); + } + + } + target.setGoals( goals ); + if(source.getConfiguration() != null) + { + if(target.getConfiguration() != null) + { + //Target is dominant + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) target.getConfiguration(), (Xpp3Dom) source.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsProcessor.java new file mode 100644 index 0000000000..5ce51f468c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PluginsProcessor.java @@ -0,0 +1,107 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Plugin; + +public class PluginsProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + List c = (child != null) ? (List) child : new ArrayList() ; + List p = null; + + if ( parent != null ) + { + p = (List) parent; + } + + List plugins = (List) target; + + PluginProcessor processor = new PluginProcessor(); + + if ( ( p == null || p.isEmpty() ) && !c.isEmpty() ) + { + for ( Plugin plugin : c ) + { + processor.process( null, plugin, plugins, isChildMostSpecialized ); + } + } + else + { + if ( !c.isEmpty() ) + { + List parentDependencies = new ArrayList(); + for ( Plugin childPlugin : c) + { + for ( Plugin parentPlugin : p) + { + if ( match( childPlugin, parentPlugin ) ) + { + processor.process( parentPlugin, childPlugin, plugins, isChildMostSpecialized );// JOIN + } + else + { + processor.process( null, childPlugin, plugins, isChildMostSpecialized ); + if(!parentDependencies.contains(parentPlugin)) + { + parentDependencies.add( parentPlugin ); + } + } + } + } + + /** + * Process Parents after child to keep plugin order but don't want to overwrite the child values. Use different method + */ + for ( Plugin d2 : parentDependencies ) + { + processor.process( d2, plugins, isChildMostSpecialized ); + } + + } + else if( p != null) + { + for ( Plugin d2 : p ) + { + processor.process( d2, null, plugins, isChildMostSpecialized ); + } + } + } + + } + + private static boolean match( Plugin d1, Plugin d2 ) + { + return getId( d1 ).equals( getId( d2 )); + } + + private static String getId( Plugin d ) + { + StringBuilder sb = new StringBuilder(); + sb.append( (d.getGroupId() != null) ? d.getGroupId() : "org.apache.maven.plugins").append( ":" ).append( d.getArtifactId() ).append( ":" ); + return sb.toString(); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/PrerequisitesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PrerequisitesProcessor.java new file mode 100644 index 0000000000..c48698319c --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PrerequisitesProcessor.java @@ -0,0 +1,45 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Model; +import org.apache.maven.model.Prerequisites; + +public class PrerequisitesProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + if ( isChildMostSpecialized ) + { + Model t = (Model) target; + Model c = (Model) child; + if ( c.getPrerequisites() == null ) + { + return; + } + Prerequisites prerequisites = new Prerequisites(); + prerequisites.setMaven( c.getPrerequisites().getMaven() ); + t.setPrerequisites( prerequisites ); + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilePropertiesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilePropertiesProcessor.java new file mode 100644 index 0000000000..2f6b8ec0d8 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilePropertiesProcessor.java @@ -0,0 +1,58 @@ +package org.apache.maven.model.processors; + +import java.util.Properties; + +import org.apache.maven.model.Model; + +public class ProfilePropertiesProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target, c = (Model) child, p = (Model) parent; + + Properties properties = new Properties(); + + if ( c.getProperties() != null ) + { + properties.putAll( c.getProperties() ); + } + + if ( p != null && p.getProperties() != null ) + { + properties.putAll( p.getProperties() ); + } + + if ( !properties.isEmpty() ) + { + if(t.getProperties().isEmpty()) + { + t.setProperties( properties ); + } + else + { + add(properties, t.getProperties()); + //t.getProperties().putAll( properties ); + } + } + } + + /** + * Add source properties to target if the property does not exist: parent over child + * + * @param source + * @param target + */ + private static void add(Properties source, Properties target) + { + for(Object key : source.keySet()) + { + if(!target.containsKey(key)) + { + target.put(key, source.get(key)); + } + } + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesModuleProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesModuleProcessor.java new file mode 100644 index 0000000000..9118650301 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesModuleProcessor.java @@ -0,0 +1,57 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Model; + +public class ProfilesModuleProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + List modules = new ArrayList(); + + for ( String module : c.getModules() ) + { + if(!modules.contains( module )) + { + modules.add(module); + } + } + if(p != null) + { + for ( String module : p.getModules() ) + { + if(!modules.contains( module )) + { + modules.add(module); + } + } + } + t.setModules( modules ); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesProcessor.java new file mode 100644 index 0000000000..2a201df767 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ProfilesProcessor.java @@ -0,0 +1,45 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Model; +import org.apache.maven.model.ProcessorContext; +import org.apache.maven.model.Profile; + + +public class ProfilesProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + List profiles = ((Model) child).getProfiles(); + List copies = new ArrayList(); + for(Profile p : profiles) + { + copies.add( ProcessorContext.copyOfProfile(p) ); + } + t.setProfiles( copies ); + //TODO - copy + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/PropertiesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PropertiesProcessor.java new file mode 100644 index 0000000000..ded083e926 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/PropertiesProcessor.java @@ -0,0 +1,58 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Properties; + +import org.apache.maven.model.Model; + +public class PropertiesProcessor + extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target, c = (Model) child, p = (Model) parent; + + Properties properties = new Properties(); + + if ( p != null && p.getProperties() != null ) + { + properties.putAll( p.getProperties() ); + } + + if ( c.getProperties() != null ) + { + properties.putAll( c.getProperties() ); + } + + if ( !properties.isEmpty() ) + { + if(t.getProperties().isEmpty()) + { + t.setProperties( properties ); + } + else + { + t.getProperties().putAll( properties ); + } + } + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ReportingProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ReportingProcessor.java new file mode 100644 index 0000000000..4cb11c3204 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ReportingProcessor.java @@ -0,0 +1,163 @@ +package org.apache.maven.model.processors; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.ReportSet; +import org.apache.maven.model.Reporting; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +public class ReportingProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model t = (Model) target, c = (Model) child, p = (Model) parent; + if(p != null && p.getReporting() != null) + { + if(t.getReporting() == null) + { + t.setReporting( new Reporting() ); + } + + copy(p.getReporting(), t.getReporting()); + } + + if(c.getReporting() != null) + { + if(t.getReporting() == null) + { + t.setReporting( new Reporting() ); + } + + copy(c.getReporting(), t.getReporting()); + } + } + + private static void copy(Reporting source, Reporting target) + { + if(source.getOutputDirectory() != null) + { + target.setOutputDirectory( source.getOutputDirectory() ); + + } + + target.setExcludeDefaults( source.isExcludeDefaults() ); + + for ( ReportPlugin plugin : source.getPlugins() ) + { + ReportPlugin match = contains(plugin, target.getPlugins()); + if(match == null) + { + target.addPlugin( copyNewPlugin( plugin ) ); + } + else + { + copyPluginToPlugin(plugin, match); + } + + } + } + + private static ReportPlugin contains(ReportPlugin plugin, List list) + { + for(ReportPlugin p :list) + { + if(match(p, plugin)) + { + return p; + } + } + return null; + } + + private static void copyPluginToPlugin(ReportPlugin source, ReportPlugin target) + { + if(source.getInherited() != null) + { + target.setInherited( source.getInherited() ); + } + + if(source.getVersion() != null) + { + target.setVersion( source.getVersion() ); + } + + if(source.getConfiguration() != null) + { + if(target.getConfiguration() != null) + { + target.setConfiguration( Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) source.getConfiguration(), (Xpp3Dom) target.getConfiguration() )); + } + else + { + target.setConfiguration( source.getConfiguration() ); + } + } + + for(ReportSet rs : source.getReportSets()) + { + ReportSet r = new ReportSet(); + r.setId( rs.getId() ); + r.setInherited( rs.getInherited() ); + r.setReports( new ArrayList(rs.getReports()) ); + r.setConfiguration( rs.getConfiguration() ); + target.addReportSet( r ); + } + } + + private static ReportPlugin copyNewPlugin(ReportPlugin plugin) + { + ReportPlugin rp = new ReportPlugin(); + rp.setArtifactId( plugin.getArtifactId() ); + rp.setGroupId( plugin.getGroupId() ); + rp.setInherited( plugin.getInherited() ); + rp.setVersion( plugin.getVersion() ); + rp.setConfiguration( plugin.getConfiguration() ); + + for(ReportSet rs : plugin.getReportSets()) + { + ReportSet r = new ReportSet(); + r.setId( rs.getId() ); + r.setInherited( rs.getInherited() ); + r.setReports( new ArrayList(rs.getReports()) ); + r.setConfiguration( rs.getConfiguration() ); + rp.addReportSet( r ); + } + return rp; + } + + private static boolean match( ReportPlugin d1, ReportPlugin d2 ) + { + return getId( d1 ).equals( getId( d2 )); + } + + private static String getId( ReportPlugin d ) + { + StringBuilder sb = new StringBuilder(); + sb.append( d.getGroupId() ).append( ":" ).append( d.getArtifactId() ).append( ":" ); + return sb.toString(); + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/RepositoriesProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/RepositoriesProcessor.java new file mode 100644 index 0000000000..dead8c00f3 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/RepositoriesProcessor.java @@ -0,0 +1,98 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.model.Model; +import org.apache.maven.model.Repository; +import org.apache.maven.model.RepositoryPolicy; + +public class RepositoriesProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + + Model t = (Model) target, c = (Model) child, p = (Model) parent; + if(p != null) + { + copy( p.getRepositories(), t.getRepositories() ); + copy( p.getPluginRepositories(), t.getPluginRepositories() ); + } + copy(c.getPluginRepositories(), t.getPluginRepositories()); + copy( c.getRepositories(), t.getRepositories() ); + } + + private static void copy(List sources, List targets) + { + for(Repository repository : sources) + { + Repository match = matches(repository, targets); + Repository r = null; + if(match != null) + { + r = match; + } + else + { + r = new Repository(); + } + + r.setId( repository.getId() ); + r.setLayout( repository.getLayout() ); + r.setName( repository.getName() ); + r.setUrl( repository.getUrl() ); + if(repository.getReleases() != null) + { + r.setReleases( copy(repository.getReleases()) ); + } + if(repository.getSnapshots() != null) + { + r.setSnapshots( copy(repository.getSnapshots()) ); + } + if (match == null) + { + targets.add( r ); + } + } + } + + private static Repository matches(Repository repository, List targets) + { + for(Repository r : targets) + { + if(r.getId() != null && r.getId().equals(repository.getId())) + { + return r; + } + } + return null; + } + + private static RepositoryPolicy copy(RepositoryPolicy policy) + { + RepositoryPolicy p = new RepositoryPolicy(); + p.setChecksumPolicy( policy.getChecksumPolicy() ); + p.setEnabledValue(policy.getEnabledValue()); + p.setUpdatePolicy( policy.getUpdatePolicy() ); + return p; + } +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/processors/ScmProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ScmProcessor.java new file mode 100644 index 0000000000..d5659de70d --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/processors/ScmProcessor.java @@ -0,0 +1,107 @@ +package org.apache.maven.model.processors; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.model.Model; +import org.apache.maven.model.Scm; + +public class ScmProcessor extends BaseProcessor +{ + public void process( Object parent, Object child, Object target, boolean isChildMostSpecialized ) + { + super.process( parent, child, target, isChildMostSpecialized ); + Model t = (Model) target; + Model c = (Model) child; + Model p = (Model) parent; + if((p == null || p.getScm() == null) && (c == null || c.getScm() == null)) + { + //return; + } + Scm targetScm = (t.getScm() == null) ? new Scm() : t.getScm(); + + copyUrl( ((p != null) ? p.getScm() : null), c.getScm(), targetScm, c.getArtifactId(), p); + copyConnection( ((p != null) ? p.getScm() : null), c.getScm(), targetScm, c.getArtifactId(), p); + copyDeveloperConnection( ((p != null) ? p.getScm() : null), c.getScm(), targetScm, c.getArtifactId(), p); + copyTag( ( ( p != null ) ? p.getScm() : null ), c.getScm(), targetScm ); + + if(t.getScm() ==null && (targetScm.getConnection() !=null || targetScm.getDeveloperConnection() != null || targetScm.getUrl() != null)) + { + t.setScm(targetScm); + } + } + + private void copyUrl(Scm p, Scm c, Scm t, String artifactId, Model parent ) + { + if(c != null && c.getUrl() != null) + { + t.setUrl( c.getUrl() ); + } + else if(p != null && p.getUrl() != null) + { + t.setUrl( normalizeUriWithRelativePath(p.getUrl(), artifactId, parent)); + } + else if(t.getUrl() != null) { + t.setUrl( t.getUrl() + "/" + artifactId ); + } + } + + private void copyConnection(Scm p, Scm c, Scm t, String artifactId, Model parent ) + { + if(c!= null && c.getConnection() != null) + { + t.setConnection( c.getConnection() ); + } + else if(p != null && p.getConnection() != null) + { + t.setConnection( normalizeUriWithRelativePath(p.getConnection(), artifactId, parent)); + } + else if(t.getConnection() != null) { + t.setConnection( t.getConnection() + "/" + artifactId ); + } + } + + private void copyDeveloperConnection(Scm p, Scm c, Scm t, String artifactId, Model parent ) + { + if(c!= null && c.getDeveloperConnection() != null) + { + t.setDeveloperConnection( c.getDeveloperConnection() ); + } + else if(p != null && p.getDeveloperConnection() != null) + { + t.setDeveloperConnection( normalizeUriWithRelativePath(p.getDeveloperConnection(), artifactId, parent) ); + } + else if(t.getDeveloperConnection() != null){ + t.setDeveloperConnection( t.getDeveloperConnection() + "/" + artifactId ); + } + } + + private static void copyTag( Scm p, Scm c, Scm t ) + { + if ( c != null && c.getTag() != null ) + { + t.setTag( c.getTag() ); + } + else if ( p != null && p.getTag() != null ) + { + t.setTag( p.getTag() ); + } + } + +} diff --git a/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java similarity index 50% rename from maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java index c89ba601c4..3e72552e34 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java @@ -22,47 +22,45 @@ package org.apache.maven.profiles; import org.apache.maven.model.Activation; import org.apache.maven.model.Model; import org.apache.maven.model.Profile; -import org.apache.maven.model.Parent; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.apache.maven.model.interpolator.InterpolatorProperty; +import org.apache.maven.model.interpolator.PomInterpolatorTag; import org.apache.maven.profiles.ProfileActivationContext; import org.apache.maven.profiles.ProfileActivationException; import org.apache.maven.profiles.ProfileManager; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelMarshaller; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.project.builder.factories.IdModelContainerFactory; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.PomInterpolatorTag; -import org.apache.maven.project.builder.profile.*; -import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.MutablePlexusContainer; -import org.codehaus.plexus.util.xml.pull.XmlSerializer; -import org.codehaus.plexus.util.xml.pull.MXSerializer; - -import java.util.*; -import java.util.Map.Entry; -import java.io.*; -import java.lang.reflect.Method; +import org.apache.maven.profiles.matchers.DefaultMatcher; +import org.apache.maven.profiles.matchers.FileMatcher; +import org.apache.maven.profiles.matchers.JdkMatcher; +import org.apache.maven.profiles.matchers.ProfileMatcher; +import org.apache.maven.profiles.matchers.PropertyMatcher; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; public class DefaultProfileManager implements ProfileManager { - private MutablePlexusContainer container; private Map profilesById = new LinkedHashMap(); private ProfileActivationContext profileActivationContext; + + private static final ProfileMatcher defaultMatcher = new DefaultMatcher(); + + private static final List matchers = + Collections.unmodifiableList( Arrays.asList( new PropertyMatcher(), new FileMatcher(), new JdkMatcher() ) ); /** * the properties passed to the profile manager are the props that * are passed to maven, possibly containing profile activator properties */ - public DefaultProfileManager( PlexusContainer container, ProfileActivationContext profileActivationContext ) + public DefaultProfileManager( ProfileActivationContext profileActivationContext ) { - this.container = (MutablePlexusContainer) container; if ( profileActivationContext == null ) { this.profileActivationContext = createDefaultActivationContext(); @@ -73,17 +71,6 @@ public class DefaultProfileManager } } - // TODO: Remove this, if possible. It uses system properties, which are not safe for IDE and other embedded environments. - /** - * @deprecated Using this is dangerous when extensions or non-global system properties are in play. - */ - public DefaultProfileManager( PlexusContainer container ) - { - this.container = (MutablePlexusContainer) container; - - profileActivationContext = createDefaultActivationContext(); - } - private ProfileActivationContext createDefaultActivationContext() { @@ -112,10 +99,10 @@ public class DefaultProfileManager { String profileId = profile.getId(); - Profile existing = (Profile) profilesById.get( profileId ); + Profile existing = profilesById.get( profileId ); if ( existing != null ) { - container.getLogger().warn( "Overriding profile: \'" + profileId + "\' (source: " + existing.getSource() + + System.out.println( "Overriding profile: \'" + profileId + "\' (source: " + existing.getSource() + ") with new instance from source: " + profile.getSource() ); } @@ -129,31 +116,22 @@ public class DefaultProfileManager } } - // TODO: Portions of this logic are duplicated in o.a.m.p.b.p.ProfileContext, something is wrong here + public List getActiveProfiles() throws ProfileActivationException { + return getActiveProfiles(null); + } + public List getActiveProfiles( Model model ) throws ProfileActivationException { List activeFromPom = new ArrayList(); List activeExternal = new ArrayList(); - - for ( Iterator it = profilesById.entrySet().iterator(); it.hasNext(); ) + for ( Map.Entry entry : profilesById.entrySet() ) { - Map.Entry entry = (Entry) it.next(); + String profileId = entry.getKey(); + Profile profile = entry.getValue(); - String profileId = (String) entry.getKey(); - Profile profile = (Profile) entry.getValue(); - - boolean shouldAdd = false; - if ( profileActivationContext.isExplicitlyActive( profileId ) ) - { - shouldAdd = true; - } - else if ( isActive( profile, profileActivationContext ) ) - { - shouldAdd = true; - } - - if ( !profileActivationContext.isExplicitlyInactive( profileId ) && shouldAdd ) + if ( !profileActivationContext.isExplicitlyInactive( profileId ) + && (profileActivationContext.isExplicitlyActive( profileId ) || isActive( profile, profileActivationContext ) ) ) { if ( "pom".equals( profile.getSource() ) ) { @@ -180,7 +158,7 @@ public class DefaultProfileManager { continue; } - Profile profile = (Profile) profilesById.get( profileId ); + Profile profile = profilesById.get( profileId ); if ( profile != null ) { @@ -190,75 +168,120 @@ public class DefaultProfileManager } List allActive = new ArrayList( activeFromPom.size() + activeExternal.size() ); - + // System.out.println("Active From POM: " + activeFromPom.size() + ": EXTERNAL:" + activeExternal.size()); allActive.addAll( activeExternal ); allActive.addAll( activeFromPom ); - + + List defaults = getDefaultProfiles(allActive); + if(defaults.size() < allActive.size()) + { + allActive.removeAll( defaults ); + } return allActive; } + + public static List getActiveProfilesFrom(ProfileManager globalProfileManager, Properties properties, Model model) + throws ProfileActivationException + { + List projectProfiles = new ArrayList(); + + ProfileActivationContext profileActivationContext = (globalProfileManager == null) ? new ProfileActivationContext( new Properties(), false ): + globalProfileManager.getProfileActivationContext(); + profileActivationContext.getExecutionProperties().putAll(properties); + + if(globalProfileManager != null) + { + projectProfiles.addAll( globalProfileManager.getActiveProfiles() ); + } - private static List matchers = Arrays.asList(new FileMatcher(), - new JdkMatcher(), new OperatingSystemMatcher(), new PropertyMatcher()); + ProfileManager profileManager = new DefaultProfileManager( profileActivationContext ); + profileManager.addProfiles( model.getProfiles() ); + projectProfiles.addAll( profileManager.getActiveProfiles() ); + return projectProfiles; + } + + public static Collection getActiveProfiles(List profiles, ProfileManagerInfo profileContextInfo) + { + List properties = profileContextInfo.getInterpolatorProperties(); + Collection activeProfileIds = profileContextInfo.getActiveProfileIds(); + Collection inactiveProfileIds = profileContextInfo.getInactiveProfileIds(); + + List matchedProfiles = new ArrayList(); + List defaultProfiles = new ArrayList(); + for ( Profile profile : profiles ) + { + String profileId = profile.getId(); + + if ( !inactiveProfileIds.contains( profileId ) ) + { + if ( activeProfileIds.contains( profileId ) ) + { + matchedProfiles.add( profile ); + } + else if ( defaultMatcher.isMatch( profile, properties ) ) + { + defaultProfiles.add( profile ); + } + else + { + for ( ProfileMatcher matcher : matchers ) + { + if ( matcher.isMatch( profile, properties ) ) + { + matchedProfiles.add( profile ); + break; + } + } + } + } + } + + if ( matchedProfiles.isEmpty() ) + { + matchedProfiles = defaultProfiles; + } + + return matchedProfiles; + } + + /* (non-Javadoc) + * @see org.apache.maven.project.ProfileManager#addProfiles(java.util.List) + */ + public void addProfiles( List profiles ) + { + for ( Profile profile : profiles ) + { + addProfile( profile ); + } + } + + private static List getDefaultProfiles(List profiles) + { + List defaults = new ArrayList(); + for(Profile p : profiles) + { + if ( p.getActivation() != null && p.getActivation().isActiveByDefault() ) + { + defaults.add( p ); + } + } + return defaults; + } private boolean isActive( Profile profile, ProfileActivationContext context ) throws ProfileActivationException { - //TODO: Using reflection now. Need to replace with custom mapper - StringWriter writer = new StringWriter(); - XmlSerializer serializer = new MXSerializer(); - serializer.setProperty( "http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " " ); - serializer.setProperty( "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n" ); - try - { - serializer.setOutput( writer ); - serializer.startDocument("UTF-8", null ); - } catch (IOException e) { - - } - - try { - MavenXpp3Writer w = new MavenXpp3Writer(); - Class c = Class.forName("org.apache.maven.model.io.xpp3.MavenXpp3Writer"); - - Class partypes[] = new Class[3]; - partypes[0] = Profile.class; - partypes[1] = String.class; - partypes[2] = XmlSerializer.class; - - Method meth = c.getDeclaredMethod( - "writeProfile", partypes); - meth.setAccessible(true); - - Object arglist[] = new Object[3]; - arglist[0] = profile; - arglist[1] = "profile"; - arglist[2] = serializer; - - meth.invoke(w, arglist); - serializer.endDocument(); - } catch (Exception e) - { - throw new ProfileActivationException(e.getMessage(), e); - } - List interpolatorProperties = new ArrayList(); - interpolatorProperties.addAll(InterpolatorProperty.toInterpolatorProperties( - context.getExecutionProperties(), - PomInterpolatorTag.EXECUTION_PROPERTIES.name())); - - List p; - try - { - p = ModelMarshaller.marshallXmlToModelProperties(new ByteArrayInputStream(writer.getBuffer().toString().getBytes()), - ProjectUri.Profiles.xUri, PomTransformer.URIS); - } catch (IOException e) { - throw new ProfileActivationException(e.getMessage()); - } - - ModelContainer mc = new IdModelContainerFactory(ProjectUri.Profiles.Profile.xUri).create(p); - for(ActiveProfileMatcher matcher : matchers) + if(context.getExecutionProperties() != null) { - if(matcher.isMatch(mc, interpolatorProperties)) + interpolatorProperties.addAll(InterpolatorProperty.toInterpolatorProperties( + context.getExecutionProperties(), + PomInterpolatorTag.EXECUTION_PROPERTIES.name())); + } + + for(ProfileMatcher matcher : matchers) + { + if(matcher.isMatch(profile, interpolatorProperties)) { return true; } @@ -266,40 +289,13 @@ public class DefaultProfileManager return false; } - /* (non-Javadoc) - * @see org.apache.maven.project.ProfileManager#addProfiles(java.util.List) - */ - public void addProfiles( List profiles ) - { - for ( Iterator it = profiles.iterator(); it.hasNext(); ) - { - Profile profile = (Profile) it.next(); - - addProfile( profile ); - } - } - private void activateAsDefault( String profileId ) { - List defaultIds = profileActivationContext.getActiveByDefaultProfileIds(); + List defaultIds = profileActivationContext.getActiveByDefaultProfileIds(); if ( !defaultIds.contains( profileId ) ) { profileActivationContext.setActiveByDefault( profileId ); } } - - - public static String getGroupId( Model model ) - { - Parent parent = model.getParent(); - - String groupId = model.getGroupId(); - if ( ( parent != null ) && ( groupId == null ) ) - { - groupId = parent.getGroupId(); - } - - return groupId; - } } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java similarity index 97% rename from maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java index e6824784b1..15336f155b 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileActivationContext.java @@ -27,7 +27,6 @@ import java.util.Properties; public class ProfileActivationContext { - private boolean isCustomActivatorFailureSuppressed; private final Properties executionProperties; @@ -40,7 +39,7 @@ public class ProfileActivationContext public ProfileActivationContext( Properties executionProperties, boolean isCustomActivatorFailureSuppressed ) { - this.executionProperties = executionProperties; + this.executionProperties = (executionProperties != null) ? executionProperties : new Properties(); this.isCustomActivatorFailureSuppressed = isCustomActivatorFailureSuppressed; } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationException.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileActivationException.java similarity index 100% rename from maven-project/src/main/java/org/apache/maven/profiles/ProfileActivationException.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileActivationException.java diff --git a/maven-project/src/main/java/org/apache/maven/profiles/ProfileManager.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManager.java similarity index 93% rename from maven-project/src/main/java/org/apache/maven/profiles/ProfileManager.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManager.java index da7f0a7c7f..de5d42a0ba 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/ProfileManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManager.java @@ -35,6 +35,10 @@ public interface ProfileManager Map getProfilesById(); + @Deprecated List getActiveProfiles( Model model ) throws ProfileActivationException; + + List getActiveProfiles( ) + throws ProfileActivationException; } \ No newline at end of file diff --git a/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManagerInfo.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManagerInfo.java new file mode 100644 index 0000000000..9f8fefc8c1 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/ProfileManagerInfo.java @@ -0,0 +1,35 @@ +package org.apache.maven.profiles; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.maven.model.interpolator.InterpolatorProperty; + +public class ProfileManagerInfo +{ + private List interpolatorProperties; + + private Collection activeProfileIds; + + private Collection inactiveProfileIds; + + public ProfileManagerInfo(List interpolatorProperties, Collection activeProfileIds, Collection inactiveProfileIds) + { + this.interpolatorProperties = (interpolatorProperties != null) ? interpolatorProperties : new ArrayList(); + this.activeProfileIds = (activeProfileIds != null) ? activeProfileIds : new ArrayList(); + this.inactiveProfileIds = (inactiveProfileIds != null) ? inactiveProfileIds : new ArrayList(); + } + + public List getInterpolatorProperties() { + return interpolatorProperties; + } + + public Collection getActiveProfileIds() { + return activeProfileIds; + } + + public Collection getInactiveProfileIds() { + return inactiveProfileIds; + } +} diff --git a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModelFactory.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/DefaultMatcher.java similarity index 65% rename from maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModelFactory.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/DefaultMatcher.java index 11af600c13..5c979ed93a 100644 --- a/maven-mercury/src/main/java/org/apache/maven/mercury/MavenDomainModelFactory.java +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/DefaultMatcher.java @@ -1,4 +1,4 @@ -package org.apache.maven.mercury; +package org.apache.maven.profiles.matchers; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,20 +19,20 @@ package org.apache.maven.mercury; * under the License. */ -import java.io.IOException; import java.util.List; -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.DomainModelFactory; -import org.apache.maven.shared.model.ModelProperty; +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; -public class MavenDomainModelFactory - implements DomainModelFactory +public class DefaultMatcher implements ProfileMatcher { - - public DomainModel createDomainModel( List modelProperties ) - throws IOException + public boolean isMatch( Profile profile, List properties ) { - return new MavenDomainModel( modelProperties ); + if(profile.getActivation() == null) + { + return false; + } + return profile.getActivation().isActiveByDefault(); } + } diff --git a/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/FileMatcher.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/FileMatcher.java new file mode 100644 index 0000000000..7136d6bada --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/FileMatcher.java @@ -0,0 +1,34 @@ +package org.apache.maven.profiles.matchers; + +import java.io.File; +import java.util.List; + +import org.apache.maven.model.ActivationFile; +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; + +public class FileMatcher implements ProfileMatcher { + + public boolean isMatch(Profile profile, List properties) { + if (profile == null) { + throw new IllegalArgumentException("profile: null"); + } + + if(profile.getActivation() == null || profile.getActivation().getFile() == null) + { + return false; + } + + ActivationFile f = profile.getActivation().getFile(); + + if (f.getExists() != null && !new File(f.getExists()).exists()) { + return false; + } + + if (f.getMissing() != null && new File(f.getMissing()).exists()) { + return false; + } + + return true; + } +} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java similarity index 58% rename from maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java rename to maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java index d2d9c6b4c6..80e817fc28 100644 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/JdkMatcher.java +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/JdkMatcher.java @@ -1,60 +1,56 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; +package org.apache.maven.profiles.matchers; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class JdkMatcher - implements ActiveProfileMatcher -{ - public boolean isMatch( ModelContainer modelContainer, List properties ) - { - if ( modelContainer == null ) - { - throw new IllegalArgumentException( "modelContainer: null" ); - } +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; - if ( properties == null ) +public class JdkMatcher + implements ProfileMatcher + { + + private static final String JDK_VERSION = "${java.version}"; + + public boolean isMatch(Profile profile, + List properties) { + String version = null; + for(InterpolatorProperty ip : properties) + { + if(ip.getKey().equals(JDK_VERSION)) + { + version = ip.getValue(); + break; + } + } + if ( version == null ) { return false; } - - for ( InterpolatorProperty property : properties ) + + org.apache.maven.model.Activation activation = profile.getActivation(); + if(activation == null || activation.getJdk() == null) { - if ( property.getKey().equals( "${java.specification.version}" ) ) - { - String version = property.getValue(); - for ( ModelProperty modelProperty : modelContainer.getProperties() ) - { - - if ( modelProperty.getUri().equals( ProjectUri.Profiles.Profile.Activation.jdk ) ) - { - if ( modelProperty.getResolvedValue().startsWith( "!" ) ) - { - return !version.equals( modelProperty.getResolvedValue().replaceFirst( "!", "" ) ); - } - else if ( isRange( modelProperty.getResolvedValue() ) ) - { - return isInRange( version, getRange( modelProperty.getResolvedValue() ) ); - } - else - { - return version.equals( modelProperty.getResolvedValue() ); - } - - } - } - return false; - } + return false; + } + + String jdk = activation.getJdk(); + if ( jdk.startsWith( "!" ) ) + { + return !version.startsWith( jdk.replaceFirst( "!", "" ) ); + } + else if ( isRange( jdk ) ) + { + return isInRange( version, getRange( jdk ) ); + } + else + { + return version.startsWith( jdk ); } - return false; - } + } + private static boolean isInRange( String value, List range ) { int leftRelation = getRelationOrder( value, range.get( 0 ), true ); @@ -74,8 +70,13 @@ public class JdkMatcher private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft ) { - List valueTokens = Arrays.asList( value.split( "." ) ); - List rangeValueTokens = Arrays.asList( rangeValue.value.split( "." ) ); + if ( rangeValue.value.length() <= 0 ) + { + return isLeft ? 1 : -1; + } + + List valueTokens = new ArrayList( Arrays.asList( value.split( "\\." ) ) ); + List rangeValueTokens = new ArrayList( Arrays.asList( rangeValue.value.split( "\\." ) ) ); int max = Math.max( valueTokens.size(), rangeValueTokens.size() ); addZeroTokens( valueTokens, max ); @@ -83,13 +84,17 @@ public class JdkMatcher if ( value.equals( rangeValue.value ) ) { - return ( rangeValue.isClosed() ) ? 0 : -1; + if ( !rangeValue.isClosed() ) + { + return isLeft ? -1 : 1; + } + return 0; } for ( int i = 0; i < valueTokens.size(); i++ ) { - int x = Integer.getInteger( valueTokens.get( i ) ); - int y = Integer.getInteger( rangeValueTokens.get( i ) ); + int x = Integer.parseInt( valueTokens.get( i ) ); + int y = Integer.parseInt( rangeValueTokens.get( i ) ); if ( x < y ) { return -1; @@ -99,6 +104,10 @@ public class JdkMatcher return 1; } } + if ( !rangeValue.isClosed() ) + { + return isLeft ? -1 : 1; + } return 0; } @@ -140,7 +149,10 @@ public class JdkMatcher { ranges.add( new RangeValue( token.replace( ")", "" ), false ) ); } - + else if ( token.length() <= 0 ) + { + ranges.add( new RangeValue( "", false ) ); + } } if ( ranges.size() < 2 ) { @@ -170,5 +182,10 @@ public class JdkMatcher { return isClosed; } - } + + public String toString() + { + return value; + } + } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/ProfileMatcher.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/ProfileMatcher.java new file mode 100644 index 0000000000..a0a7f56c93 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/ProfileMatcher.java @@ -0,0 +1,30 @@ +package org.apache.maven.profiles.matchers; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; + +public interface ProfileMatcher +{ + boolean isMatch( Profile profile, List properties ); +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/PropertyMatcher.java b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/PropertyMatcher.java new file mode 100644 index 0000000000..4daa9fb916 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/profiles/matchers/PropertyMatcher.java @@ -0,0 +1,60 @@ +package org.apache.maven.profiles.matchers; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.List; + +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; + +public class PropertyMatcher implements ProfileMatcher +{ + public boolean isMatch( Profile profile, List properties ) + { + if (profile == null) { + throw new IllegalArgumentException("profile: null"); + } + + if(profile.getActivation() == null || profile.getActivation().getProperty() == null) + { + return false; + } + String value = profile.getActivation().getProperty().getValue(); + String name = profile.getActivation().getProperty().getName(); + + if(name == null ) + { + return false; + } + + if(value == null) + { + return !name.startsWith("!"); + } + + for(InterpolatorProperty ip : properties) { + if(ip.getKey().equals("${" + name + "}")) { + return ip.getValue().equals(value); + } + } + + return false; + } +} diff --git a/maven-project/src/main/mdo/profiles.mdo b/maven-model-builder/src/main/mdo/profiles.mdo similarity index 100% rename from maven-project/src/main/mdo/profiles.mdo rename to maven-model-builder/src/main/mdo/profiles.mdo diff --git a/maven-project-builder/src/main/resources/org/apache/maven/project/pom-4.0.0.xml b/maven-model-builder/src/main/resources/org/apache/maven/project/pom-4.0.0.xml similarity index 100% rename from maven-project-builder/src/main/resources/org/apache/maven/project/pom-4.0.0.xml rename to maven-model-builder/src/main/resources/org/apache/maven/project/pom-4.0.0.xml diff --git a/maven-project-builder/src/test/projects/enforcer/enforcer-api/pom.xml b/maven-model-builder/src/test/projects/enforcer/enforcer-api/pom.xml similarity index 100% rename from maven-project-builder/src/test/projects/enforcer/enforcer-api/pom.xml rename to maven-model-builder/src/test/projects/enforcer/enforcer-api/pom.xml diff --git a/maven-project-builder/src/test/projects/enforcer/enforcer-rules/pom.xml b/maven-model-builder/src/test/projects/enforcer/enforcer-rules/pom.xml similarity index 100% rename from maven-project-builder/src/test/projects/enforcer/enforcer-rules/pom.xml rename to maven-model-builder/src/test/projects/enforcer/enforcer-rules/pom.xml diff --git a/maven-project-builder/src/test/projects/enforcer/maven-enforcer-plugin/pom.xml b/maven-model-builder/src/test/projects/enforcer/maven-enforcer-plugin/pom.xml similarity index 100% rename from maven-project-builder/src/test/projects/enforcer/maven-enforcer-plugin/pom.xml rename to maven-model-builder/src/test/projects/enforcer/maven-enforcer-plugin/pom.xml diff --git a/maven-project-builder/src/test/projects/enforcer/pom.xml b/maven-model-builder/src/test/projects/enforcer/pom.xml similarity index 100% rename from maven-project-builder/src/test/projects/enforcer/pom.xml rename to maven-model-builder/src/test/projects/enforcer/pom.xml diff --git a/maven-project-builder/src/test/resources/test.txt b/maven-model-builder/src/test/resources/test.txt similarity index 100% rename from maven-project-builder/src/test/resources/test.txt rename to maven-model-builder/src/test/resources/test.txt diff --git a/maven-model/pom.xml b/maven-model/pom.xml index b0c223c6c0..6c75b00ac7 100644 --- a/maven-model/pom.xml +++ b/maven-model/pom.xml @@ -20,15 +20,26 @@ under the License. --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-model + Maven Model Maven Model + + + + org.codehaus.plexus + plexus-utils + + + @@ -58,6 +69,7 @@ under the License. + all-models @@ -100,10 +112,4 @@ under the License. - - - org.codehaus.plexus - plexus-utils - - diff --git a/maven-model/src/main/mdo/maven.mdo b/maven-model/src/main/mdo/maven.mdo index 42f6391db4..a3851e6d96 100644 --- a/maven-model/src/main/mdo/maven.mdo +++ b/maven-model/src/main/mdo/maven.mdo @@ -583,6 +583,12 @@ return id.toString(); } + + @Override + public String toString() + { + return getId(); + } ]]> @@ -2110,8 +2116,8 @@ String - - filtering + + filteringValue 3.0.0+ filters element. ]]> - boolean - false + String mergeId @@ -2152,7 +2157,17 @@ setMergeId( "resource-" + (mergeIdCounter++) ); } } + + public boolean isFiltering() + { + return filteringValue != null ? (new Boolean(filteringValue)).booleanValue() : false; + } + public void setFiltering( boolean filtering ) + { + filteringValue = String.valueOf(filtering); + } + /** * @see java.lang.Object#toString() */ @@ -2433,12 +2448,11 @@ 4.0.0 Download policy. - - enabled + + enabledValue 4.0.0 Whether to use this repository for downloading this type of artifact. - boolean - true + String updatePolicy @@ -2474,6 +2488,26 @@ String + + + 4.0.0 + + + + + @@ -2736,7 +2770,7 @@ id 4.0.0 String - default-execution-id + default The identifier of this execution for labelling the goals during the build, and for matching executions to merge during inheritance. @@ -2762,7 +2796,7 @@ 4.0.0 diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index f649c4f109..f54c68cea3 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -20,14 +20,18 @@ under the License. --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-plugin-api + Maven Plugin API + @@ -39,6 +43,7 @@ under the License. plexus-container-default + diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java index 5f393c78e7..9442cddbce 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java @@ -38,7 +38,7 @@ public class LifecycleXpp3ReaderTest { public void testLifecycleReader() throws IOException, XmlPullParserException - { + {/* LifecycleMappingsXpp3Reader reader = new LifecycleMappingsXpp3Reader(); LifecycleConfiguration config = reader.read( new InputStreamReader( getClass().getResourceAsStream( "/lifecycle.xml" ) ) ); assertEquals( "check number of lifecycles", 1, config.getLifecycles().size() ); @@ -53,5 +53,6 @@ public class LifecycleXpp3ReaderTest assertEquals( "check number of goals", 1, e.getGoals().size() ); String g = (String) e.getGoals().iterator().next(); assertEquals( "check goal", "clover:compiler", g ); + */ } } diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/DataSourceRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/DataSourceRule.java deleted file mode 100644 index 16c9c3f7f1..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/DataSourceRule.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.ModelDataSource; -import org.apache.maven.shared.model.DataSourceException; - -public interface DataSourceRule -{ - void execute(ModelDataSource dataSource) throws DataSourceException; -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/JoinRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/JoinRule.java deleted file mode 100644 index 3ccdc41541..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/JoinRule.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; - -public interface JoinRule -{ - List execute(List modelProperties) throws DataSourceException; -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModel.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModel.java deleted file mode 100644 index 6dd68d85f8..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModel.java +++ /dev/null @@ -1,401 +0,0 @@ -package org.apache.maven.project.builder; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelMarshaller; -import org.apache.maven.shared.model.InputStreamDomainModel; -import org.codehaus.plexus.util.IOUtil; -import org.codehaus.plexus.util.ReaderFactory; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.ArrayList; -import java.util.Set; -import java.util.HashSet; - -/** - * Provides a wrapper for the maven model. - */ -public class PomClassicDomainModel implements InputStreamDomainModel -{ - - /** - * Bytes containing the underlying model - */ - private byte[] inputBytes; - - /** - * History of joins and deletes of model properties - */ - private String eventHistory; - - private String id; - - private File file; - - private File parentFile; - - private File projectDirectory; - - private List modelProperties; - - private int lineageCount; - - private boolean isMostSpecialized = false; - - private String parentGroupId = null, parentArtifactId = null, parentVersion = null, parentId = null, parentRelativePath; - - public PomClassicDomainModel( List modelProperties ) - { - this.modelProperties = modelProperties; - try - { - String xml = ModelMarshaller.unmarshalModelPropertiesToXml( modelProperties, ProjectUri.baseUri ); - inputBytes = xml.getBytes( "UTF-8" ); - } - catch ( IOException e ) - { - throw new IllegalStateException( "Unmarshalling of model properties failed", e ); - } - initializeProperties( modelProperties ); - } - - public PomClassicDomainModel( List modelProperties, boolean isMostSpecialized ) - { - this( modelProperties ); - this.isMostSpecialized = isMostSpecialized; - } - - - /** - * Constructor - * - * @param inputStream input stream of the maven model - * @throws IOException if there is a problem constructing the model - */ - public PomClassicDomainModel( InputStream inputStream ) - throws IOException - { - if ( inputStream == null ) - { - throw new IllegalArgumentException( "inputStream: null" ); - } - this.inputBytes = IOUtil.toByteArray( inputStream ); - modelProperties = getModelProperties(); - initializeProperties( modelProperties ); - } - - public PomClassicDomainModel( InputStream inputStream, boolean isMostSpecialized ) - throws IOException - { - this( inputStream ); - this.isMostSpecialized = isMostSpecialized; - } - - private void initializeProperties(List modelProperties) - { - String groupId = null, artifactId = null, version = null; - for(ModelProperty mp : modelProperties) - { - if(mp.getUri().equals(ProjectUri.groupId)) - { - groupId = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.artifactId)) - { - artifactId = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.version)) - { - version = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.Parent.artifactId)) - { - parentArtifactId = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.Parent.groupId)) - { - parentGroupId = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.Parent.version)) - { - parentVersion = mp.getResolvedValue(); - } - else if(mp.getUri().equals(ProjectUri.Parent.relativePath)) - { - parentRelativePath = mp.getResolvedValue(); - } - - if(groupId != null && artifactId != null && version != null && parentGroupId != null && - parentArtifactId != null && parentVersion != null & parentRelativePath != null) - { - break; - } - } - if( groupId == null && parentGroupId != null) - { - groupId = parentGroupId; - } - if( artifactId == null && parentArtifactId != null) - { - artifactId = parentArtifactId; - } - if( version == null && parentVersion != null ) - { - version = parentVersion; - } - - if(parentGroupId != null && parentArtifactId != null && parentVersion != null) - { - parentId = parentGroupId + ":" + parentArtifactId + ":" + parentVersion; - } - - if(parentRelativePath == null) - { - parentRelativePath = ".." + File.separator + "pom.xml"; - } - - id = groupId + ":" + artifactId + ":" + version; - } - - public PomClassicDomainModel( File file ) - throws IOException - { - this( new FileInputStream( file ) ); - this.file = file; - } - - public File getParentFile() - { - return parentFile; - } - - public void setParentFile( File parentFile ) - { - this.parentFile = parentFile; - } - - public String getParentGroupId() { - return parentGroupId; - } - - public String getParentArtifactId() { - return parentArtifactId; - } - - public String getParentVersion() { - return parentVersion; - } - - /** - * This should only be set for projects that are in the build. Setting for poms in the repo may cause unstable behavior. - * - * @param projectDirectory - */ - public void setProjectDirectory(File projectDirectory) - { - this.projectDirectory = projectDirectory; - } - - public File getProjectDirectory() - { - return projectDirectory; - } - - public boolean isPomInBuild() - { - return projectDirectory != null; - } - - public String getParentId() throws IOException - { - return parentId; - } - - public String getRelativePathOfParent() - { - return parentRelativePath; - } - - public String getId() throws IOException - { - return id; - } - - - public boolean matchesParentOf( PomClassicDomainModel domainModel ) throws IOException - { - if ( domainModel == null ) - { - throw new IllegalArgumentException( "domainModel: null" ); - } - - return getId().equals(domainModel.getParentId()); - } - - /** - * Returns XML model as string - * - * @return XML model as string - */ - public String asString() - { - try - { - return IOUtil.toString( ReaderFactory.newXmlReader( new ByteArrayInputStream( inputBytes ) ) ); - } - catch ( IOException ioe ) - { - // should not occur: everything is in-memory - return ""; - } - } - - /** - * @see org.apache.maven.shared.model.InputStreamDomainModel#getInputStream() - */ - public InputStream getInputStream() - { - byte[] copy = new byte[inputBytes.length]; - System.arraycopy( inputBytes, 0, copy, 0, inputBytes.length ); - return new ByteArrayInputStream( copy ); - } - - /** - * @return file of pom. May be null. - */ - public File getFile() - { - return file; - } - - public List getModelProperties() throws IOException - { - if(modelProperties == null) - { - Set s = new HashSet(); - //TODO: Should add all collections from ProjectUri - s.addAll(PomTransformer.URIS); - s.add(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri); - s.add(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.xUri); - s.add(ProjectUri.Dependencies.Dependency.Exclusions.xUri); - s.add(ProjectUri.Build.Plugins.Plugin.Executions.xUri); - s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI); - s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.xUri); - s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration); - s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.configuration); - //TODO: More profile info - s.add(ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Executions.xUri); - s.add(ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.Dependency.Exclusions.xUri); - s.add(ProjectUri.Profiles.Profile.Dependencies.Dependency.Exclusions.xUri); - s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri); - s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.Goals.xURI); - s.add(ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.xUri); - s.add(ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration); - s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.configuration); - s.add(ProjectUri.Profiles.Profile.properties); - s.add(ProjectUri.Profiles.Profile.modules); - s.add(ProjectUri.Profiles.Profile.Dependencies.xUri); - s.add(ProjectUri.Profiles.Profile.Build.Plugins.Plugin.configuration); - - modelProperties = ModelMarshaller.marshallXmlToModelProperties( - getInputStream(), ProjectUri.baseUri, s ); - } - return new ArrayList(modelProperties); - } - - /** - * @see org.apache.maven.shared.model.DomainModel#getEventHistory() - */ - public String getEventHistory() - { - return eventHistory; - } - - /** - * @see org.apache.maven.shared.model.DomainModel#setEventHistory(String) - */ - public void setEventHistory( String eventHistory ) - { - if ( eventHistory == null ) - { - throw new IllegalArgumentException( "eventHistory: null" ); - } - this.eventHistory = eventHistory; - } - - public int getLineageCount() - { - return lineageCount; - } - - public void setLineageCount( int lineageCount ) - { - this.lineageCount = lineageCount; - } - - public PomClassicDomainModel createCopy() - { - List props = new ArrayList(); - for(ModelProperty mp : modelProperties) - { - props.add(mp.createCopyOfOriginal()); - } - - return new PomClassicDomainModel(props); - } - - /** - * Returns true if this.asString.equals(o.asString()), otherwise false. - * - * @param o domain model - * @return true if this.asString.equals(o.asString()), otherwise false. - */ - public boolean equals( Object o ) - { - try { - return o instanceof PomClassicDomainModel && getId().equals( ( (PomClassicDomainModel) o ).getId() ); - } catch (IOException e) { - return false; - } - } - - public boolean isMostSpecialized() - { - return isMostSpecialized; - } - - public void setMostSpecialized( boolean isMostSpecialized ) - { - this.isMostSpecialized = isMostSpecialized; - } - - @Override - public String toString() - { - return String.valueOf( id ); - } - -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModelFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModelFactory.java deleted file mode 100644 index e293584423..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomClassicDomainModelFactory.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.DomainModelFactory; -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.ModelProperty; - -import java.util.List; -import java.io.IOException; - -public class PomClassicDomainModelFactory implements DomainModelFactory -{ - public DomainModel createDomainModel(List modelProperties) throws IOException - { - return new PomClassicDomainModel(modelProperties); - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomTransformer.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomTransformer.java deleted file mode 100644 index edd41471ad..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/PomTransformer.java +++ /dev/null @@ -1,873 +0,0 @@ -package org.apache.maven.project.builder; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.io.File; -import java.io.IOException; -import java.util.*; - -import org.apache.maven.shared.model.*; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; -import org.apache.maven.project.builder.rules.*; -import org.apache.maven.project.builder.factories.PluginExecutionIdModelContainerFactory; -import org.apache.maven.project.builder.factories.AlwaysJoinModelContainerFactory; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.project.builder.factories.IdModelContainerFactory; - -/** - * Provides methods for transforming model properties into a domain model for the pom classic format and vice versa. - */ -public class PomTransformer - implements ModelTransformer -{ - - private final DomainModelFactory factory; - - public PomTransformer(DomainModelFactory factory) - { - this.factory = factory; - } - - public static final List MODEL_CONTAINER_FACTORIES = - Collections.unmodifiableList(Arrays.asList(new ArtifactModelContainerFactory(), - new IdModelContainerFactory(ProjectUri.PluginRepositories.PluginRepository.xUri), - new IdModelContainerFactory(ProjectUri.Repositories.Repository.xUri), - new IdModelContainerFactory(ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.xUri), - new IdModelContainerFactory(ProjectUri.Profiles.Profile.xUri), - new IdModelContainerFactory(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri))); - - private static Collection goals_infos = Arrays.asList( - ModelContainerInfo.Factory.createModelContainerInfo( - new AlwaysJoinModelContainerFactory(), new ExecutionRule(), null) - ); - - private static Collection plugin_executions = Arrays.asList( - ModelContainerInfo.Factory.createModelContainerInfo( - new IdModelContainerFactory(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri), - null, goals_infos) - ); - - private static Collection dependency_exclusions = Arrays.asList( - ModelContainerInfo.Factory.createModelContainerInfo( - new IdModelContainerFactory(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.Exclusion.xUri), - new DependencyRule(), null) - ); - - //Don't add subcontainers here, breaks MNG-3821 - public static final Collection MODEL_CONTAINER_INFOS = Arrays.asList( - ModelContainerInfo.Factory.createModelContainerInfo( - new ArtifactModelContainerFactory(), null, plugin_executions), - ModelContainerInfo.Factory.createModelContainerInfo( - new IdModelContainerFactory(ProjectUri.PluginRepositories.PluginRepository.xUri), null, null), - ModelContainerInfo.Factory.createModelContainerInfo( - new IdModelContainerFactory(ProjectUri.Repositories.Repository.xUri), null, null), - ModelContainerInfo.Factory.createModelContainerInfo( - new ArtifactModelContainerFactory(), null, dependency_exclusions), - ModelContainerInfo.Factory.createModelContainerInfo( - new IdModelContainerFactory(ProjectUri.Profiles.Profile.xUri), null, null) - ); - - /** - * The URIs this transformer supports - */ - public static final Set URIS = Collections.unmodifiableSet(new HashSet( Arrays.asList( ProjectUri.Build.Extensions.xUri, - ProjectUri.Build.PluginManagement.Plugins.xUri, - ProjectUri.Build.PluginManagement.Plugins.Plugin.configuration, - ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri, - ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.xURI, - ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri, - ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.Dependency.Exclusions.xUri, - ProjectUri.Build.Plugins.xUri, - ProjectUri.properties, - ProjectUri.Build.Plugins.Plugin.configuration, - ProjectUri.Reporting.Plugins.xUri, - ProjectUri.Reporting.Plugins.Plugin.configuration, - ProjectUri.Build.Plugins.Plugin.Dependencies.xUri, - ProjectUri.Build.Resources.xUri, - ProjectUri.Build.Resources.Resource.includes, - ProjectUri.Build.Resources.Resource.excludes, - ProjectUri.Build.TestResources.xUri, - ProjectUri.Build.Filters.xUri, - ProjectUri.CiManagement.Notifiers.xUri, - ProjectUri.Contributors.xUri, - ProjectUri.Dependencies.xUri, - ProjectUri.DependencyManagement.Dependencies.xUri, - ProjectUri.Developers.xUri, - ProjectUri.Developers.Developer.roles, - ProjectUri.Licenses.xUri, - ProjectUri.MailingLists.xUri, - ProjectUri.Modules.xUri, - ProjectUri.PluginRepositories.xUri, - ProjectUri.Profiles.xUri, - ProjectUri.Profiles.Profile.Build.Plugins.xUri, - ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Dependencies.xUri, - ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri, - ProjectUri.Profiles.Profile.Build.Resources.xUri, - ProjectUri.Profiles.Profile.Build.TestResources.xUri, - ProjectUri.Profiles.Profile.Dependencies.xUri, - ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.xUri, - ProjectUri.Profiles.Profile.PluginRepositories.xUri, - ProjectUri.Profiles.Profile.Reporting.Plugins.xUri, - ProjectUri.Profiles.Profile.Repositories.xUri, - ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.xUri, - ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri, - ProjectUri.Reporting.Plugins.xUri, - ProjectUri.Repositories.xUri) )); - - /** - * The URIs that denote file/directory paths and need their file separators being normalized. - */ - private static final Set PATH_URIS = - Collections.unmodifiableSet( new HashSet( - Arrays.asList( - ProjectUri.Build.directory, - ProjectUri.Build.outputDirectory, - ProjectUri.Build.testOutputDirectory, - ProjectUri.Build.sourceDirectory, - ProjectUri.Build.testSourceDirectory, - ProjectUri.Build.scriptSourceDirectory, - ProjectUri.Build.Resources.Resource.directory, - ProjectUri.Build.TestResources.TestResource.directory, - ProjectUri.Build.Filters.filter, - ProjectUri.Reporting.outputDirectory ) ) ); - /** - * @see ModelTransformer#transformToDomainModel(java.util.List, java.util.List) - */ - public final DomainModel transformToDomainModel( List properties, List eventListeners ) - throws IOException - { - if ( properties == null ) - { - throw new IllegalArgumentException( "properties: null" ); - } - - if( eventListeners == null ) - { - eventListeners = new ArrayList(); - } - else - { - eventListeners = new ArrayList(eventListeners); - } - - List props = new ArrayList( properties ); - - - ModelDataSource source = new DefaultModelDataSource( props, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - //Dependency Management - new DependencyManagementDataSourceRule().execute( source ); - - //Plugin Management - List joinedContainers = new ArrayList(); - for ( ModelContainer pluginContainer : source.queryFor( ProjectUri.Build.Plugins.Plugin.xUri ) ) - { - for ( ModelContainer managementContainer : source.queryFor( ProjectUri.Build.PluginManagement.Plugins.Plugin.xUri ) ) - { - //Transform from plugin management to plugins - List transformedProperties = new ArrayList(); - for ( ModelProperty mp : managementContainer.getProperties() ) - { - if ( mp.getUri().startsWith( ProjectUri.Build.PluginManagement.xUri ) ) - { - transformedProperties.add( new ModelProperty( mp.getUri().replace( ProjectUri.Build.PluginManagement.xUri, - ProjectUri.Build.xUri ), mp.getResolvedValue() ) ); - } - } - - managementContainer = new ArtifactModelContainerFactory().create( transformedProperties ); - - //Remove duplicate executions tags - boolean hasExecutionsTag = false; - for ( ModelProperty mp : pluginContainer.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.Executions.xUri ) ) - { - hasExecutionsTag = true; - break; - } - } - - List pList; - - if ( !hasExecutionsTag ) - { - pList = managementContainer.getProperties(); - } - else - { - pList = new ArrayList(); - - for ( ModelProperty mp : managementContainer.getProperties() ) - { - if ( !mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.Executions.xUri ) ) - { - pList.add( mp ); - } - } - } - - managementContainer = new ArtifactModelContainerFactory().create( pList ); - - ModelContainerAction action = pluginContainer.containerAction( managementContainer ); - - //Join Execution Containers - if ( action.equals( ModelContainerAction.JOIN ) || action.equals( ModelContainerAction.DELETE ) ) - { - ModelDataSource pluginDatasource = new DefaultModelDataSource( pluginContainer.getProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES ); - ModelDataSource managementDatasource = new DefaultModelDataSource( managementContainer.getProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List managementExecutionContainers = managementDatasource.queryFor(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri); - List managementPropertiesWithoutExecutions = new ArrayList(managementContainer.getProperties()); - for(ModelContainer a : managementExecutionContainers) - { - managementPropertiesWithoutExecutions.removeAll(a.getProperties()); - } - - source.joinWithOriginalOrder( pluginContainer, new ArtifactModelContainerFactory().create(managementPropertiesWithoutExecutions) ); - - List pluginExecutionContainers = pluginDatasource.queryFor(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri); - List joinedExecutionContainers = new ArrayList(); - - for(ModelContainer a : managementExecutionContainers) - { - boolean hasId = false; - for(ModelProperty mp : a.getProperties()) { - if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.id)) { - hasId = true; - break; - } - } - - ModelContainer c = a; - if(!hasId) { - List listWithId = new ArrayList(a.getProperties()); - listWithId.add(1, new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.id, "default")); - c = new IdModelContainerFactory(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri).create(listWithId); - } - - - for(ModelContainer b : pluginExecutionContainers) - { - if(b.containerAction(c).equals(ModelContainerAction.JOIN)) - { - //MNG-3995 - property lost here - joinedContainers.addAll(source.join(b, c).getProperties()); - joinedExecutionContainers.add(a); - } - } - } - - ModelProperty executionsProperty = null; - for(ModelProperty a : pluginContainer.getProperties()) - { - if(a.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.xUri)) { - executionsProperty = a; - break; - } - } - - if(executionsProperty == null) - { - for(ModelProperty a : managementPropertiesWithoutExecutions) - { - if(a.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.xUri)) { - executionsProperty = a; - break; - } - } - } - - if(executionsProperty != null) - { - managementExecutionContainers.removeAll(joinedExecutionContainers); - Collections.reverse(managementExecutionContainers); - for(ModelContainer a : managementExecutionContainers) - { - source.insertModelPropertiesAfter(executionsProperty, - ModelTransformerContext.sort(a.getProperties(), ProjectUri.Build.Plugins.Plugin.Executions.xUri)); - } - } - - } - } - } - - props = source.getModelProperties(); - - //TransformerRule: Do not join plugin executions without ids - Set removeProperties = new HashSet(); - - ModelDataSource dataSource = new DefaultModelDataSource( props, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List containers = dataSource.queryFor( ProjectUri.Build.Plugins.Plugin.xUri ); - - for ( ModelContainer pluginContainer : containers ) - { - ModelDataSource executionSource = new DefaultModelDataSource( pluginContainer.getProperties(), - Arrays.asList( new ArtifactModelContainerFactory(), new PluginExecutionIdModelContainerFactory() )); - - List executionContainers = executionSource.queryFor( ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri ); - - if ( executionContainers.size() < 2 ) - { - continue; - } - - boolean hasAtLeastOneWithoutId = false; - - for ( ModelContainer executionContainer : executionContainers ) - { - - - if ( hasAtLeastOneWithoutId && !hasExecutionId( executionContainer ) && executionContainers.indexOf( executionContainer ) > 0 ) - { - removeProperties.addAll( executionContainer.getProperties() ); - } - if ( !hasAtLeastOneWithoutId ) - { - hasAtLeastOneWithoutId = !hasExecutionId( executionContainer ); - } - } - } - - props.removeAll( removeProperties ); - - //Execution TransformerRule - extension for this needs to be pushed into model-builder - dataSource = new DefaultModelDataSource( props, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - for(ModelContainer mc : dataSource.queryFor( ProjectUri.Build.Plugins.Plugin.xUri )) - { - ModelDataSource executionSource = - new DefaultModelDataSource(mc.getProperties(), - Arrays.asList(new IdModelContainerFactory(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri), - new AlwaysJoinModelContainerFactory())); - for(ModelContainer es : executionSource.queryFor( ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri )) { - ExecutionRule rule = new ExecutionRule(); - // List x = rule.execute(es.getProperties()); - List x = !aContainsAnyOfB(es.getProperties(), joinedContainers) ? rule.execute(es.getProperties()) : - ModelTransformerContext.sort(rule.execute(es.getProperties()), - ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri); - - dataSource.replace(es, es.createNewInstance(x)); - } - } - - props =// false ? ModelTransformerContext.sort(dataSource.getModelProperties(), ProjectUri.baseUri) - dataSource.getModelProperties(); - - for(ModelEventListener listener : eventListeners) - { - ModelDataSource ds = new DefaultModelDataSource( props, listener.getModelContainerFactories() ); - for(String uri : listener.getUris() ) - { - listener.fire(ds.queryFor(uri)); - } - } - - //Cleanup props (MNG-3979) - List p = new ArrayList(); - for(ModelProperty mp : props) - { - if(mp.getResolvedValue() != null - && mp.getResolvedValue().trim().equals("")) - { - int index = props.indexOf(mp) + 1; - - if(index < props.size() && mp.isParentOf(props.get(index)) && mp.getDepth() != props.get(index).getDepth() - && !props.get(index).getUri().contains("#property")) - { - p.add(new ModelProperty(mp.getUri(), null)); - } - else - { - p.add(mp); - } - } - else if ( mp.getResolvedValue() != null && PATH_URIS.contains( mp.getUri() ) ) - { - // normalize file separator - p.add( new ModelProperty( mp.getUri(), new File( mp.getResolvedValue() ).getPath() ) ); - } - else - { - p.add(mp); - } - } - - return factory.createDomainModel( p ); - } - - private static boolean aContainsAnyOfB(List a, List b) { - for(ModelProperty mpA : a ) - { - for(ModelProperty mpB : b) - { - if(mpA.equals(mpB)) - { - return true; - } - } - } - return false; - } - - - - List transformerRules = Arrays.asList(new MissingVersionTransformerRule(), - new DefaultDependencyScopeTransformerRule(), new MissingGroupIdTransformerRule()); - - List transformerRemovalRules = Arrays.asList(new DefaultExecutionIdTransformerRule(), - new ModulesNotInheritedTransformerRule(), new NotInheritedPluginExecutionTransformerRule(), - new NotInheritedPluginTransformerRule(), new RelativePathNotInheritedTransformerRule(), - new PackagingNotInheritedTransformerRule(), new NameNotInheritedTransformerRule()); - - /** - * @see ModelTransformer#transformToModelProperties(java.util.List) - */ - public final List transformToModelProperties(List domainModels - ) - throws IOException - { - if ( domainModels == null || domainModels.isEmpty() ) - { - throw new IllegalArgumentException( "domainModels: null or empty" ); - } - - List modelProperties = new ArrayList(); - List projectNames = new ArrayList(); - StringBuilder projectUrl = new StringBuilder( 128 ); - StringBuilder siteUrl = new StringBuilder( 128 ); - StringBuilder scmUrl = new StringBuilder( 128 ); - StringBuilder scmConnectionUrl = new StringBuilder( 128 ); - StringBuilder scmDeveloperUrl = new StringBuilder( 128 ); - - boolean containsBuildResources = false; - boolean containsTestResources = false; - boolean containsPluginRepositories = false; - boolean containsLicenses = false; - boolean containsDevelopers = false; - boolean containsContributors = false; - boolean containsMailingLists = false; - boolean containsOrganization = false; - boolean containsIssueManagement = false; - boolean containsCiManagement = false; - boolean containsDistRepo = false; - boolean containsDistSnapRepo = false; - boolean containsDistSite = false; - - - for ( DomainModel domainModel : domainModels ) - { - List tmp = domainModel.getModelProperties(); - - List clearedProperties = new ArrayList(); - - for(TransformerRule rule : transformerRules) - { - rule.execute(tmp, domainModel.isMostSpecialized()); - } - - for(TransformerRemovalRule rule : transformerRemovalRules) - { - tmp.removeAll(rule.executeWithReturnPropertiesToRemove(tmp, domainModel.isMostSpecialized())); - } - - // Project URL TransformerRule - adjustUrl( projectUrl, tmp, ProjectUri.url, projectNames ); - // Site TransformerRule - adjustUrl( siteUrl, tmp, ProjectUri.DistributionManagement.Site.url, projectNames ); - // SCM TransformerRule - adjustUrl( scmUrl, tmp, ProjectUri.Scm.url, projectNames ); - // SCM Connection TransformerRule - adjustUrl( scmConnectionUrl, tmp, ProjectUri.Scm.connection, projectNames ); - // SCM Developer TransformerRule - adjustUrl( scmDeveloperUrl, tmp, ProjectUri.Scm.developerConnection, projectNames ); - - // Profiles TransformerRule: not inherited - // Prerequisites TransformerRule: not inherited - // DistributionManagent.Relocation TransformerRule: not inherited - if ( !domainModel.isMostSpecialized() ) - { - for ( ModelProperty mp : tmp ) - { - String uri = mp.getUri(); - if ( uri.startsWith( ProjectUri.Profiles.xUri ) - || uri.startsWith( ProjectUri.Prerequisites.xUri ) - || uri.startsWith( ProjectUri.DistributionManagement.Relocation.xUri ) ) - { - clearedProperties.add( mp ); - } - } - } - - // Remove Plugin Repository Inheritance TransformerRule - // License TransformerRule: only inherited if not specified in child - // Organization TransformerRule: only inherited if not specified in child - // Developers TransformerRule: only inherited if not specified in child - // Contributors TransformerRule: only inherited if not specified in child - // Mailing Lists TransformerRule: only inherited if not specified in child - // Build Resources TransformerRule: only inherited if not specified in child - // Build Test Resources TransformerRule: only inherited if not specified in child - // CI Management TransformerRule: only inherited if not specified in child - // Issue Management TransformerRule: only inherited if not specified in child - // Distribution Management Repository TransformerRule: only inherited if not specified in child - // Distribution Management Snapshot Repository TransformerRule: only inherited if not specified in child - // Distribution Management Site TransformerRule: only inherited if not specified in child - for ( ModelProperty mp : tmp ) - { - String uri = mp.getUri(); - if ( ( containsBuildResources && uri.startsWith( ProjectUri.Build.Resources.xUri ) ) - || ( containsTestResources && uri.startsWith( ProjectUri.Build.TestResources.xUri ) ) - || ( containsPluginRepositories && uri.startsWith( ProjectUri.PluginRepositories.xUri ) ) - || ( containsOrganization && uri.startsWith( ProjectUri.Organization.xUri ) ) - || ( containsLicenses && uri.startsWith( ProjectUri.Licenses.xUri ) ) - || ( containsDevelopers && uri.startsWith( ProjectUri.Developers.xUri ) ) - || ( containsContributors && uri.startsWith( ProjectUri.Contributors.xUri ) ) - || ( containsMailingLists && uri.startsWith( ProjectUri.MailingLists.xUri ) ) - || ( containsCiManagement && uri.startsWith( ProjectUri.CiManagement.xUri ) ) - || ( containsIssueManagement && uri.startsWith( ProjectUri.IssueManagement.xUri ) ) - || ( containsDistRepo && uri.startsWith( ProjectUri.DistributionManagement.Repository.xUri ) ) - || ( containsDistSnapRepo && uri.startsWith( ProjectUri.DistributionManagement.SnapshotRepository.xUri ) ) - || ( containsDistSite && uri.startsWith( ProjectUri.DistributionManagement.Site.xUri ) ) ) - { - clearedProperties.add( mp ); - } - } - containsBuildResources |= hasProjectUri( ProjectUri.Build.Resources.xUri, tmp ); - containsTestResources |= hasProjectUri( ProjectUri.Build.TestResources.xUri, tmp ); - containsPluginRepositories |= hasProjectUri( ProjectUri.PluginRepositories.xUri, tmp ); - containsOrganization |= hasProjectUri( ProjectUri.Organization.xUri, tmp ); - containsLicenses |= hasProjectUri( ProjectUri.Licenses.xUri, tmp ); - containsDevelopers |= hasProjectUri( ProjectUri.Developers.xUri, tmp ); - containsContributors |= hasProjectUri( ProjectUri.Contributors.xUri, tmp ); - containsMailingLists |= hasProjectUri( ProjectUri.MailingLists.xUri, tmp ); - containsCiManagement |= hasProjectUri( ProjectUri.CiManagement.xUri, tmp ); - containsIssueManagement |= hasProjectUri( ProjectUri.IssueManagement.xUri, tmp ); - containsDistRepo |= hasProjectUri( ProjectUri.DistributionManagement.Repository.xUri, tmp ); - containsDistSnapRepo |= hasProjectUri( ProjectUri.DistributionManagement.SnapshotRepository.xUri, tmp ); - containsDistSite |= hasProjectUri( ProjectUri.DistributionManagement.Site.xUri, tmp ); - - ModelProperty artifactId = getPropertyFor( ProjectUri.artifactId, tmp ); - if ( artifactId != null ) - { - projectNames.add( 0, artifactId.getResolvedValue() ); - } - - tmp.removeAll( clearedProperties ); - modelProperties.addAll( tmp ); - modelProperties.removeAll( clearedProperties ); - } - - //Rules processed on collapsed pom - - //TransformerRule: Remove duplicate filters - modelProperties.removeAll(new DuplicateFiltersTransformerRule().executeWithReturnPropertiesToRemove( modelProperties , false)); - - //TransformerRule: Build plugin config overrides reporting plugin config - return new OverideConfigTransformerRule().execute( modelProperties ); - } - - /** - * Overide this method to change the way interpolation is handled. - * - * @param modelProperties - * @param interpolatorProperties - * @param domainModel - * @throws IOException - */ - private static final Map aliases = new HashMap(); - - private static void addProjectAlias( String element, boolean leaf ) - { - String suffix = leaf ? "\\}" : "\\."; - aliases.put( "\\$\\{project\\." + element + suffix, "\\$\\{" + element + suffix ); - } - - static - { - aliases.put( "\\$\\{project\\.", "\\$\\{pom\\." ); - addProjectAlias( "modelVersion", true ); - addProjectAlias( "groupId", true ); - addProjectAlias( "artifactId", true ); - addProjectAlias( "version", true ); - addProjectAlias( "packaging", true ); - addProjectAlias( "name", true ); - addProjectAlias( "description", true ); - addProjectAlias( "inceptionYear", true ); - addProjectAlias( "url", true ); - addProjectAlias( "parent", false ); - addProjectAlias( "prerequisites", false ); - addProjectAlias( "organization", false ); - addProjectAlias( "build", false ); - addProjectAlias( "reporting", false ); - addProjectAlias( "scm", false ); - addProjectAlias( "distributionManagement", false ); - addProjectAlias( "issueManagement", false ); - addProjectAlias( "ciManagement", false ); - } - - public void interpolateModelProperties( List modelProperties, - List interpolatorProperties, - DomainModel domainModel ) - throws IOException - { - PomClassicDomainModel dm = (PomClassicDomainModel) domainModel; - - if ( !containsProjectVersion( interpolatorProperties ) ) - { - aliases.put( "\\$\\{project.version\\}", "\\$\\{version\\}" ); - } - - List firstPassModelProperties = new ArrayList(); - List secondPassModelProperties = new ArrayList(); - - ModelProperty buildProperty = new ModelProperty( ProjectUri.Build.xUri, null ); - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getValue() != null && !mp.getUri().contains( "#property" ) && !mp.getUri().contains( "#collection" ) ) - { - if ( ( !buildProperty.isParentOf( mp ) && !mp.getUri().equals( ProjectUri.Reporting.outputDirectory ) || mp.getUri().equals( ProjectUri.Build.finalName ) ) ) - { - firstPassModelProperties.add( mp ); - } - else - { - secondPassModelProperties.add( mp ); - } - } - } - - List standardInterpolatorProperties = new ArrayList(); - if ( dm.isPomInBuild() ) - { - String basedir = dm.getProjectDirectory().getAbsolutePath(); - standardInterpolatorProperties.add( new InterpolatorProperty( "${project.basedir}", basedir, PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); - standardInterpolatorProperties.add( new InterpolatorProperty( "${basedir}", basedir, PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); - standardInterpolatorProperties.add( new InterpolatorProperty( "${pom.basedir}", basedir, PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); - - } - - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.properties ) && mp.getValue() != null ) - { - String uri = mp.getUri(); - standardInterpolatorProperties.add( new InterpolatorProperty( "${" + uri.substring( uri.lastIndexOf( "/" ) + 1, uri.length() ) + "}", mp.getValue(), - PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); - } - } - - //FIRST PASS - Withhold using build directories as interpolator properties - List ips1 = new ArrayList( interpolatorProperties ); - ips1.addAll( standardInterpolatorProperties ); - ips1.addAll( ModelTransformerContext.createInterpolatorProperties( firstPassModelProperties, ProjectUri.baseUri, aliases, PomInterpolatorTag.PROJECT_PROPERTIES.name(), false, false ) ); - Collections.sort( ips1, new Comparator() - { - public int compare( InterpolatorProperty o, InterpolatorProperty o1 ) - { - if(o.getTag() == null || o1.getTag() == null) - { - return 0; - } - return PomInterpolatorTag.valueOf(o.getTag()).compareTo(PomInterpolatorTag.valueOf(o1.getTag())); - } - }); - - ModelTransformerContext.interpolateModelProperties( modelProperties, ips1 ); - - //SECOND PASS - Set absolute paths on build directories - if ( dm.isPomInBuild() ) - { - String basedir = dm.getProjectDirectory().getAbsolutePath(); - Map buildDirectories = new HashMap(); - for ( ModelProperty mp : secondPassModelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.Build.xUri ) || mp.getUri().equals( ProjectUri.Reporting.outputDirectory ) ) - { - File file = new File(mp.getResolvedValue()); - if( !file.isAbsolute() && !mp.getResolvedValue().startsWith("${project.build.") - && !mp.getResolvedValue().equals("${project.basedir}")) - { - buildDirectories.put( mp, new ModelProperty( mp.getUri(), new File( basedir, file.getPath() ).getAbsolutePath() ) ); - } - } - } - - for ( Map.Entry e : buildDirectories.entrySet() ) - { - secondPassModelProperties.remove( e.getKey() ); - secondPassModelProperties.add( e.getValue() ); - } - } - - //THIRD PASS - Use build directories as interpolator properties - List ips2 = new ArrayList( interpolatorProperties ); - ips2.addAll( standardInterpolatorProperties ); - ips2.addAll( ModelTransformerContext.createInterpolatorProperties( secondPassModelProperties, ProjectUri.baseUri, aliases, PomInterpolatorTag.PROJECT_PROPERTIES.name(), false, false ) ); - ips2.addAll( interpolatorProperties ); - Collections.sort( ips2, new Comparator() - { - public int compare( InterpolatorProperty o, InterpolatorProperty o1 ) - { - if(o.getTag() == null || o1.getTag() == null) - { - return 0; - } - - return PomInterpolatorTag.valueOf( o.getTag() ).compareTo( PomInterpolatorTag.valueOf( o1.getTag() ) ); - } - } ); - - ModelTransformerContext.interpolateModelProperties( modelProperties, ips2 ); - } - /** - * Override this method for different preprocessing of model properties. - * - * @param modelProperties - * @return - */ - public List preprocessModelProperties(List modelProperties) - { - return new ArrayList(modelProperties); - } - - /** - * Returns the base uri of all model properties: http://apache.org/maven/project/ - * - * @return Returns the base uri of all model properties: http://apache.org/maven/project/ - */ - public final String getBaseUri() - { - return ProjectUri.baseUri; - } - - /** - * Adjusts an inherited URL to compensate for a child's relation/distance to the parent that defines the URL. - * - * @param url The buffer for the adjusted URL, must not be {@code null}. - * @param properties The model properties to update, must not be {@code null}. - * @param uri The URI of the model property defining the URL to adjust, must not be {@code null}. - * @param ids The artifact identifiers of the parent projects, starting with the least significant parent, must not - * be {@code null}. - */ - private void adjustUrl( StringBuilder url, List properties, String uri, List ids ) - { - if ( url.length() == 0 ) - { - ModelProperty property = getPropertyFor( uri, properties ); - if ( property != null ) - { - url.append( property.getResolvedValue() ); - for ( String id : ids ) - { - if ( url.length() > 0 && url.charAt( url.length() - 1 ) != '/' ) - { - url.append( '/' ); - } - url.append( id ); - } - int index = properties.indexOf( property ); - properties.set( index, new ModelProperty( uri, url.toString() ) ); - } - } - } - - private static boolean containsProjectVersion( List interpolatorProperties ) - { - InterpolatorProperty versionInterpolatorProperty = - new ModelProperty( ProjectUri.version, "").asInterpolatorProperty( ProjectUri.baseUri); - for( InterpolatorProperty ip : interpolatorProperties) - { - if ( ip.equals( versionInterpolatorProperty ) ) - { - return true; - } - } - return false; - } - - private static boolean hasExecutionId( ModelContainer executionContainer ) - { - for ( ModelProperty mp : executionContainer.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.Executions.Execution.id ) ) - { - return true; - } - } - return false; - } - - private static boolean hasProjectUri( String projectUri, List modelProperties ) - { - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().equals( projectUri ) ) - { - return true; - } - } - return false; - } - - /** - * Returns all model properties containing the specified uri from the specified properties list. - * - * @param uri the uri to use in finding the returned model properties - * @param properties the model properties list to search - * @return all model properties containing the specified uri from the specified properties list - */ - public static List getPropertiesFor( String uri, List properties ) - { - List modelProperties = new ArrayList(); - for ( ModelProperty mp : properties ) - { - if ( uri.equals( mp.getUri() ) ) - { - modelProperties.add( mp ); - } - } - return modelProperties; - } - - - /** - * Returns the first model property containing the specified uri from the specified properties list. - * - * @param uri the uri to use in finding the returned model property - * @param properties the model properties list to search - * @return the first model property containing the specified uri from the specified properties list. - */ - public static ModelProperty getPropertyFor( String uri, List properties ) - { - for ( ModelProperty mp : properties ) - { - if ( uri.equals( mp.getUri() ) ) - { - return mp; - } - } - return null; - } - - -} - diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRemovalRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRemovalRule.java deleted file mode 100644 index d735a81da5..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRemovalRule.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; - -public interface TransformerRemovalRule { - - List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException; -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRule.java deleted file mode 100644 index cd69b17340..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/TransformerRule.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; - -public interface TransformerRule -{ - void execute(List modelProperties, boolean isMostSpecialized) throws DataSourceException; - -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/AlwaysJoinModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/AlwaysJoinModelContainerFactory.java deleted file mode 100644 index cd566c8467..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/AlwaysJoinModelContainerFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.apache.maven.project.builder.factories; - -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.*; - -public class AlwaysJoinModelContainerFactory - implements ModelContainerFactory -{ - - private static final Collection uris = Collections.unmodifiableList( Arrays.asList( - - ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal - // ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri - - ) ); - - public Collection getUris() - { - return uris; - } - - public ModelContainer create( List modelProperties ) - { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new Anon_ModelContainer( modelProperties ); - } - - private static class Anon_ModelContainer - implements ModelContainer - { - - public Anon_ModelContainer(List properties) { - this.properties = new ArrayList(properties); - } - - private List properties; - - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - return ModelContainerAction.JOIN; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new Anon_ModelContainer( modelProperties ); - } - - public List getProperties() - { - return new ArrayList(properties); - } - - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ArtifactModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ArtifactModelContainerFactory.java deleted file mode 100644 index 11d420361a..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ArtifactModelContainerFactory.java +++ /dev/null @@ -1,241 +0,0 @@ -package org.apache.maven.project.builder.factories; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public final class ArtifactModelContainerFactory - implements ModelContainerFactory -{ - - private static final Collection uris = Collections.unmodifiableList( Arrays.asList( - ProjectUri.DependencyManagement.Dependencies.Dependency.xUri, - ProjectUri.Dependencies.Dependency.xUri, - ProjectUri.Reporting.Plugins.Plugin.xUri, - ProjectUri.Build.PluginManagement.Plugins.Plugin.xUri, - ProjectUri.Build.Plugins.Plugin.xUri, - ProjectUri.Build.Extensions.Extension.xUri - ) ); - - private final Collection u; - - public Collection getUris() - { - return u; - } - - public ArtifactModelContainerFactory() { - u = uris; - } - - public ArtifactModelContainerFactory(String uri) { - u = Collections.unmodifiableList( Arrays.asList(uri) ); - } - - public ModelContainer create( List modelProperties ) - { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new ArtifactModelContainer( modelProperties ); - } - - private static class ArtifactModelContainer - implements ModelContainer - { - - private String groupId; - - private String artifactId; - - private String version; - - private String type; - - private String scope; - - private String classifier; - - private String uri; - - private List properties; - - private static String findBaseUriFrom( List modelProperties ) - { - String baseUri = null; - for ( ModelProperty mp : modelProperties ) - { - if ( baseUri == null || mp.getUri().length() < baseUri.length() ) - { - baseUri = mp.getUri(); - } - } - return baseUri; - } - - private ArtifactModelContainer( List properties ) - { - this.properties = new ArrayList( properties ); - this.properties = Collections.unmodifiableList( this.properties ); - uri = findBaseUriFrom( this.properties ); - - for ( ModelProperty mp : this.properties ) - { - if ( version == null && mp.getUri().equals( uri + "/version" ) ) - { - this.version = mp.getResolvedValue(); - } - else if ( artifactId == null && mp.getUri().equals( uri + "/artifactId" ) ) - { - this.artifactId = mp.getResolvedValue(); - } - else if ( groupId == null && mp.getUri().equals( uri + "/groupId" ) ) - { - this.groupId = mp.getResolvedValue(); - } - else if ( scope == null && mp.getUri().equals( uri + "/scope" ) ) - { - this.scope = mp.getResolvedValue(); - } - else if ( classifier == null && mp.getUri().equals( uri + "/classifier" ) ) - { - this.classifier = mp.getResolvedValue(); - } - else if ( type == null && mp.getUri().equals( ProjectUri.Dependencies.Dependency.type ) - || mp.getUri().equals(ProjectUri.DependencyManagement.Dependencies.Dependency.type) - || mp.getUri().equals(ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.Dependency.type) - || mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Dependencies.Dependency.type)) - { - this.type = mp.getResolvedValue(); - } - } - if ( groupId == null ) - { - if ( ProjectUri.Build.Plugins.Plugin.xUri.equals( uri ) - || ProjectUri.Profiles.Profile.Build.Plugins.Plugin.xUri.equals( uri ) - || ProjectUri.Build.PluginManagement.Plugins.Plugin.xUri.equals( uri ) - || ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.xUri.equals( uri ) - || ProjectUri.Reporting.Plugins.Plugin.xUri.equals( uri ) - || ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.xUri.equals( uri )) - { - groupId = "org.apache.maven.plugins"; - } - else - { - throw new IllegalArgumentException( "Properties do not contain group id. Artifact ID = " - + artifactId + ", Version = " + version ); - } - } - - if ( artifactId == null ) - { - StringBuffer sb = new StringBuffer(); - for ( ModelProperty mp : properties ) - { - sb.append( mp ).append( "\r\n" ); - } - throw new IllegalArgumentException( "Properties does not contain artifact id. Group ID = " + groupId + - ", Version = " + version + ", Base = " + uri + ":\r\n" + sb ); - } - - if ( version == null ) - { - version = ""; - } - - if ( type == null ) - { - type = "jar"; - } - - if ( classifier == null ) - { - classifier = ""; - } - - if ( scope == null || scope.equals("provided")) - { - scope = "compile"; - } - } - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - if ( modelContainer == null ) - { - throw new IllegalArgumentException( "modelContainer: null" ); - } - - if ( !( modelContainer instanceof ArtifactModelContainer ) ) - { - throw new IllegalArgumentException( "modelContainer: wrong type" ); - } - - ArtifactModelContainer c = (ArtifactModelContainer) modelContainer; - if ( c.groupId.equals( groupId ) && c.artifactId.equals( artifactId ) && c.type.equals( type ) - && c.classifier.equals( classifier )) - { - if ( uri.startsWith(ProjectUri.Build.Plugins.xUri) || c.version.equals( version ) - || version.equals("") || c.version.equals("")) - { - return ModelContainerAction.JOIN; - } - else - { - return ModelContainerAction.DELETE; - } - } - return ModelContainerAction.NOP; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new ArtifactModelContainer( modelProperties ); - } - - public List getProperties() - { - return properties; - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - sb.append( "Group ID = " ).append( groupId ).append( ", Artifact ID = " ).append( artifactId ) - .append( ", Version" ).append( version ).append( "\r\n" ); - for ( ModelProperty mp : properties ) - { - sb.append( mp ).append( "\r\n" ); - } - return sb.toString(); - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ExclusionModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ExclusionModelContainerFactory.java deleted file mode 100644 index 795ff555a7..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/ExclusionModelContainerFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.apache.maven.project.builder.factories; - -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.*; - -public class ExclusionModelContainerFactory implements ModelContainerFactory -{ - - private static final Collection uris = Collections.unmodifiableList( Arrays.asList( - - ProjectUri.Dependencies.Dependency.Exclusions.Exclusion.xUri - - ) ); - - public Collection getUris() - { - return uris; - } - - public ModelContainer create( List modelProperties ) - { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new ExclusionModelContainer( modelProperties ); - } - - private static class ExclusionModelContainer - implements ModelContainer - { - - public ExclusionModelContainer(List properties) { - this.properties = properties; - } - - private List properties; - - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - throw new UnsupportedOperationException(); - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new ExclusionModelContainer( modelProperties ); - } - - public List getProperties() - { - return properties; - } - - } -} - diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/IdModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/IdModelContainerFactory.java deleted file mode 100644 index 91ed3a74d2..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/IdModelContainerFactory.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.apache.maven.project.builder.factories; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class IdModelContainerFactory - implements ModelContainerFactory -{ - - private String uri; - - public IdModelContainerFactory(String uri) - { - if(uri == null) - { - throw new IllegalArgumentException("uri: null"); - } - this.uri = uri; - } - - public static final List ID_CONTAINER_FACTORIES = - Collections.unmodifiableList(Arrays.asList(new IdModelContainerFactory(ProjectUri.PluginRepositories.PluginRepository.xUri), - new IdModelContainerFactory(ProjectUri.Repositories.Repository.xUri), - new IdModelContainerFactory(ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.xUri), - new IdModelContainerFactory(ProjectUri.Profiles.Profile.xUri), - new IdModelContainerFactory(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri))); - - public Collection getUris() - { - return Collections.unmodifiableList(Arrays.asList(uri)); - } - - public ModelContainer create( List modelProperties ) - { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new IdModelContainer( modelProperties ); - } - - private static class IdModelContainer - implements ModelContainer - { - - private String id; - - private List properties; - - private IdModelContainer( List properties ) - { - this.properties = new ArrayList( properties ); - this.properties = Collections.unmodifiableList( this.properties ); - - for ( ModelProperty mp : properties ) - { - if ( mp.getUri().endsWith( "/id" ) ) - { - this.id = mp.getResolvedValue(); - } - } - } - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - if ( modelContainer == null ) - { - throw new IllegalArgumentException( "modelContainer: null" ); - } - - if ( !( modelContainer instanceof IdModelContainer ) ) - { - throw new IllegalArgumentException( "modelContainer: wrong type" ); - } - - IdModelContainer c = (IdModelContainer) modelContainer; - if ( c.id == null || id == null ) - { - return ModelContainerAction.NOP; - } - return ( c.id.equals( id ) ) ? ModelContainerAction.JOIN : ModelContainerAction.NOP; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new IdModelContainer( modelProperties ); - } - - public List getProperties() - { - return properties; - } - - public String toString() - { - return "ID = " + id; - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginExecutionIdModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginExecutionIdModelContainerFactory.java deleted file mode 100644 index dc12e365ae..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginExecutionIdModelContainerFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.apache.maven.project.builder.factories; - -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.*; - -public class PluginExecutionIdModelContainerFactory implements ModelContainerFactory { - - private static final Collection uris = Collections.unmodifiableList(Arrays.asList( - ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri, - ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.xUri)); - - public Collection getUris() { - return uris; - } - - public ModelContainer create(List modelProperties) { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new PluginExecutionIdModelContainer( modelProperties ); - } - - private static class PluginExecutionIdModelContainer - implements ModelContainer - { - - private String id; - - private List properties; - - private PluginExecutionIdModelContainer( List properties ) - { - this.properties = new ArrayList( properties ); - this.properties = Collections.unmodifiableList( this.properties ); - - for ( ModelProperty mp : properties ) - { - if ( mp.getUri().endsWith( "/id" ) ) - { - this.id = mp.getResolvedValue(); - } - } - } - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - if ( modelContainer == null ) - { - throw new IllegalArgumentException( "modelContainer: null" ); - } - - if ( !( modelContainer instanceof PluginExecutionIdModelContainer ) ) - { - throw new IllegalArgumentException( "modelContainer: wrong type" ); - } - - PluginExecutionIdModelContainer c = (PluginExecutionIdModelContainer) modelContainer; - if ( c.id == null || id == null ) - { - return ModelContainerAction.NOP; - } - return ( c.id.equals( id ) ) ? ModelContainerAction.JOIN : ModelContainerAction.NOP; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new PluginExecutionIdModelContainer( modelProperties ); - } - - public List getProperties() - { - return properties; - } - - public String toString() - { - return "ID = " + id; - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginReportSetIdModelContainerFactory.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginReportSetIdModelContainerFactory.java deleted file mode 100644 index 5f72881c31..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/factories/PluginReportSetIdModelContainerFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.apache.maven.project.builder.factories; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.shared.model.ModelContainerFactory; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.*; - -public class PluginReportSetIdModelContainerFactory implements ModelContainerFactory { - - private static final Collection uris = Collections.unmodifiableList(Arrays.asList( - ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.xUri)); - - public Collection getUris() { - return uris; - } - - public ModelContainer create(List modelProperties) { - if ( modelProperties == null || modelProperties.size() == 0 ) - { - throw new IllegalArgumentException( "modelProperties: null or empty" ); - } - return new PluginReportSetIdModelContainer( modelProperties ); - } - - private static class PluginReportSetIdModelContainer - implements ModelContainer - { - - private String id; - - private List properties; - - private PluginReportSetIdModelContainer( List properties ) - { - this.properties = new ArrayList( properties ); - this.properties = Collections.unmodifiableList( this.properties ); - - for ( ModelProperty mp : properties ) - { - if ( mp.getUri().endsWith( "/id" ) ) - { - this.id = mp.getResolvedValue(); - } - } - } - - public ModelContainerAction containerAction( ModelContainer modelContainer ) - { - if ( modelContainer == null ) - { - throw new IllegalArgumentException( "modelContainer: null" ); - } - - if ( !( modelContainer instanceof PluginReportSetIdModelContainer ) ) - { - throw new IllegalArgumentException( "modelContainer: wrong type" ); - } - - PluginReportSetIdModelContainer c = (PluginReportSetIdModelContainer) modelContainer; - if ( c.id == null || id == null ) - { - return ModelContainerAction.NOP; - } - return ( c.id.equals( id ) ) ? ModelContainerAction.JOIN : ModelContainerAction.NOP; - } - - public ModelContainer createNewInstance( List modelProperties ) - { - return new PluginReportSetIdModelContainer( modelProperties ); - } - - public List getProperties() - { - return properties; - } - - public String toString() - { - return "ID = " + id; - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ActiveProfileMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ActiveProfileMatcher.java deleted file mode 100644 index 5618595d20..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ActiveProfileMatcher.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; - -import java.util.List; - -public interface ActiveProfileMatcher { - - /** - * If model container does not contain the activator property, must return false. - * - * @param modelContainer - * @param properties - * @return - */ - boolean isMatch(ModelContainer modelContainer, List properties); -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ByDefaultMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ByDefaultMatcher.java deleted file mode 100644 index 9e616cecc7..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ByDefaultMatcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; - -public class ByDefaultMatcher implements ActiveProfileMatcher { - - public boolean isMatch(ModelContainer modelContainer, List properties) { - if(modelContainer == null ) { - throw new IllegalArgumentException("modelContainer: null"); - } - - for(ModelProperty mp : modelContainer.getProperties()) { - if(mp.getUri().equals(ProjectUri.Profiles.Profile.Activation.activeByDefault)) { - return true; - } - } - return false; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/FileMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/FileMatcher.java deleted file mode 100644 index b8b5a49ea8..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/FileMatcher.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; -import java.util.ArrayList; -import java.io.File; - -public class FileMatcher implements ActiveProfileMatcher { - - public boolean isMatch(ModelContainer modelContainer, List properties) { - if(modelContainer == null ) { - throw new IllegalArgumentException("modelContainer: null"); - } - - List exists = new ArrayList(), missings = new ArrayList(); - - for(ModelProperty mp : modelContainer.getProperties()) { - if(mp.getUri().equals(ProjectUri.Profiles.Profile.Activation.File.exists)) { - exists.add(mp.getValue()); - } else if(mp.getUri().equals(ProjectUri.Profiles.Profile.Activation.File.missing)) { - missings.add(mp.getValue()); - } - } - - if(exists.isEmpty() && missings.isEmpty()) { - return false; - } - - for(String exist : exists) { - if(!new File(exist).exists()) { - return false; - } - } - - for(String missing : missings) { - if(new File(missing).exists()) { - return false; - } - } - - return true; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/OperatingSystemMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/OperatingSystemMatcher.java deleted file mode 100644 index 727e727107..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/OperatingSystemMatcher.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; - -public class OperatingSystemMatcher implements ActiveProfileMatcher { - - public boolean isMatch(ModelContainer modelContainer, List properties) { - if(modelContainer == null ) { - throw new IllegalArgumentException("modelContainer: null"); - } - - if(!doTest(modelContainer)) { - return false; - } - - for(InterpolatorProperty property : properties) { - if(!matches(modelContainer, property)) { - return false; - } - } - - return true; - } - - private static boolean doTest(ModelContainer modelContainer) { - for(ModelProperty mp : modelContainer.getProperties()) { - if(mp.getUri().startsWith(ProjectUri.Profiles.Profile.Activation.Os.xUri)) { - return true; - } - } - return false; - } - - private static boolean matches(ModelContainer modelContainer, InterpolatorProperty interpolatorProperty) { - String key = interpolatorProperty.getKey(); - - for(ModelProperty property : modelContainer.getProperties()) { - if((key.equals("${os.arch}") && property.getUri().equals(ProjectUri.Profiles.Profile.Activation.Os.arch)) - || (key.equals("${os.version}") && property.getUri().equals(ProjectUri.Profiles.Profile.Activation.Os.version)) - || (key.equals("${os.family}") && property.getUri().equals(ProjectUri.Profiles.Profile.Activation.Os.family)) - || (key.equals("${os.name}") && property.getUri().equals(ProjectUri.Profiles.Profile.Activation.Os.name)) ) - { - - if(property.getResolvedValue().startsWith("!")) - { - return !interpolatorProperty.getValue().equals(property.getResolvedValue()); - } - else - { - return interpolatorProperty.getValue().equals(property.getResolvedValue()); - } - - } - } - return true; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileContext.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileContext.java deleted file mode 100644 index 001f30423e..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileContext.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.*; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.*; - - -public class ProfileContext { - - private ModelDataSource modelDataSource; - - private List properties; - - private Collection activeProfileIds; - - private Collection inactiveProfileIds; - - private ActiveProfileMatcher defaultMatcher = new ByDefaultMatcher(); - - private List matchers = Collections.unmodifiableList( Arrays.asList( - new FileMatcher(), new JdkMatcher(), new OperatingSystemMatcher(), new PropertyMatcher() - ) ); - - public ProfileContext( ModelDataSource modelDataSource, Collection activeProfileIds, - Collection inactiveProfileIds, List properties ) - { - this.modelDataSource = modelDataSource; - this.properties = new ArrayList( properties ); - this.activeProfileIds = ( activeProfileIds != null ) ? activeProfileIds : new ArrayList(); - this.inactiveProfileIds = ( inactiveProfileIds != null ) ? inactiveProfileIds : new ArrayList(); - } - - public Collection getActiveProfiles() - throws DataSourceException - { - List matchedContainers = new ArrayList(); - List defaultContainers = new ArrayList(); - - List modelContainers = modelDataSource.queryFor( ProjectUri.Profiles.Profile.xUri ); - for ( ModelContainer mc : modelContainers ) - { - String profileId = getProfileId( mc.getProperties() ); - - if ( !inactiveProfileIds.contains( profileId ) ) - { - if ( activeProfileIds.contains( profileId ) ) - { - matchedContainers.add( mc ); - } - else if ( defaultMatcher.isMatch( mc, properties ) ) - { - defaultContainers.add( mc ); - } - else - { - for ( ActiveProfileMatcher matcher : matchers ) - { - if ( matcher.isMatch( mc, properties ) ) - { - matchedContainers.add( mc ); - break; - } - } - } - } - } - - if ( matchedContainers.isEmpty() ) - { - matchedContainers = defaultContainers; - } - - return matchedContainers; - } - - private String getProfileId(List modelProperties) - { - for(ModelProperty mp : modelProperties) - { - if(mp.getUri().equals(ProfileUri.Profiles.Profile.id)) - { - return mp.getResolvedValue(); - } - } - return null; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileUri.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileUri.java deleted file mode 100644 index 124782aca3..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/ProfileUri.java +++ /dev/null @@ -1,178 +0,0 @@ -package org.apache.maven.project.builder.profile; - - -public class ProfileUri { - - public static class Profiles - { - public static String xUri = "http://apache.org/maven/project/profiles#collection"; - - public static class Profile - { - public static String xUri = "http://apache.org/maven/project/profiles#collection/profile"; - - public static String id = "http://apache.org/maven/project/profiles#collection/profile/id"; - - public static class Activation - { - public static String xUri = "http://apache.org/maven/profiles#collection/profile/activation"; - - public static String activeByDefault = - "http://apache.org/maven/profiles#collection/profile/activation/activeByDefault"; - - public static String jdk = "http://apache.org/maven/profiles#collection/profile/activation/jdk"; - - public static class Os - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/activation/os"; - - public static String name = - "http://apache.org/maven/profiles#collection/profile/activation/os/name"; - - public static String family = - "http://apache.org/maven/profiles#collection/profile/activation/os/family"; - - public static String arch = - "http://apache.org/maven/profiles#collection/profile/activation/os/arch"; - - public static String version = - "http://apache.org/maven/profiles#collection/profile/activation/os/version"; - } - - public static class Property - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/activation/property"; - - public static String name = - "http://apache.org/maven/profiles#collection/profile/activation/property/name"; - - public static String value = - "http://apache.org/maven/profiles#collection/profile/activation/property/value"; - } - - public static class File - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/activation/file"; - - public static String missing = - "http://apache.org/maven/profiles#collection/profile/activation/file/missing"; - - public static String exists = - "http://apache.org/maven/profiles#collection/profile/activation/file/exists"; - } - } - - public static class Repositories - { - public static String xUri = "http://apache.org/maven/profiles#collection/profile/repositories"; - - public static class Repository - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/repositories/repository"; - - public static class Releases - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/releases"; - - public static String enabled = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/releases/enabled"; - - public static String updatePolicy = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/releases/updatePolicy"; - - public static String checksumPolicy = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/releases/checksumPolicy"; - } - - public static class Snapshots - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/snapshots"; - - public static String enabled = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/snapshots/enabled"; - - public static String updatePolicy = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/snapshots/updatePolicy"; - - public static String checksumPolicy = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/snapshots/checksumPolicy"; - } - - public static String id = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/id"; - - public static String name = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/name"; - - public static String url = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/url"; - - public static String layout = - "http://apache.org/maven/profiles#collection/profile/repositories/repository/layout"; - } - } - - public static class PluginRepositories - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories"; - - public static class PluginRepository - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository"; - - public static class Releases - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/releases"; - - public static String enabled = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/releases/enabled"; - - public static String updatePolicy = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/releases/updatePolicy"; - - public static String checksumPolicy = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/releases/checksumPolicy"; - } - - public static class Snapshots - { - public static String xUri = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/snapshots"; - - public static String enabled = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/snapshots/enabled"; - - public static String updatePolicy = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/snapshots/updatePolicy"; - - public static String checksumPolicy = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/snapshots/checksumPolicy"; - } - - public static String id = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/id"; - - public static String name = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/name"; - - public static String url = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/url"; - - public static String layout = - "http://apache.org/maven/profiles#collection/profile/pluginRepositories/pluginRepository/layout"; - } - } - - public static String properties = "http://apache.org/maven/profiles#collection/profile/properties"; - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/PropertyMatcher.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/PropertyMatcher.java deleted file mode 100644 index f968d2a16c..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/profile/PropertyMatcher.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; - -public class PropertyMatcher implements ActiveProfileMatcher { - - public boolean isMatch(ModelContainer modelContainer, List properties) { - - if (modelContainer == null) { - throw new IllegalArgumentException("modelContainer: null"); - } - - String name = null, value = null; - - for(ModelProperty mp : modelContainer.getProperties()) { - if(mp.getUri().equals(ProjectUri.Profiles.Profile.Activation.Property.name)) { - name = mp.getValue(); - } else if(mp.getUri().equals(ProjectUri.Profiles.Profile.Activation.Property.value)) { - value = mp.getValue(); - } - } - - if(name == null ) - { - return false; - } - - if(value == null) - { - return !name.startsWith("!"); - } - - for(InterpolatorProperty ip : properties) { - if(ip.getKey().equals("${" + name + "}")) { - return ip.getValue().equals(value); - } - } - - return false; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultDependencyScopeTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultDependencyScopeTransformerRule.java deleted file mode 100644 index c89db8e7de..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultDependencyScopeTransformerRule.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelDataSource; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; -import org.apache.maven.project.builder.TransformerRule; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; -import java.util.Arrays; - - -/** - * If no scope is found in most specialized model, then set scope to compile. - */ -public class DefaultDependencyScopeTransformerRule implements TransformerRule -{ - public void execute(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - if(isMostSpecialized) - { - ModelDataSource s = new DefaultModelDataSource( modelProperties, Arrays.asList( new ArtifactModelContainerFactory()) ); - for(ModelContainer mc : s.queryFor(ProjectUri.Dependencies.Dependency.xUri)) - { - boolean containsScope = false; - for(ModelProperty mp :mc.getProperties()) - { - if(mp.getUri().equals(ProjectUri.Dependencies.Dependency.scope)) { - containsScope = true; - break; - } - } - - if(!containsScope) - { - modelProperties.add(modelProperties.indexOf(mc.getProperties().get(0)) + 1, - new ModelProperty(ProjectUri.Dependencies.Dependency.scope, "compile")); - } - } - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultExecutionIdTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultExecutionIdTransformerRule.java deleted file mode 100644 index 352dc5f237..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DefaultExecutionIdTransformerRule.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.TransformerRemovalRule; - -import java.util.List; -import java.util.ArrayList; - -/** - * Removes any plugin execution id that has a value of "default-execution-id": (mng-3965) - */ -public class DefaultExecutionIdTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List replace = new ArrayList(); - for(ModelProperty mp : modelProperties) - { - if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.id) - && mp.getResolvedValue() != null && mp.getResolvedValue().equals("default-execution-id")) { - replace.add(mp); - } - } - return replace; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyManagementDataSourceRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyManagementDataSourceRule.java deleted file mode 100644 index 46177b2aa9..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyManagementDataSourceRule.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.DataSourceRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.shared.model.*; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; - -import java.util.Collections; -import java.util.Arrays; -import java.util.List; -import java.util.ArrayList; - -/** - * Transform Dependency Management section of pom into dependency section - */ -public class DependencyManagementDataSourceRule implements DataSourceRule -{ - public void execute(ModelDataSource source) throws DataSourceException - { - for ( ModelContainer dependencyContainer : source.queryFor( ProjectUri.Dependencies.Dependency.xUri ) ) - { - for ( ModelContainer managementContainer : source.queryFor( - ProjectUri.DependencyManagement.Dependencies.Dependency.xUri ) ) - { - //Join Duplicate Exclusions TransformerRule (MNG-4010) - ModelDataSource exclusionSource = new DefaultModelDataSource(managementContainer.getProperties(), - Collections.unmodifiableList(Arrays.asList(new ArtifactModelContainerFactory(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.Exclusion.xUri)))); - List exclusionContainers = - exclusionSource.queryFor(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.Exclusion.xUri); - - for(ModelContainer mc : exclusionContainers) - { - for(ModelContainer mc1 : exclusionContainers) - { - if(!mc.equals(mc1) && mc.containerAction(mc1).equals(ModelContainerAction.JOIN)) - { - exclusionSource.joinWithOriginalOrder(mc1, mc); - } - } - } - - managementContainer = new ArtifactModelContainerFactory().create( - transformDependencyManagement( exclusionSource.getModelProperties() ) ); - ModelContainerAction action = dependencyContainer.containerAction( managementContainer ); - if ( action.equals( ModelContainerAction.JOIN ) || action.equals( ModelContainerAction.DELETE ) ) - { - source.join( dependencyContainer, managementContainer ); - } - } - } - } - - private static List transformDependencyManagement( List modelProperties ) - { - List transformedProperties = new ArrayList(); - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.DependencyManagement.xUri ) ) - { - transformedProperties.add( new ModelProperty( - mp.getUri().replace( ProjectUri.DependencyManagement.xUri, ProjectUri.xUri ), mp.getResolvedValue() ) ); - } - } - return transformedProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyRule.java deleted file mode 100644 index 7c5a9f651c..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DependencyRule.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.ModelContainerRule; -import org.apache.maven.shared.model.ModelProperty; - -import java.util.List; -import java.util.ArrayList; - -public class DependencyRule implements ModelContainerRule { - public List execute(List modelProperties) { - List properties = new ArrayList(modelProperties); - List goalProperties = new ArrayList(); - List processedProperties = new ArrayList(); - - return processedProperties; - - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DuplicateFiltersTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DuplicateFiltersTransformerRule.java deleted file mode 100644 index bc1ce0bf72..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/DuplicateFiltersTransformerRule.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; -import java.util.ArrayList; - -public class DuplicateFiltersTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removedProperties = new ArrayList(); - List filters = new ArrayList(); - for(ModelProperty mp : modelProperties) - { - if(mp.getUri().equals(ProjectUri.Build.Filters.filter)) - { - if(filters.contains(mp.getResolvedValue())) - { - removedProperties.add(mp); - } - else - { - filters.add(mp.getResolvedValue()); - } - } - } - return removedProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ExecutionRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ExecutionRule.java deleted file mode 100644 index 612072d811..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ExecutionRule.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.*; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; -import java.util.ArrayList; -import java.util.Collections; - -public class ExecutionRule implements ModelContainerRule { - - public List execute(List modelProperties) { - List properties = new ArrayList(modelProperties); - List goalProperties = new ArrayList(); - List processedProperties = new ArrayList(); - - for(ModelProperty mp : properties) { - if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal)) { - goalProperties.add(mp); - } else if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI)) { - if(!containsProperty(mp, processedProperties)) { - processedProperties.add(mp); - } - } else { - processedProperties.add(mp); - } - } - - //Remove duplicate collections - List c = new ArrayList(); - boolean x = false; - for(ModelProperty mp : processedProperties) { - if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.configuration)) { - if(x) { - c.add(mp); - } else { - x = true; - } - - } - } - - processedProperties.removeAll(c); - - if(!goalProperties.isEmpty()) { - Collections.reverse(goalProperties); - List uniqueGoals = new ArrayList(); - for(ModelProperty mp : goalProperties) { - if(!containsProperty(mp, uniqueGoals)) { - uniqueGoals.add(mp); - } - } - Collections.reverse(uniqueGoals); - - processedProperties.addAll( - findIndexOf(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI, processedProperties) + 1, - uniqueGoals); - } - - List emptyTags = new ArrayList(); - for(ModelProperty mp : processedProperties) { - if(mp.getUri().equals(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI) - && mp.getResolvedValue() != null && mp.getResolvedValue().trim().equals("")) { - emptyTags.add(mp); - } - } - processedProperties.removeAll(emptyTags); - - return processedProperties; - } - - - private static int findIndexOf(String uri, List modelProperties) { - for(ModelProperty mp : modelProperties) { - if(mp.getUri().equals(uri)) { - return modelProperties.indexOf(mp); - } - } - return -1; - } - - private static boolean containsProperty(ModelProperty modelProperty, List modelProperties) { - for (ModelProperty mp : modelProperties) { - if ((mp.getUri().equals(modelProperty.getUri()))) { - boolean b = (mp.getResolvedValue() == null && modelProperty.getResolvedValue() == null) || - (mp.getResolvedValue() != null && !mp.getResolvedValue().trim().equals("") - && mp.getResolvedValue().equals(modelProperty.getResolvedValue())); - /* - boolean b = (mp.getResolvedValue() == null && modelProperty.getResolvedValue() == null) || - (mp.getResolvedValue() != null && modelProperty.getResolvedValue() != null - && mp.getResolvedValue().equals(modelProperty.getResolvedValue())); - */ - if(b) { - return true; - } - } - } - return false; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingGroupIdTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingGroupIdTransformerRule.java deleted file mode 100644 index 222c2a27f7..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingGroupIdTransformerRule.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; -import static org.apache.maven.project.builder.PomTransformer.getPropertyFor; - -import java.util.List; - -/** - * If the groupId is missing, add it using the value of the parent groupId. - */ -public class MissingGroupIdTransformerRule implements TransformerRule -{ - public void execute(List modelProperties, boolean isMostSpecialized) throws DataSourceException - { - if ( getPropertyFor( ProjectUri.groupId, modelProperties ) == null ) - { - ModelProperty parentGroupId = getPropertyFor( ProjectUri.Parent.groupId, modelProperties ); - if ( parentGroupId != null ) - { - modelProperties.add( new ModelProperty( ProjectUri.groupId, parentGroupId.getResolvedValue() ) ); - } - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingVersionTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingVersionTransformerRule.java deleted file mode 100644 index 25031320d3..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/MissingVersionTransformerRule.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.project.builder.TransformerRule; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.ProjectUri; - -import java.util.List; - -/** - * If model does not have version, then find the parent version and use it - */ -public class MissingVersionTransformerRule implements TransformerRule -{ - public void execute(List modelProperties, boolean isMostSpecialized) throws DataSourceException - { - if ( PomTransformer.getPropertyFor( ProjectUri.version, modelProperties ) == null ) - { - ModelProperty parentVersion = PomTransformer.getPropertyFor( ProjectUri.Parent.version, modelProperties ); - if ( parentVersion != null ) - { - modelProperties.add( new ModelProperty( ProjectUri.version, parentVersion.getResolvedValue() ) ); - } - } - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ModulesNotInheritedTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ModulesNotInheritedTransformerRule.java deleted file mode 100644 index 03a23c8738..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/ModulesNotInheritedTransformerRule.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; -import java.util.ArrayList; - -/** - * If the model is not the least child and has a module element, remove it. - */ -public class ModulesNotInheritedTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - if (!isMostSpecialized) - { - ModelProperty modulesProperty = PomTransformer.getPropertyFor(ProjectUri.Modules.xUri, modelProperties); - if (modulesProperty != null) - { - modelProperties.remove(modulesProperty); - modelProperties.removeAll(PomTransformer.getPropertiesFor(ProjectUri.Modules.module, modelProperties)); - } - } - return new ArrayList();//todo: fix - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NameNotInheritedTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NameNotInheritedTransformerRule.java deleted file mode 100644 index 07897528e1..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NameNotInheritedTransformerRule.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; -import java.util.ArrayList; - -/** - * Do not inherit the name attribute of the pom - */ -public class NameNotInheritedTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removedProperties = new ArrayList(); - if ( !isMostSpecialized ) - { - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.name ) ) - { - removedProperties.add( mp ); - return removedProperties; - } - } - } - return removedProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginExecutionTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginExecutionTransformerRule.java deleted file mode 100644 index 63ae156ec7..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginExecutionTransformerRule.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.project.builder.factories.PluginExecutionIdModelContainerFactory; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.ModelDataSource; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * If plugin execution inherited property is false, do not inherit the execution - */ -public class NotInheritedPluginExecutionTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removeProperties = new ArrayList(); - - if ( !isMostSpecialized) - { - ModelDataSource source = new DefaultModelDataSource( modelProperties, Arrays.asList( - new ArtifactModelContainerFactory(), new PluginExecutionIdModelContainerFactory() )); - List containers = - source.queryFor( ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri ); - for ( ModelContainer container : containers ) - { - for ( ModelProperty mp : container.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.Executions.Execution.inherited ) && - mp.getResolvedValue() != null && mp.getResolvedValue().equals( "false" ) ) - { - removeProperties.addAll( container.getProperties() ); - for ( int j = modelProperties.indexOf( mp ); j >= 0; j-- ) - { - if ( modelProperties.get( j ).getUri().equals( ProjectUri.Build.Plugins.Plugin.Executions.xUri ) ) - { - removeProperties.add( modelProperties.get( j ) ); - break; - } - } - break; - } - } - } - } - return removeProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginTransformerRule.java deleted file mode 100644 index 210e30a705..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/NotInheritedPluginTransformerRule.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.ModelDataSource; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; - -import java.util.List; -import java.util.ArrayList; - -/** - * If plugin inherited element value is false, do not inherit the plugin. - */ -public class NotInheritedPluginTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removeProperties = new ArrayList(); - if ( !isMostSpecialized) - { - ModelDataSource source = new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - List containers = source.queryFor( ProjectUri.Build.Plugins.Plugin.xUri ); - for ( ModelContainer container : containers ) - { - for ( ModelProperty mp : container.getProperties() ) - { - if ( mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.inherited ) && mp.getResolvedValue() != null && - mp.getResolvedValue().equals( "false" ) ) - { - removeProperties.addAll( container.getProperties() ); - for ( int j = modelProperties.indexOf( mp ); j >= 0; j-- ) - { - if ( modelProperties.get( j ).getUri().equals( ProjectUri.Build.Plugins.Plugin.xUri ) ) - { - removeProperties.add( modelProperties.get( j ) ); - break; - } - } - break; - } - } - } - } - return removeProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/OverideConfigTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/OverideConfigTransformerRule.java deleted file mode 100644 index 948b5e9de5..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/OverideConfigTransformerRule.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.JoinRule; -import org.apache.maven.project.builder.factories.ArtifactModelContainerFactory; -import org.apache.maven.shared.model.*; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; - -import java.util.List; -import java.util.ArrayList; - -/** - * - */ -public class OverideConfigTransformerRule implements JoinRule -{ - public List execute(List modelProperties) throws DataSourceException - { - ModelDataSource source = new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - List reportContainers = source.queryFor( ProjectUri.Reporting.Plugins.Plugin.xUri ); - for ( ModelContainer pluginContainer : source.queryFor( ProjectUri.Build.Plugins.Plugin.xUri ) ) - { - ModelContainer transformedReportContainer = new ArtifactModelContainerFactory().create( - transformPlugin( pluginContainer.getProperties() ) ); - - for(ModelContainer reportContainer : reportContainers) { - ModelContainerAction action = transformedReportContainer.containerAction( reportContainer ); - if ( action.equals( ModelContainerAction.JOIN ) ) - { - source.join( transformedReportContainer, reportContainer ); - break; - } - } - } - - return source.getModelProperties(); - } - - private static List transformPlugin( List modelProperties ) - { - List transformedProperties = new ArrayList(); - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.Build.Plugins.xUri ) ) - { if(mp.getUri().startsWith(ProjectUri.Build.Plugins.Plugin.configuration) - || mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.groupId) - || mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.artifactId) - || mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.version) - || mp.getUri().equals( ProjectUri.Build.Plugins.Plugin.xUri ) ) - { - transformedProperties.add( new ModelProperty( - mp.getUri().replace( ProjectUri.Build.Plugins.xUri, ProjectUri.Reporting.Plugins.xUri ), - mp.getResolvedValue() ) ); - } - - } - } - return transformedProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/PackagingNotInheritedTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/PackagingNotInheritedTransformerRule.java deleted file mode 100644 index 0a2a9873e3..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/PackagingNotInheritedTransformerRule.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; -import java.util.ArrayList; - -public class PackagingNotInheritedTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removedProperties = new ArrayList(); - if ( !isMostSpecialized ) - { - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.packaging ) ) - { - removedProperties.add( mp ); - return removedProperties; - } - } - } - return removedProperties; - } -} diff --git a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/RelativePathNotInheritedTransformerRule.java b/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/RelativePathNotInheritedTransformerRule.java deleted file mode 100644 index 36f9add5f2..0000000000 --- a/maven-project-builder/src/main/java/org/apache/maven/project/builder/rules/RelativePathNotInheritedTransformerRule.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.project.builder.TransformerRemovalRule; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.DataSourceException; - -import java.util.List; -import java.util.ArrayList; - -/** - * The relativePath element is not inherited. - */ -public class RelativePathNotInheritedTransformerRule implements TransformerRemovalRule -{ - public List executeWithReturnPropertiesToRemove(List modelProperties, boolean isMostSpecialized) - throws DataSourceException - { - List removedProperties = new ArrayList(); - if ( !isMostSpecialized ) - { - for ( ModelProperty mp : modelProperties ) - { - if ( mp.getUri().startsWith( ProjectUri.Parent.relativePath ) ) - { - removedProperties.add( mp ); - return removedProperties; - } - } - } - return removedProperties; - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModel.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModel.java deleted file mode 100644 index 077d3df6d2..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModel.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.InputStreamDomainModel; - -import java.util.List; -import java.io.IOException; -import java.io.File; -import java.io.InputStream; - -public class DefaultDomainModel extends PomClassicDomainModel { - - private List modelProperties; - - public DefaultDomainModel(List modelProperties, boolean isMostSpecialized) { - super( modelProperties, isMostSpecialized); - this.modelProperties = modelProperties; - } - - public List getModelProperties() throws IOException { - return modelProperties; - } - - public String getEventHistory() { - return ""; - } - - public void setEventHistory(String s) { - - } - - public boolean isPomInBuild() { - return false; - } - - public File getProjectDirectory() { - return null; - } - - public InputStream getInputStream() { - return null; - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModelFactory.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModelFactory.java deleted file mode 100644 index da3814e2d9..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/DefaultDomainModelFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.DomainModelFactory; -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.ModelProperty; - -import java.util.List; -import java.io.IOException; - -public class DefaultDomainModelFactory implements DomainModelFactory { - public DomainModel createDomainModel(List modelProperties) throws IOException { - return new DefaultDomainModel(modelProperties, false); - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/EnforcerPomTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/EnforcerPomTest.java deleted file mode 100644 index 8583c03d3a..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/EnforcerPomTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.apache.maven.project.builder; - -import org.apache.maven.shared.model.*; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.io.IOException; - -import static org.junit.Assert.*; - -public class EnforcerPomTest -{ - @org.junit.Test - public void dependencyManagementWithScopeAndClassifier() throws IOException - { - List mp = new ArrayList(); - mp.add(new ModelProperty(ProjectUri.xUri, null)); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.xUri, null)); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.xUri, null)); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.xUri, null)); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.groupId, "gid")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.artifactId, "aid")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.version, "v1")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.scope, "test")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.classifier, "tests")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.xUri, null)); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.groupId, "gid")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.artifactId, "aid")); - mp.add(new ModelProperty(ProjectUri.DependencyManagement.Dependencies.Dependency.version, "v1")); - - List mp2 = new ArrayList(); - mp2.add(new ModelProperty(ProjectUri.xUri, null)); - mp2.add(new ModelProperty(ProjectUri.Dependencies.xUri, null)); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.xUri, null)); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.groupId, "gid")); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.artifactId, "aid")); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.xUri, null)); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.groupId, "gid")); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.artifactId, "aid")); - mp2.add(new ModelProperty(ProjectUri.Dependencies.Dependency.classifier, "tests")); - - DomainModel childModel = new DefaultDomainModel(mp2, true); - DomainModel parentModel = new DefaultDomainModel(mp, false); - - ModelTransformerContext ctx = new ModelTransformerContext(PomTransformer.MODEL_CONTAINER_INFOS ); - - ModelTransformer transformer = new PomTransformer(new DefaultDomainModelFactory()); - DomainModel domainModel = ctx.transform( Arrays.asList(childModel, parentModel), transformer, transformer ); - - DefaultModelDataSource source = new DefaultModelDataSource( domainModel.getModelProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES); - - List containers = source.queryFor(ProjectUri.Dependencies.Dependency.xUri); - assertTrue(containers.size() == 2 ); - - ModelContainer mc0 = containers.get(0); - assertTrue(contains(ProjectUri.Dependencies.Dependency.version, "v1", mc0)); - assertFalse(contains(ProjectUri.Dependencies.Dependency.classifier, "tests", mc0)); - - ModelContainer mc1 = containers.get(1); - assertTrue(contains(ProjectUri.Dependencies.Dependency.version, "v1", mc1)); - assertTrue(contains(ProjectUri.Dependencies.Dependency.classifier, "tests", mc1)); - } - - private boolean contains(String name, String value, ModelContainer modelContainer) { - for(ModelProperty mp : modelContainer.getProperties()) { - if(mp.getUri().equals(name) && mp.getValue() != null && mp.getValue().equals(value)) { - return true; - } - } - return false; - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/PluginSpecTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/PluginSpecTest.java deleted file mode 100644 index ebefb8b46d..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/PluginSpecTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.apache.maven.project.builder; - -import static org.junit.Assert.*; -import org.apache.maven.shared.model.*; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; -import org.apache.maven.project.builder.factories.PluginExecutionIdModelContainerFactory; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.io.IOException; - -public class PluginSpecTest { - - @org.junit.Test - public void goalsInherited() throws IOException { - - List mp0 = new ArrayList(); - mp0.add(new ModelProperty(ProjectUri.xUri, null)); - mp0.add(new ModelProperty(ProjectUri.Build.xUri, null)); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.xUri, null)); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.xUri, null)); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.xUri, null)); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.groupId, "org.codehaus.modello")); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.artifactId, "modello-maven-plugin")); - mp0.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.version, "v1")); - - List mp = new ArrayList(); - mp.add(new ModelProperty(ProjectUri.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.groupId, "org.codehaus.modello")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.artifactId, "modello-maven-plugin")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.version, "v1")); - - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.id, "site-docs")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.phase, "phase")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.xURI, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal, "xdoc")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal, "xsd")); - - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.xUri, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.id, "standard")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.xURI, null)); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal, "xpp3-reader")); - mp.add(new ModelProperty(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal, "xpp3-writer")); - - DomainModel parentModel = new DefaultDomainModel(mp, false); - - ModelTransformerContext ctx = new ModelTransformerContext(PomTransformer.MODEL_CONTAINER_INFOS ); - - ModelTransformer transformer = new PomTransformer(new DefaultDomainModelFactory()); - DomainModel domainModel = ctx.transform( Arrays.asList(parentModel, new DefaultDomainModel(mp0, true)), transformer, transformer ); - - - List factories = new ArrayList(PomTransformer.MODEL_CONTAINER_FACTORIES); - factories.add(new PluginExecutionIdModelContainerFactory()); - DefaultModelDataSource source = new DefaultModelDataSource(domainModel.getModelProperties(), factories); - - List containers = source.queryFor(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.xUri); - assertTrue(2 == containers.size()); - - int numberOfGoals = 0; - for(ModelProperty x : containers.get(0).getProperties()) - { - if(x.getUri().equals(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal)) - { - numberOfGoals++; - } - } - assertTrue(numberOfGoals == 2); - - numberOfGoals = 0; - for(ModelProperty x : containers.get(1).getProperties()) - { - if(x.getUri().equals(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.goal)) - { - numberOfGoals++; - } - } - assertTrue(numberOfGoals == 2); - - // System.out.println(ModelMarshaller.unmarshalModelPropertiesToXml(domainModel.getModelProperties(), ProjectUri.baseUri)); - - - } - -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/DefaultModelContainer.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/DefaultModelContainer.java deleted file mode 100644 index d3311eb380..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/DefaultModelContainer.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelContainerAction; -import org.apache.maven.shared.model.ModelProperty; - -import java.util.ArrayList; -import java.util.List; - - -public class DefaultModelContainer implements ModelContainer -{ - - List modelProperties; - - public DefaultModelContainer(List properties) { - this.modelProperties = properties; - } - - public List getProperties() { - return new ArrayList(modelProperties); - } - - public ModelContainerAction containerAction(ModelContainer modelContainer) { - return null; - } - - public ModelContainer createNewInstance(List modelProperties) { - return null; - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/FileMatcherTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/FileMatcherTest.java deleted file mode 100644 index a64f436957..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/FileMatcherTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.project.builder.profile.FileMatcher; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -public class FileMatcherTest { - - private static String basedir = System.getProperty("basedir"); - - @org.junit.Test(expected=IllegalArgumentException.class) - public void modelContainerIsNull() { - FileMatcher matcher = new FileMatcher(); - matcher.isMatch(null, new ArrayList()); - } - - @org.junit.Test - public void fileExistActivationAndExists() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.exists , - new File(basedir, "src/test/resources/test.txt").getAbsolutePath())); - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - FileMatcher matcher = new FileMatcher(); - assertTrue(matcher.isMatch(modelContainer, new ArrayList())); - } - - @org.junit.Test - public void fileExistActivationButDoesNotExist() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.exists , - new File(basedir, "src/test/resources/bogus.txt").getAbsolutePath())); - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - FileMatcher matcher = new FileMatcher(); - assertFalse(matcher.isMatch(modelContainer, new ArrayList())); - } - - @org.junit.Test - public void fileMissingActivationButExists() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.missing , - new File(basedir, "src/test/resources/test.txt").getAbsolutePath())); - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - FileMatcher matcher = new FileMatcher(); - assertFalse(matcher.isMatch(modelContainer, new ArrayList())); - } - - @org.junit.Test - public void fileMissingActivationAndDoesNotExist() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.File.missing , - new File(basedir, "src/test/resources/bogus.txt").getAbsolutePath())); - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - FileMatcher matcher = new FileMatcher(); - assertTrue(matcher.isMatch(modelContainer, new ArrayList())); - } - -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/JdkMatcherTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/JdkMatcherTest.java deleted file mode 100644 index 9ad6c4c664..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/JdkMatcherTest.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.project.builder.profile.JdkMatcher; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - -public class JdkMatcherTest { - - @org.junit.Test(expected=IllegalArgumentException.class) - public void modelContainerIsNull() { - JdkMatcher matcher = new JdkMatcher(); - matcher.isMatch(null, new ArrayList()); - } - - @org.junit.Test - public void jdkVersionMatches() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "1.5")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionDoesNotMatchWithNotSymbol() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "!1.5")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(!matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionDoesMatchWithNotSymbol() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "!1.5")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.6")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - - @org.junit.Test - public void jdkVersionNotMatches() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "1.5")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.4")); - - JdkMatcher matcher = new JdkMatcher(); - assertFalse(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_ClosedEdge() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "[1.5,")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_OpenEdge() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "(1.5,")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertFalse(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_OpenEdge2() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "(1.4,")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_OpenEdgeWithPadding() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "(1.5.0,")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - @org.junit.Test - public void jdkVersionRange_OpenRightEdge() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , ", 1.6)")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_OpenRightEdge2() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , ",1.5)")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertFalse(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionRange_OpenRightEdgeWithWhiteSpace() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , ", 1.5)")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${java.specification.version}" , "1.5")); - - JdkMatcher matcher = new JdkMatcher(); - assertFalse(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void jdkVersionNotFound() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.jdk , "1.5")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - JdkMatcher matcher = new JdkMatcher(); - assertFalse(matcher.isMatch(modelContainer, new ArrayList())); - } -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/ProfileContextTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/ProfileContextTest.java deleted file mode 100644 index 01cf5dc762..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/ProfileContextTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.project.builder.profile.ProfileContext; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.DataSourceException; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; -import org.junit.Test; - -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -public class ProfileContextTest { - - @Test - public void getActiveProfiles() throws DataSourceException { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.name , "foo")); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.value , "bar")); - - DefaultModelDataSource dataSource = new DefaultModelDataSource(modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List interpolatorProperties = new ArrayList(); - interpolatorProperties.add(new InterpolatorProperty( "${foo}", "bar")); - - ProfileContext ctx = new ProfileContext(dataSource, null, null, interpolatorProperties); - - Collection profiles = ctx.getActiveProfiles(); - - assertTrue(profiles.size() == 1); - - } - - @Test - public void getActiveProfilesById() throws DataSourceException { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.id , "test")); - - DefaultModelDataSource dataSource = new DefaultModelDataSource(modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List interpolatorProperties = new ArrayList(); - - ProfileContext ctx = new ProfileContext(dataSource, Arrays.asList("test"), null, interpolatorProperties); - - Collection profiles = ctx.getActiveProfiles(); - - assertTrue(profiles.size() == 1); - - } - - @Test - public void getActiveByDefaultProfilesOnlyActivatedIfNoOtherPomProfilesAreActive() - throws DataSourceException - { - List modelProperties = new ArrayList(); - modelProperties.add( new ModelProperty( ProjectUri.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.id, "default" ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.Activation.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.Activation.activeByDefault, "true" ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.id, "explicit" ) ); - - DefaultModelDataSource dataSource = - new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List interpolatorProperties = new ArrayList(); - - ProfileContext ctx = new ProfileContext( dataSource, Arrays.asList( "explicit" ), null, interpolatorProperties ); - - Collection profiles = ctx.getActiveProfiles(); - - assertEquals( 1, profiles.size() ); - assertProperty( profiles.iterator().next().getProperties(), ProjectUri.Profiles.Profile.id, "explicit" ); - } - - @Test - public void getDeactivateProfiles() - throws DataSourceException - { - List modelProperties = new ArrayList(); - modelProperties.add( new ModelProperty( ProjectUri.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.id, "default" ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.Activation.xUri, null ) ); - modelProperties.add( new ModelProperty( ProjectUri.Profiles.Profile.Activation.activeByDefault, "true" ) ); - - DefaultModelDataSource dataSource = - new DefaultModelDataSource( modelProperties, PomTransformer.MODEL_CONTAINER_FACTORIES ); - - List interpolatorProperties = new ArrayList(); - - ProfileContext ctx = new ProfileContext( dataSource, null, Arrays.asList( "default" ), interpolatorProperties ); - - Collection profiles = ctx.getActiveProfiles(); - - assertEquals( 0, profiles.size() ); - } - - private void assertProperty( Collection properties, String uri, String value ) - { - for ( ModelProperty property : properties ) - { - if ( uri.equals( property.getUri() ) && value.equals( property.getValue() ) ) - { - return; - } - } - fail( "missing model property " + uri + " = " + value ); - } - -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/PropertyMatcherTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/PropertyMatcherTest.java deleted file mode 100644 index 1ee0590753..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/profile/PropertyMatcherTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.apache.maven.project.builder.profile; - -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelProperty; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.List; - - -public class PropertyMatcherTest { - - @org.junit.Test - public void propertyMatches() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.name , "foo")); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.value , "bar")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${foo}" , "bar")); - - PropertyMatcher matcher = new PropertyMatcher(); - assertTrue(matcher.isMatch(modelContainer, props)); - } - - @org.junit.Test - public void propertyDoesNotMatch() { - List modelProperties = new ArrayList(); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.xUri, null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.xUri , null)); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.name , "foo")); - modelProperties.add(new ModelProperty(ProjectUri.Profiles.Profile.Activation.Property.value , "bars")); - - ModelContainer modelContainer = new DefaultModelContainer(modelProperties); - - List props = new ArrayList(); - props.add(new InterpolatorProperty("${foo}" , "bar")); - - PropertyMatcher matcher = new PropertyMatcher(); - assertFalse(matcher.isMatch(modelContainer, props)); - } - -} diff --git a/maven-project-builder/src/test/java/org/apache/maven/project/builder/rules/ExecutionRuleTest.java b/maven-project-builder/src/test/java/org/apache/maven/project/builder/rules/ExecutionRuleTest.java deleted file mode 100644 index 69aeacb0b2..0000000000 --- a/maven-project-builder/src/test/java/org/apache/maven/project/builder/rules/ExecutionRuleTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.maven.project.builder.rules; - -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.project.builder.ProjectUri; - -import java.io.IOException; -import java.util.List; -import java.util.Arrays; - -public class ExecutionRuleTest { - - @org.junit.Test - public void execute() throws IOException - { - List modelProperties = Arrays.asList( - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.xUri, null), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI, null), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "parent-a"), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "merged"), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "parent-b"), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI, null), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "child-b"), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "merged"), - new ModelProperty(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.goal, "child-a")); - - List mps = new ExecutionRule().execute(modelProperties); - for(ModelProperty mp : mps) { - //System.out.println(mp); - } - } -} diff --git a/maven-project/pom.xml b/maven-project/pom.xml index 4347fd724c..3fc8687cbb 100644 --- a/maven-project/pom.xml +++ b/maven-project/pom.xml @@ -20,16 +20,21 @@ under the License. --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-project + Maven Project + This library is used to not only read Maven project object model files, but to assemble inheritence and to retrieve remote models as required. + org.apache.maven @@ -60,83 +65,20 @@ under the License. org.codehaus.woodstox wstx-asl - - org.sonatype.spice - model-builder - org.apache.maven - maven-project-builder + maven-model-builder org.apache.maven maven-repository - commons-jxpath - commons-jxpath + commons-jxpath + commons-jxpath - - - org.apache.maven - maven-repository - ${project.version} - test-jar - test - - - - org.sonatype.plexus - plexus-jetty6 - test - - - - org.sonatype.spice - plexus-webdav - test - - - - org.apache.maven.mercury - mercury-util - test - - - - org.apache.maven.mercury - mercury-logging - ${mercuryVersion} - test - - - - org.apache.maven.mercury - mercury-event - ${mercuryVersion} - test - - - - commons-cli - commons-cli - test - - - - org.apache.maven.mercury - mercury-crypto-basic - ${mercuryVersion} - test - - - - org.apache.maven.wagon - wagon-http-lightweight - test - - + @@ -152,16 +94,6 @@ under the License. org.codehaus.plexus plexus-component-metadata - - org.codehaus.modello - modello-maven-plugin - - 1.0.0 - - src/main/mdo/profiles.mdo - - - diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index 93da118aa6..59433176dc 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -15,25 +15,17 @@ package org.apache.maven.project; * the License. */ -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; +import java.util.Properties; + import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; @@ -44,33 +36,25 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.model.Build; +import org.apache.maven.model.DomainModel; import org.apache.maven.model.Model; +import org.apache.maven.model.ModelEventListener; +import org.apache.maven.model.PomClassicDomainModel; +import org.apache.maven.model.ProcessorContext; import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.Interpolator; +import org.apache.maven.model.interpolator.InterpolatorProperty; +import org.apache.maven.model.interpolator.PomInterpolatorTag; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; import org.apache.maven.profiles.DefaultProfileManager; -import org.apache.maven.profiles.ProfileActivationContext; import org.apache.maven.profiles.ProfileActivationException; +import org.apache.maven.profiles.ProfileManagerInfo; import org.apache.maven.profiles.ProfileManager; import org.apache.maven.project.artifact.InvalidDependencyVersionException; -import org.apache.maven.project.builder.PomClassicDomainModel; -import org.apache.maven.project.builder.PomClassicDomainModelFactory; -import org.apache.maven.project.builder.PomInterpolatorTag; -import org.apache.maven.project.builder.PomTransformer; -import org.apache.maven.project.builder.ProjectUri; -import org.apache.maven.project.builder.profile.ProfileContext; import org.apache.maven.project.validation.ModelValidationResult; import org.apache.maven.project.validation.ModelValidator; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.VersionNotFoundException; -import org.apache.maven.shared.model.DomainModel; -import org.apache.maven.shared.model.InterpolatorProperty; -import org.apache.maven.shared.model.ModelContainer; -import org.apache.maven.shared.model.ModelEventListener; -import org.apache.maven.shared.model.ModelMarshaller; -import org.apache.maven.shared.model.ModelProperty; -import org.apache.maven.shared.model.ModelTransformerContext; -import org.apache.maven.shared.model.impl.DefaultModelDataSource; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; @@ -78,10 +62,6 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.WriterFactory; -import org.codehaus.plexus.util.xml.pull.MXSerializer; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.codehaus.plexus.util.xml.pull.XmlSerializer; /** * @version $Id$ @@ -99,12 +79,12 @@ public class DefaultMavenProjectBuilder @Requirement private RepositorySystem repositorySystem; - @Requirement - private PlexusContainer container; - @Requirement List listeners; + @Requirement + private Interpolator interpolator; + @Requirement private ResolutionErrorHandler resolutionErrorHandler; @@ -137,12 +117,59 @@ public class DefaultMavenProjectBuilder public MavenProject build( File pomFile, ProjectBuilderConfiguration configuration ) throws ProjectBuildingException { - MavenProject project = readModelFromLocalPath( "unknown", pomFile, configuration.getLocalRepository(), configuration.getRemoteRepositories(), configuration ); + //Do inheritance + PomClassicDomainModel domainModel; + try + { + domainModel = build( "unknown", pomFile, configuration ); + } + catch (IOException e) + { + throw new ProjectBuildingException("", "", e); + } - project.setFile( pomFile ); - - project = buildWithProfiles( project.getModel(), configuration, pomFile, project.getParentFile() ); + //Profiles + List projectProfiles; + Properties props = new Properties(); + props.putAll(configuration.getExecutionProperties()); + props.putAll(configuration.getUserProperties()); + try + { + projectProfiles = DefaultProfileManager.getActiveProfilesFrom(configuration.getGlobalProfileManager(), props, domainModel.getModel() ); + } + catch ( ProfileActivationException e ) + { + throw new ProjectBuildingException( "", "Failed to activate pom profiles."); + } + catch(IOException e) + { + throw new ProjectBuildingException( "", "Failed to activate pom profiles."); + } + + try + { + List externalProfiles = new ArrayList(); + for(Profile p : projectProfiles) + { + if(!"pom".equals(p.getSource())) + { + logger.debug("Merging profile into model (build): Model = " + domainModel.getId() + ", Profile = " + p.getId() ); + externalProfiles.add(p); + } + } + + domainModel = ProcessorContext.mergeProfilesIntoModel( externalProfiles, domainModel ); + } + catch ( IOException e ) + { + throw new ProjectBuildingException("", ""); + } + + //Interpolation + MavenProject project = interpolateDomainModel( domainModel, configuration, pomFile ); + project.setActiveProfiles( projectProfiles ); + Build build = project.getBuild(); // NOTE: setting this script-source root before path translation, because // the plugin tools compose basedir and scriptSourceRoot into a single file. @@ -150,13 +177,15 @@ public class DefaultMavenProjectBuilder project.addCompileSourceRoot( build.getSourceDirectory() ); project.addTestCompileSourceRoot( build.getTestSourceDirectory() ); project.setFile( pomFile ); - + setBuildOutputDirectoryOnParent( project ); hm.put( ArtifactUtils.artifactId( project.getGroupId(), project.getArtifactId(), "pom", project.getVersion() ), project ); - + return project; } + + // private static void setRepositoriesOn(MavenProject project, ) //!! This is used by the RR plugin public MavenProject buildFromRepository( Artifact artifact, List remoteArtifactRepositories, ArtifactRepository localRepository, boolean allowStubs ) @@ -171,18 +200,24 @@ public class DefaultMavenProjectBuilder return buildFromRepository( pomArtifact, remoteArtifactRepositories, localRepository ); } - - public MavenProject buildFromRepository( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) - throws ProjectBuildingException + + public MavenProject buildFromRepository(Artifact artifact, ProjectBuilderConfiguration configuration ) + throws ProjectBuildingException { + MavenProject project = hm.get( artifact.getId() ); if ( project != null ) { return project; } + + if(configuration.getRemoteRepositories() == null) + { + throw new IllegalArgumentException("configuration.getRemoteRepositories(): null"); + } - ArtifactResolutionRequest request = new ArtifactResolutionRequest( artifact, localRepository, remoteRepositories ); + ArtifactResolutionRequest request = new ArtifactResolutionRequest( artifact, configuration.getLocalRepository(), configuration.getRemoteRepositories() ); ArtifactResolutionResult result = repositorySystem.resolve( request ); try @@ -193,26 +228,69 @@ public class DefaultMavenProjectBuilder { throw new ProjectBuildingException( artifact.getId(), "Error resolving project artifact.", e ); } - - ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration() - .setLocalRepository( localRepository ) - .setRemoteRepositories( remoteRepositories ); - /* - if( !artifact.getFile().getName().endsWith(".pom")) + PomClassicDomainModel domainModel; + try { - throw new ProjectBuildingException("", "Invalid project extension", artifact.getFile()); - } else { - System.out.println("READ: " + artifact.getFile()); + domainModel = build( "unknown", artifact.getFile(), configuration ); + } + catch (IOException e) + { + throw new ProjectBuildingException(artifact.getId(), "Error reading project artifact.", e); } - */ - project = readModelFromLocalPath( "unknown", artifact.getFile(), config.getLocalRepository(), remoteRepositories, config ); - project = buildWithProfiles( project.getModel(), config, artifact.getFile(), project.getParentFile() ); + + List projectProfiles; + Properties props = new Properties(); + props.putAll(configuration.getExecutionProperties()); + props.putAll(configuration.getUserProperties()); + + try + { + projectProfiles = DefaultProfileManager.getActiveProfilesFrom(configuration.getGlobalProfileManager(), props, domainModel.getModel() ); + } + catch ( ProfileActivationException e ) + { + throw new ProjectBuildingException( "", "Failed to activate pom profiles."); + } + catch(IOException e) + { + throw new ProjectBuildingException( "", "Failed to activate pom profiles."); + } + + try + { + for(Profile p : projectProfiles) + { + logger.debug("Merging profile into model (buildFromRepository): Model = " + domainModel.getId() + ", Profile = " + p.getId() ); + } + + domainModel = ProcessorContext.mergeProfilesIntoModel( projectProfiles, domainModel ); + } + catch ( IOException e ) + { + throw new ProjectBuildingException("", ""); + } + project = interpolateDomainModel( domainModel, configuration, artifact.getFile() ); + project.setActiveProfiles( projectProfiles ); artifact.setFile( artifact.getFile() ); project.setVersion( artifact.getVersion() ); hm.put( artifact.getId(), project ); - return project; + return project; + } + + //TODO: Get rid of this after merge of new PluginManager code + public MavenProject buildFromRepository( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) + throws ProjectBuildingException + { + if(remoteRepositories == null) + { + throw new IllegalArgumentException("repositories: null"); + } + ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration() + .setLocalRepository( localRepository ) + .setRemoteRepositories(remoteRepositories); + return buildFromRepository(artifact, configuration); } /** @@ -268,6 +346,12 @@ public class DefaultMavenProjectBuilder .setLocalRepository( configuration.getLocalRepository() ) .setRemoteRepostories( project.getRemoteArtifactRepositories() ) .setManagedVersionMap( project.getManagedVersionMap() ); + + + if(request.getRemoteRepostories() == null) + { + request.setRemoteRepostories( new ArrayList() ); + } ArtifactResolutionResult result = repositorySystem.resolve( request ); @@ -283,49 +367,42 @@ public class DefaultMavenProjectBuilder return new MavenProjectBuildingResult( project, result ); } - - private MavenProject buildWithProfiles( Model model, ProjectBuilderConfiguration config, File projectDescriptor, File parentDescriptor ) + + private MavenProject interpolateDomainModel( PomClassicDomainModel domainModel, ProjectBuilderConfiguration config, File projectDescriptor ) throws ProjectBuildingException { + Model model; + try + { + model = domainModel.getModel(); + } + catch (IOException e) + { + throw new ProjectBuildingException("", e.getMessage()); + } + String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); + + List interpolatorProperties = new ArrayList(); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( config.getExecutionProperties(), PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( config.getUserProperties(), PomInterpolatorTag.USER_PROPERTIES.name() ) ); - ProfileActivationContext profileActivationContext; - - List projectProfiles = new ArrayList(); - ProfileManager externalProfileManager = config.getGlobalProfileManager(); - - if ( externalProfileManager != null ) + if ( config.getBuildStartTime() != null ) { + interpolatorProperties.add( new InterpolatorProperty( "${build.timestamp}", new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( config.getBuildStartTime() ), + PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); + } + try { - projectProfiles.addAll( externalProfileManager.getActiveProfiles( model ) ); + model = interpolator.interpolateDomainModel( domainModel, interpolatorProperties ).getModel(); } - catch ( ProfileActivationException e ) + catch ( IOException e ) { - throw new ProjectBuildingException( projectId, "Failed to activate external profiles.", projectDescriptor, e ); - } - profileActivationContext = externalProfileManager.getProfileActivationContext(); - } - else - { - profileActivationContext = new ProfileActivationContext( config.getExecutionProperties(), false ); - ProfileManager profileManager = new DefaultProfileManager( container, profileActivationContext ); - profileManager.addProfiles( model.getProfiles() ); - try - { - projectProfiles.addAll( profileManager.getActiveProfiles( model ) ); - } - catch ( ProfileActivationException e ) - { - throw new ProjectBuildingException( projectId, "Failed to activate external profiles.", projectDescriptor, e ); - } - } - - for ( Profile profile : projectProfiles ) - { - model = inject( profile, model ); - } + throw new ProjectBuildingException(projectId, "", projectDescriptor, e); + } + MavenProject project; @@ -338,7 +415,7 @@ public class DefaultMavenProjectBuilder Artifact projectArtifact = repositorySystem.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null, project.getPackaging() ); project.setArtifact( projectArtifact ); - project.setParentFile( parentDescriptor ); + project.setParentFile( domainModel.getParentFile() ); } catch ( InvalidRepositoryException e ) @@ -346,123 +423,113 @@ public class DefaultMavenProjectBuilder throw new InvalidProjectModelException( projectId, e.getMessage(), projectDescriptor, e ); } - project.setActiveProfiles( projectProfiles ); - return project; } - - private Model inject( Profile profile, Model model ) + + private PomClassicDomainModel build( String projectId, File pomFile, ProjectBuilderConfiguration projectBuilderConfiguration ) + throws ProjectBuildingException, IOException { - //TODO: Using reflection now. Need to replace with custom mapper - StringWriter writer = new StringWriter(); - XmlSerializer serializer = new MXSerializer(); - serializer.setProperty( "http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " " ); - serializer.setProperty( "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n" ); - try - { - serializer.setOutput( writer ); - serializer.startDocument( "UTF-8", null ); - } - catch ( IOException e ) - { + List activeProfileIds = ( projectBuilderConfiguration != null && projectBuilderConfiguration.getGlobalProfileManager() != null && projectBuilderConfiguration.getGlobalProfileManager() + .getProfileActivationContext() != null ) ? projectBuilderConfiguration.getGlobalProfileManager().getProfileActivationContext().getExplicitlyActiveProfileIds() : new ArrayList(); - } + List inactiveProfileIds = ( projectBuilderConfiguration != null && projectBuilderConfiguration.getGlobalProfileManager() != null && projectBuilderConfiguration + .getGlobalProfileManager().getProfileActivationContext() != null ) ? projectBuilderConfiguration.getGlobalProfileManager().getProfileActivationContext().getExplicitlyInactiveProfileIds() + : new ArrayList(); + + List interpolatorProperties = new ArrayList(); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( projectBuilderConfiguration.getExecutionProperties(), PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); + interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( projectBuilderConfiguration.getUserProperties(), PomInterpolatorTag.USER_PROPERTIES.name() ) ); + + ProfileManagerInfo profileInfo = new ProfileManagerInfo(interpolatorProperties, activeProfileIds, inactiveProfileIds); + PomClassicDomainModel domainModel = new PomClassicDomainModel( pomFile ); + domainModel.setProjectDirectory( pomFile.getParentFile() ); + domainModel.setMostSpecialized( true ); - try - { - MavenXpp3Writer w = new MavenXpp3Writer(); - Class c = Class.forName( "org.apache.maven.model.io.xpp3.MavenXpp3Writer" ); + List domainModels = new ArrayList(); - Class partypes[] = new Class[3]; - partypes[0] = Profile.class; - partypes[1] = String.class; - partypes[2] = XmlSerializer.class; + domainModels.add( domainModel ); + ArtifactRepository localRepository = projectBuilderConfiguration.getLocalRepository(); + List remoteRepositories = projectBuilderConfiguration.getRemoteRepositories(); - Method meth = c.getDeclaredMethod( "writeProfile", partypes ); - meth.setAccessible( true ); - - Object arglist[] = new Object[3]; - arglist[0] = profile; - arglist[1] = "profile"; - arglist[2] = serializer; - - meth.invoke( w, arglist ); - serializer.endDocument(); - } - catch ( Exception e ) - { - return null; - } - Set uris = new HashSet( PomTransformer.URIS ); - uris.add( ProjectUri.Profiles.Profile.Build.Plugins.Plugin.configuration ); - - List p; - try - { - String xml = writer.getBuffer().toString(); - p = ModelMarshaller.marshallXmlToModelProperties( new ByteArrayInputStream( xml.getBytes( "UTF-8" ) ), ProjectUri.Profiles.xUri, uris ); - } - catch ( IOException e ) - { - return null; - } - - List transformed = new ArrayList(); - for ( ModelProperty mp : p ) - { - if ( mp.getUri().startsWith( ProjectUri.Profiles.Profile.xUri ) && !mp.getUri().equals( ProjectUri.Profiles.Profile.id ) - && !mp.getUri().startsWith( ProjectUri.Profiles.Profile.Activation.xUri ) ) + File parentFile = null; + int lineageCount = 0; + if ( domainModel.getParentId() != null ) { - transformed.add( new ModelProperty( mp.getUri().replace( ProjectUri.Profiles.Profile.xUri, ProjectUri.xUri ), mp.getResolvedValue() ) ); + List mavenParents; + MavenProject topProject = projectBuilderConfiguration.getTopLevelProjectFromReactor(); + if(useTopLevelProjectForParent(domainModel, topProject) ) + { + mavenParents = getDomainModelParentsFromLocalPath( domainModel, localRepository, remoteRepositories, topProject.getFile(), projectBuilderConfiguration ); + } + else if ( isParentLocal( domainModel.getRelativePathOfParent(), pomFile.getParentFile() ) ) + { + mavenParents = getDomainModelParentsFromLocalPath( domainModel, localRepository, remoteRepositories, pomFile.getParentFile(), projectBuilderConfiguration ); + } + else + { + mavenParents = getDomainModelParentsFromRepository( domainModel, localRepository, remoteRepositories ); + } + + if ( mavenParents.size() > 0 ) + { + PomClassicDomainModel dm = (PomClassicDomainModel) mavenParents.get( 0 ); + parentFile = dm.getFile(); + domainModel.setParentFile( parentFile ); + lineageCount = mavenParents.size(); + } + + domainModels.addAll( mavenParents ); } - } - PomTransformer transformer = new PomTransformer( new PomClassicDomainModelFactory() ); - ModelTransformerContext ctx = new ModelTransformerContext( PomTransformer.MODEL_CONTAINER_INFOS ); + domainModels.add( new PomClassicDomainModel( getSuperModel(), false ) ); + List profileModels = new ArrayList(); + //Process Profiles + for(DomainModel domain : domainModels) + { + PomClassicDomainModel dm = (PomClassicDomainModel) domain; - PomClassicDomainModel transformedDomainModel; - try - { - transformedDomainModel = ( (PomClassicDomainModel) ctx.transform( Arrays.asList( new PomClassicDomainModel( transformed, false ), convertToDomainModel( model, true ) ), transformer, - transformer, Collections.EMPTY_LIST, null, null ) ); - return convertFromInputStreamToModel( transformedDomainModel.getInputStream() ); - } - catch ( IOException e ) - { - e.printStackTrace(); - return null; - } + if(!dm.getModel().getProfiles().isEmpty()) + { + Collection profiles = DefaultProfileManager.getActiveProfiles(dm.getModel().getProfiles(), profileInfo); + if(!profiles.isEmpty()) + { + for(Profile p : profiles) + { + logger.debug("Merging profile into model: Model = " + dm.getId() + ", Profile = " + p.getId() ); + } + profileModels.add(ProcessorContext.mergeProfilesIntoModel( profiles, dm )); + } + else + { + profileModels.add( dm ); + } + } + else + { + profileModels.add( dm ); + } + } + PomClassicDomainModel transformedDomainModel = ProcessorContext.build(profileModels, listeners); + + // Lineage count is inclusive to add the POM read in itself. + transformedDomainModel.setLineageCount( lineageCount + 1 ); + transformedDomainModel.setParentFile( parentFile ); + + return transformedDomainModel; } - - private MavenProject readModelFromLocalPath( String projectId, File pomFile, ArtifactRepository localRepository, List remoteRepositories, ProjectBuilderConfiguration config ) - throws ProjectBuildingException + + private static boolean useTopLevelProjectForParent(PomClassicDomainModel currentModel, MavenProject topProject) throws IOException { - List interpolatorProperties = new ArrayList(); - - interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( config.getExecutionProperties(), PomInterpolatorTag.EXECUTION_PROPERTIES.name() ) ); - - interpolatorProperties.addAll( InterpolatorProperty.toInterpolatorProperties( config.getUserProperties(), PomInterpolatorTag.USER_PROPERTIES.name() ) ); - - if ( config.getBuildStartTime() != null ) - { - interpolatorProperties.add( new InterpolatorProperty( "${build.timestamp}", new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( config.getBuildStartTime() ), - PomInterpolatorTag.PROJECT_PROPERTIES.name() ) ); - } - - MavenProject mavenProject; - - try - { - mavenProject = buildFromLocalPath( pomFile, interpolatorProperties, localRepository, remoteRepositories, config, this ); - } - catch ( IOException e ) - { - throw new ProjectBuildingException( projectId, "File = " + pomFile.getAbsolutePath(), e ); - } - - return mavenProject; + if(topProject == null || currentModel.getModel().getParent() == null) + { + return false; + } + return topProject.getGroupId().equals(currentModel.getParentGroupId()) + && topProject.getArtifactId().equals(currentModel.getParentArtifactId()) + && topProject.getVersion().equals(currentModel.getParentVersion()); + } private void validateModel( Model model, File pomFile ) @@ -477,7 +544,7 @@ public class DefaultMavenProjectBuilder { for ( String s : (List) validationResult.getMessages() ) { - logger.debug( s ); + logger.info( s ); } throw new InvalidProjectModelException( projectId, "Failed to validate POM", pomFile, validationResult ); } @@ -512,159 +579,6 @@ public class DefaultMavenProjectBuilder } } - protected PomClassicDomainModel buildModel( File pom, Collection interpolatorProperties, ArtifactRepository localRepository, List remoteRepositories ) - throws IOException - { - return buildModel( pom, interpolatorProperties, null, null, localRepository, remoteRepositories ); - } - - private PomClassicDomainModel buildModel( File pom, Collection interpolatorProperties, Collection activeProfileIds, Collection inactiveProfileIds, - ArtifactRepository localRepository, List remoteRepositories ) - throws IOException - { - if ( pom == null ) - { - throw new IllegalArgumentException( "pom: null" ); - } - - if ( activeProfileIds == null ) - { - activeProfileIds = new ArrayList(); - } - if ( inactiveProfileIds == null ) - { - inactiveProfileIds = new ArrayList(); - } - - List properties; - if ( interpolatorProperties == null ) - { - properties = new ArrayList(); - } - else - { - properties = new ArrayList( interpolatorProperties ); - } - - PomClassicDomainModel domainModel = new PomClassicDomainModel( pom ); - domainModel.setProjectDirectory( pom.getParentFile() ); - domainModel.setMostSpecialized( true ); - - List domainModels = new ArrayList(); - - //Process Profile on most specialized child model - ProfileContext profileContext = new ProfileContext( new DefaultModelDataSource( domainModel.getModelProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES ), activeProfileIds, - inactiveProfileIds, properties ); - - domainModels.addAll( transformProfiles( profileContext ) ); - domainModels.add( domainModel ); - - File parentFile = null; - int lineageCount = 0; - if ( domainModel.getParentId() != null ) - { - List mavenParents; - if ( isParentLocal( domainModel.getRelativePathOfParent(), pom.getParentFile() ) ) - { - mavenParents = getDomainModelParentsFromLocalPath( domainModel, localRepository, remoteRepositories, pom.getParentFile(), properties, activeProfileIds, inactiveProfileIds ); - } - else - { - mavenParents = getDomainModelParentsFromRepository( domainModel, localRepository, remoteRepositories, properties, activeProfileIds, inactiveProfileIds ); - } - - if ( mavenParents.size() > 0 ) - { - PomClassicDomainModel dm = (PomClassicDomainModel) mavenParents.get( 0 ); - parentFile = dm.getFile(); - domainModel.setParentFile( parentFile ); - lineageCount = mavenParents.size(); - } - - domainModels.addAll( mavenParents ); - } - - domainModels.add( convertToDomainModel( getSuperModel(), false ) ); - - PomTransformer transformer = new PomTransformer( new PomClassicDomainModelFactory() ); - - ModelTransformerContext ctx = new ModelTransformerContext( PomTransformer.MODEL_CONTAINER_INFOS ); - - PomClassicDomainModel transformedDomainModel = ( (PomClassicDomainModel) ctx.transform( domainModels, transformer, transformer, Collections.EMPTY_LIST, properties, listeners ) ); - // Lineage count is inclusive to add the POM read in itself. - transformedDomainModel.setLineageCount( lineageCount + 1 ); - transformedDomainModel.setParentFile( parentFile ); - - return transformedDomainModel; - } - - private PomClassicDomainModel convertToDomainModel( Model model, boolean isMostSpecialized ) - throws IOException - { - if ( model == null ) - { - throw new IllegalArgumentException( "model: null" ); - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Writer out = null; - MavenXpp3Writer writer = new MavenXpp3Writer(); - try - { - out = WriterFactory.newXmlWriter( baos ); - writer.write( out, model ); - } - finally - { - if ( out != null ) - { - out.close(); - } - } - return new PomClassicDomainModel( new ByteArrayInputStream( baos.toByteArray() ), isMostSpecialized ); - } - - protected MavenProject buildFromLocalPath( File pom, Collection interpolatorProperties, ArtifactRepository localRepository, List remoteRepositories, - ProjectBuilderConfiguration projectBuilderConfiguration, MavenProjectBuilder mavenProjectBuilder ) - throws IOException - { - - List activeProfileIds = ( projectBuilderConfiguration != null && projectBuilderConfiguration.getGlobalProfileManager() != null && projectBuilderConfiguration.getGlobalProfileManager() - .getProfileActivationContext() != null ) ? projectBuilderConfiguration.getGlobalProfileManager().getProfileActivationContext().getExplicitlyActiveProfileIds() : new ArrayList(); - - List inactiveProfileIds = ( projectBuilderConfiguration != null && projectBuilderConfiguration.getGlobalProfileManager() != null && projectBuilderConfiguration - .getGlobalProfileManager().getProfileActivationContext() != null ) ? projectBuilderConfiguration.getGlobalProfileManager().getProfileActivationContext().getExplicitlyInactiveProfileIds() - : new ArrayList(); - - PomClassicDomainModel domainModel = buildModel( pom, interpolatorProperties, activeProfileIds, inactiveProfileIds, localRepository, remoteRepositories ); - - try - { - MavenProject mavenProject = new MavenProject( convertFromInputStreamToModel( domainModel.getInputStream() ), repositorySystem, mavenProjectBuilder, projectBuilderConfiguration ); - - mavenProject.setParentFile( domainModel.getParentFile() ); - - return mavenProject; - } - catch ( InvalidRepositoryException e ) - { - throw new IOException( e.getMessage() ); - } - } - - private static Model convertFromInputStreamToModel( InputStream inputStream ) - throws IOException - { - try - { - return new MavenXpp3Reader().read( ReaderFactory.newXmlReader( inputStream ) ); - } - catch ( XmlPullParserException e ) - { - throw new IOException( e.getMessage() ); - } - - } - /** * Returns true if the relative path of the specified parent references a pom, otherwise returns * false. @@ -674,7 +588,7 @@ public class DefaultMavenProjectBuilder * @return true if the relative path of the specified parent references a pom, otherwise returns * fals */ - private boolean isParentLocal( String relativePath, File projectDirectory ) + private static boolean isParentLocal( String relativePath, File projectDirectory ) { try { @@ -693,15 +607,14 @@ public class DefaultMavenProjectBuilder } } - private List getDomainModelParentsFromRepository( PomClassicDomainModel domainModel, ArtifactRepository localRepository, List remoteRepositories, - List properties, Collection activeProfileIds, Collection inactiveProfileIds ) + private List getDomainModelParentsFromRepository( PomClassicDomainModel domainModel, ArtifactRepository localRepository, List remoteRepositories ) throws IOException { List domainModels = new ArrayList(); String parentId = domainModel.getParentId(); - if ( parentId == null ) + if ( parentId == null || localRepository == null) { return domainModels; } @@ -727,41 +640,12 @@ public class DefaultMavenProjectBuilder //shane: what does this mean exactly and why does it occur logger.debug( "Parent pom ids do not match: Parent File = " + artifactParent.getFile().getAbsolutePath() + ": Child ID = " + domainModel.getId() ); - return domainModels; + // return domainModels; } domainModels.add( parentDomainModel ); - //Process Profiles - ProfileContext profileContext = new ProfileContext( new DefaultModelDataSource( parentDomainModel.getModelProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES ), activeProfileIds, - inactiveProfileIds, properties ); - domainModels.addAll( transformProfiles( profileContext ) ); - - domainModels.addAll( getDomainModelParentsFromRepository( parentDomainModel, localRepository, remoteRepositories, properties, activeProfileIds, inactiveProfileIds ) ); - return domainModels; - } - - private static List transformProfiles( ProfileContext profileContext ) - throws IOException - { - List domainModels = new ArrayList(); - Collection profileContainers = profileContext.getActiveProfiles(); - - for ( ModelContainer mc : profileContainers ) - { - List transformed = new ArrayList(); - transformed.add( new ModelProperty( ProjectUri.xUri, null ) ); - for ( ModelProperty mp : mc.getProperties() ) - { - if ( mp.getUri().startsWith( ProjectUri.Profiles.Profile.xUri ) && !mp.getUri().equals( ProjectUri.Profiles.Profile.id ) - && !mp.getUri().startsWith( ProjectUri.Profiles.Profile.Activation.xUri ) ) - { - transformed.add( new ModelProperty( mp.getUri().replace( ProjectUri.Profiles.Profile.xUri, ProjectUri.xUri ), mp.getResolvedValue() ) ); - } - } - - domainModels.add( new PomClassicDomainModel( transformed ) ); - } + domainModels.addAll( getDomainModelParentsFromRepository( parentDomainModel, localRepository, remoteRepositories ) ); return domainModels; } @@ -775,8 +659,7 @@ public class DefaultMavenProjectBuilder * @throws IOException */ private List getDomainModelParentsFromLocalPath( PomClassicDomainModel domainModel, ArtifactRepository localRepository, List remoteRepositories, - File projectDirectory, List properties, Collection activeProfileIds, - Collection inactiveProfileIds ) + File projectDirectory, ProjectBuilderConfiguration projectBuilderConfiguration ) throws IOException { List domainModels = new ArrayList(); @@ -793,33 +676,21 @@ public class DefaultMavenProjectBuilder { parentFile = new File( parentFile.getAbsolutePath(), "pom.xml" ); } - - if ( !parentFile.isFile() ) + MavenProject topProject = projectBuilderConfiguration.getTopLevelProjectFromReactor(); + boolean isTop = useTopLevelProjectForParent(domainModel, topProject); + PomClassicDomainModel parentDomainModel = null; + if ( !isTop ) { - throw new IOException( "File does not exist: File = " + parentFile.getAbsolutePath() ); + if(!parentFile.isFile()) + { + throw new IOException( "File does not exist: File = " + parentFile.getAbsolutePath() ); + } + parentDomainModel = new PomClassicDomainModel( parentFile ); + parentDomainModel.setProjectDirectory( parentFile.getParentFile() ); } - - PomClassicDomainModel parentDomainModel = new PomClassicDomainModel( parentFile ); - parentDomainModel.setProjectDirectory( parentFile.getParentFile() ); - - //Process Profiles - ProfileContext profileContext = new ProfileContext( new DefaultModelDataSource( parentDomainModel.getModelProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES ), activeProfileIds, - inactiveProfileIds, properties ); - Collection profileContainers = profileContext.getActiveProfiles(); - - for ( ModelContainer mc : profileContainers ) + else { - List transformed = new ArrayList(); - transformed.add( new ModelProperty( ProjectUri.xUri, null ) ); - for ( ModelProperty mp : mc.getProperties() ) - { - if ( mp.getUri().startsWith( ProjectUri.Profiles.Profile.xUri ) && !mp.getUri().equals( ProjectUri.Profiles.Profile.id ) - && !mp.getUri().startsWith( ProjectUri.Profiles.Profile.Activation.xUri ) ) - { - transformed.add( new ModelProperty( mp.getUri().replace( ProjectUri.Profiles.Profile.xUri, ProjectUri.xUri ), mp.getResolvedValue() ) ); - } - } - domainModels.add( new PomClassicDomainModel( transformed ) ); + parentDomainModel = new PomClassicDomainModel(projectBuilderConfiguration.getTopLevelProjectFromReactor().getFile()); } if ( !parentDomainModel.matchesParentOf( domainModel ) ) @@ -827,7 +698,7 @@ public class DefaultMavenProjectBuilder logger.info( "Parent pom ids do not match: Parent File = " + parentFile.getAbsolutePath() + ", Parent ID = " + parentDomainModel.getId() + ", Child ID = " + domainModel.getId() + ", Expected Parent ID = " + domainModel.getParentId() ); - List parentDomainModels = getDomainModelParentsFromRepository( domainModel, localRepository, remoteRepositories, properties, activeProfileIds, inactiveProfileIds ); + List parentDomainModels = getDomainModelParentsFromRepository( domainModel, localRepository, remoteRepositories ); if ( parentDomainModels.size() == 0 ) { @@ -841,22 +712,30 @@ public class DefaultMavenProjectBuilder domainModels.add( parentDomainModel ); if ( domainModel.getParentId() != null ) { - if ( isParentLocal( parentDomainModel.getRelativePathOfParent(), parentFile.getParentFile() ) ) + if(isTop) + { + if ( isParentLocal( parentDomainModel.getRelativePathOfParent(), parentFile.getParentFile() ) ) + { + domainModels.addAll( getDomainModelParentsFromLocalPath( parentDomainModel, localRepository, remoteRepositories, topProject.getFile(), projectBuilderConfiguration ) ); + } + else + { + domainModels.addAll( getDomainModelParentsFromRepository( parentDomainModel, localRepository, remoteRepositories ) ); + } + } + else if ( isParentLocal( parentDomainModel.getRelativePathOfParent(), parentFile.getParentFile() ) ) { - domainModels.addAll( getDomainModelParentsFromLocalPath( parentDomainModel, localRepository, remoteRepositories, parentFile.getParentFile(), properties, activeProfileIds, - inactiveProfileIds ) ); + domainModels.addAll( getDomainModelParentsFromLocalPath( parentDomainModel, localRepository, remoteRepositories, parentFile.getParentFile(), projectBuilderConfiguration ) ); } else { - domainModels.addAll( getDomainModelParentsFromRepository( parentDomainModel, localRepository, remoteRepositories, properties, activeProfileIds, inactiveProfileIds ) ); + domainModels.addAll( getDomainModelParentsFromRepository( parentDomainModel, localRepository, remoteRepositories ) ); } } return domainModels; } - private DomainModel superDomainModel; - // Super Model Handling private static final String MAVEN_MODEL_VERSION = "4.0.0"; @@ -891,5 +770,4 @@ public class DefaultMavenProjectBuilder return superModel; } - } \ No newline at end of file diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java b/maven-project/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java index b4bb843378..8f77ab0362 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java @@ -24,8 +24,8 @@ import java.util.List; import java.util.Properties; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.model.ModelEventListener; import org.apache.maven.profiles.ProfileManager; -import org.apache.maven.shared.model.ModelEventListener; public class DefaultProjectBuilderConfiguration implements ProjectBuilderConfiguration @@ -44,6 +44,18 @@ public class DefaultProjectBuilderConfiguration private Date buildStartTime; private List listeners; + + private MavenProject topProject; + + public MavenProject getTopLevelProjectFromReactor() + { + return topProject; + } + + public void setTopLevelProjectForReactor(MavenProject mavenProject) + { + this.topProject = mavenProject; + } public ProjectBuilderConfiguration setGlobalProfileManager( ProfileManager globalProfileManager ) { diff --git a/maven-project/src/main/java/org/apache/maven/project/MavenProject.java b/maven-project/src/main/java/org/apache/maven/project/MavenProject.java index 5555f8deec..00522ff279 100644 --- a/maven-project/src/main/java/org/apache/maven/project/MavenProject.java +++ b/maven-project/src/main/java/org/apache/maven/project/MavenProject.java @@ -237,7 +237,24 @@ public class MavenProject } */ - setRemoteArtifactRepositories( projectBuilderConfiguration.getRemoteRepositories() ); + setRemoteArtifactRepositories( (projectBuilderConfiguration.getRemoteRepositories() != null) ? new ArrayList(projectBuilderConfiguration.getRemoteRepositories()) : new ArrayList()); + + for(Repository r: model.getPluginRepositories()) + { + try { + remoteArtifactRepositories.add(repositorySystem.buildArtifactRepository( r )); + } catch (InvalidRepositoryException e) { + + } + } + for(Repository r: model.getPluginRepositories()) + { + try { + remoteArtifactRepositories.add(repositorySystem.buildArtifactRepository( r )); + } catch (InvalidRepositoryException e) { + + } + } } /** @@ -331,6 +348,10 @@ public class MavenProject { if ( parent == null ) { + /* + * TODO: This is suboptimal. Without a cache in the project builder, rebuilding the parent chain currently + * causes O(n^2) parser invocations for an inheritance hierarchy of depth n. + */ if ( parentFile != null ) { try @@ -369,9 +390,9 @@ public class MavenProject public List getRemoteArtifactRepositories() { - return remoteArtifactRepositories; + return new ArrayList( remoteArtifactRepositories ); } - + public boolean hasParent() { return getParent() != null; @@ -419,21 +440,36 @@ public class MavenProject // Test and compile sourceroots. // ---------------------------------------------------------------------- - public void addCompileSourceRoot( String path ) + private void addPath( List paths, String path ) { if ( path != null ) { path = path.trim(); - if ( path.length() != 0 ) + if ( path.length() > 0 ) { - if ( !getCompileSourceRoots().contains( path ) ) + File file = new File( path ); + if ( file.isAbsolute() ) { - getCompileSourceRoots().add( path ); + path = file.getAbsolutePath(); + } + else + { + path = new File( getBasedir(), path ).getAbsolutePath(); + } + + if ( !paths.contains( path ) ) + { + paths.add( path ); } } } } + public void addCompileSourceRoot( String path ) + { + addPath( getCompileSourceRoots(), path ); + } + public void addScriptSourceRoot( String path ) { if ( path != null ) @@ -451,17 +487,7 @@ public class MavenProject public void addTestCompileSourceRoot( String path ) { - if ( path != null ) - { - path = path.trim(); - if ( path.length() != 0 ) - { - if ( !getTestCompileSourceRoots().contains( path ) ) - { - getTestCompileSourceRoots().add( path ); - } - } - } + addPath( getTestCompileSourceRoots(), path ); } public List getCompileSourceRoots() diff --git a/maven-project/src/main/java/org/apache/maven/project/MavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/MavenProjectBuilder.java index c908e3d4e1..effa4db409 100644 --- a/maven-project/src/main/java/org/apache/maven/project/MavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/MavenProjectBuilder.java @@ -40,6 +40,9 @@ public interface MavenProjectBuilder MavenProject buildFromRepository( Artifact artifact, List remoteRepositories, ArtifactRepository localRepository ) throws ProjectBuildingException; + + MavenProject buildFromRepository(Artifact artifact, ProjectBuilderConfiguration configuration ) + throws ProjectBuildingException; MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration configuration ) throws ProjectBuildingException; diff --git a/maven-project/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java b/maven-project/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java index f501cc1ac3..bef479f14b 100644 --- a/maven-project/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java +++ b/maven-project/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java @@ -33,4 +33,8 @@ public interface ProjectBuilderConfiguration Date getBuildStartTime(); ProjectBuilderConfiguration setBuildStartTime( Date buildStartTime ); + + MavenProject getTopLevelProjectFromReactor(); + + void setTopLevelProjectForReactor(MavenProject mavenProject); } diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/BaseProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/BaseProcessor.java deleted file mode 100644 index d31c65eb82..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/BaseProcessor.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.ArrayList; -import java.util.Collection; - -public abstract class BaseProcessor { - - Object parent; - - Object child; - - Collection processors; - - public BaseProcessor(Collection processors) - { - if(processors == null) - { - throw new IllegalArgumentException("processors: null"); - } - - this.processors = processors; - } - - public BaseProcessor() - { - this.processors = new ArrayList(); - } - - public void process(Object parent, Object child, Object target, boolean isChildMostSpecialized) - { - if(child == null) - { - throw new IllegalArgumentException("child: null"); - } - - if(target == null) - { - throw new IllegalArgumentException("target: null"); - } - - this.parent = parent; - this.child = child; - - for(Processor processor : processors) - { - processor.process(parent, child, target, isChildMostSpecialized); - } - - } - - public Object getChild() { - return child; - } - - public Object getParent() { - return parent; - } -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/BuildProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/BuildProcessor.java deleted file mode 100644 index a8fa42bcdc..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/BuildProcessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.Collection; - -public class BuildProcessor extends BaseProcessor -{ - public BuildProcessor(Collection processors) - { - super(processors); - } - - public void process(Object parent, Object child, Object target, boolean isChildMostSpecialized) - { - super.process(parent, child, target, isChildMostSpecialized); - - - } -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/DependenciesProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/DependenciesProcessor.java deleted file mode 100644 index b8604b0b97..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/DependenciesProcessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.List; - -import org.apache.maven.model.Dependency; - -public class DependenciesProcessor extends BaseProcessor { - /* - public void process(List parentDependencies, List childDependencies, List targetDependencies) - { - - } -*/ - public void process(Object parent, Object child, Object target, boolean sChildMostSpecialized) { - - - } -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/DependencyProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/DependencyProcessor.java deleted file mode 100644 index 1361939cd2..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/DependencyProcessor.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.apache.maven.project.processor; - -public class DependencyProcessor { - -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/ModelListener.java b/maven-project/src/main/java/org/apache/maven/project/processor/ModelListener.java deleted file mode 100644 index c0f40f7f01..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/ModelListener.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.apache.maven.project.processor; - -public interface ModelListener -{ - void register(Object xmlNode); - - void fire(Object object); - - boolean isRegistered(Object object); -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/ModelProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/ModelProcessor.java deleted file mode 100644 index 360706f4fd..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/ModelProcessor.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.Collection; - -import org.apache.maven.model.Model; -/* - * hold original pom - * Track where a property is from - */ -public class ModelProcessor extends BaseProcessor -{ - - public ModelProcessor(Collection processors) - { - super(processors); - } - - public void process(Object parent, Object child, Object target, boolean isChildMostSpecialized) - { - super.process(parent, child, target, isChildMostSpecialized); - - Model c = (Model) child; - Model t = (Model) target; - Model p = null; - if (parent != null) - { - p = (Model) parent; - } - - //Version - if(c.getVersion() == null) - { - if(c.getParent() != null) - { - t.setVersion(c.getParent().getVersion()); - } - } - else - { - t.setVersion(c.getVersion()); - } - - //GroupId - if(c.getGroupId() == null) - { - if(c.getParent() != null) - { - t.setGroupId(c.getParent().getGroupId()); - } - } - else - { - t.setGroupId(c.getGroupId()); - } - - t.setModelVersion(c.getModelVersion()); - t.setPackaging(c.getPackaging()); - - if(isChildMostSpecialized) - { - t.setName(c.getName()); - t.setDescription(c.getDescription()); - } - - } -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/ModuleProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/ModuleProcessor.java deleted file mode 100644 index 24936495bb..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/ModuleProcessor.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.ArrayList; - -import org.apache.maven.model.Model; - -public class ModuleProcessor extends BaseProcessor { - - public void process(Object parent, Object child, Object target, - boolean isChildMostSpecialized) - { - super.process(parent, child, target, isChildMostSpecialized); - - if(isChildMostSpecialized) - { - Model t = (Model) target; - Model c = (Model) child; - t.setModules(new ArrayList(c.getModules())); - } - } - -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/ParentProcessor.java b/maven-project/src/main/java/org/apache/maven/project/processor/ParentProcessor.java deleted file mode 100644 index 903560bc6e..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/ParentProcessor.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.apache.maven.project.processor; - -import org.apache.maven.model.Model; -import org.apache.maven.model.Parent; - -public class ParentProcessor extends BaseProcessor { - - public ParentProcessor() { } - - public void process(Object parent, Object child, Object target, - boolean isChildMostSpecialized) - { - super.process(parent, child, target, isChildMostSpecialized); - - if(isChildMostSpecialized) - { - Model t = (Model) target; - Model c = (Model) child; - Parent p = new Parent(); - p.setGroupId(c.getGroupId()); - p.setArtifactId(c.getParent().getArtifactId()); - p.setVersion(c.getParent().getVersion()); - p.setRelativePath(c.getParent().getRelativePath()); - t.setParent(p); - //t.setPa - - } - } -} diff --git a/maven-project/src/main/java/org/apache/maven/project/processor/Processor.java b/maven-project/src/main/java/org/apache/maven/project/processor/Processor.java deleted file mode 100644 index 8d1d292670..0000000000 --- a/maven-project/src/main/java/org/apache/maven/project/processor/Processor.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.apache.maven.project.processor; - -public interface Processor { - void process(Object parent, Object child, Object target, boolean isChildMostSpecialized); - - Object getParent(); - - Object getChild(); -} diff --git a/maven-project/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java b/maven-project/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java index 29821faea3..57b930d132 100644 --- a/maven-project/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java +++ b/maven-project/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java @@ -85,10 +85,10 @@ public class DefaultModelValidator validateId( "dependencies.dependency.groupId", result, d.getGroupId() ); - validateStringNotEmpty( "dependencies.dependency.type", result, d.getType(), dependencySourceHint( d ) ); + validateStringNotEmpty( "dependencies.dependency.type", result, d.getType(), d.getManagementKey() ); validateStringNotEmpty( "dependencies.dependency.version", result, d.getVersion(), - dependencySourceHint( d ) ); + d.getManagementKey() ); if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) ) { @@ -263,19 +263,6 @@ public class DefaultModelValidator // Field validation // ---------------------------------------------------------------------- - /** - * Create a hint string consisting of the groupId and artifactId for user validation - * messages. For example when the version or type information is missing from a - * dependency. - * - * @param d The dependency from which to make the hint. - * @return String of the form g:a. - */ - private String dependencySourceHint( Dependency d ) - { - return d.getGroupId() + ":" + d.getArtifactId(); - } - private boolean validateStringNotEmpty( String fieldName, ModelValidationResult result, String string ) { return validateStringNotEmpty( fieldName, result, string, null ); diff --git a/maven-project/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java b/maven-project/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java index dbe1ee4cd7..c980c08fd0 100644 --- a/maven-project/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java +++ b/maven-project/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java @@ -20,7 +20,6 @@ package org.apache.maven.profiles.manager; */ import org.apache.maven.model.Activation; -import org.apache.maven.model.ActivationOS; import org.apache.maven.model.ActivationProperty; import org.apache.maven.model.Profile; import org.apache.maven.profiles.DefaultProfileManager; @@ -65,12 +64,12 @@ public class DefaultProfileManagerTest Properties props = new Properties(); ProfileActivationContext ctx = new ProfileActivationContext( props, false ); - ProfileManager profileManager = new DefaultProfileManager( getContainer(), ctx ); + ProfileManager profileManager = new DefaultProfileManager( ctx ); profileManager.addProfile( notActivated ); profileManager.addProfile( defaultActivated ); - List active = profileManager.getActiveProfiles( null ); + List active = profileManager.getActiveProfiles(); assertNotNull( active ); assertEquals( 1, active.size() ); @@ -104,17 +103,18 @@ public class DefaultProfileManagerTest Properties props = System.getProperties(); ProfileActivationContext ctx = new ProfileActivationContext( props, false ); - ProfileManager profileManager = new DefaultProfileManager( getContainer(), ctx ); + ProfileManager profileManager = new DefaultProfileManager( ctx ); profileManager.addProfile( syspropActivated ); profileManager.addProfile( defaultActivated ); - List active = profileManager.getActiveProfiles( null ); + List active = profileManager.getActiveProfiles(); assertNotNull( active ); assertEquals( 1, active.size() ); assertEquals( "syspropActivated", ( (Profile) active.get( 0 ) ).getId() ); } + public void testShouldNotActivateReversalOfPresentSystemProperty() throws Exception @@ -134,11 +134,11 @@ public class DefaultProfileManagerTest Properties props = System.getProperties(); ProfileActivationContext ctx = new ProfileActivationContext( props, false ); - ProfileManager profileManager = new DefaultProfileManager( getContainer(), ctx ); + ProfileManager profileManager = new DefaultProfileManager( ctx ); profileManager.addProfile( syspropActivated ); - List active = profileManager.getActiveProfiles( null ); + List active = profileManager.getActiveProfiles(); assertNotNull( active ); assertEquals( 0, active.size() ); @@ -162,13 +162,13 @@ public class DefaultProfileManagerTest Properties props = System.getProperties(); ProfileActivationContext ctx = new ProfileActivationContext( props, false ); - ProfileManager profileManager = new DefaultProfileManager( getContainer(), ctx ); + ProfileManager profileManager = new DefaultProfileManager( ctx ); profileManager.addProfile( syspropActivated ); ctx.setActive( "syspropActivated" ); - List active = profileManager.getActiveProfiles( null ); + List active = profileManager.getActiveProfiles(); assertNotNull( active ); assertEquals( 1, active.size() ); @@ -193,18 +193,18 @@ public class DefaultProfileManagerTest Properties props = System.getProperties(); ProfileActivationContext ctx = new ProfileActivationContext( props, false ); - ProfileManager profileManager = new DefaultProfileManager( getContainer(), ctx ); + ProfileManager profileManager = new DefaultProfileManager( ctx ); profileManager.addProfile( syspropActivated ); ctx.setInactive( "syspropActivated" ); - List active = profileManager.getActiveProfiles( null ); + List active = profileManager.getActiveProfiles(); assertNotNull( active ); assertEquals( 0, active.size() ); } - +/* public void testOsActivationProfile() throws Exception { @@ -233,5 +233,6 @@ public class DefaultProfileManagerTest assertNotNull( active ); assertEquals( 1, active.size() ); } + */ } diff --git a/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java b/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java new file mode 100644 index 0000000000..42a3353b9d --- /dev/null +++ b/maven-project/src/test/java/org/apache/maven/profiles/matchers/JdkMatcherTest.java @@ -0,0 +1,24 @@ +package org.apache.maven.profiles.matchers; + +import java.util.Collections; + +import org.apache.maven.model.Activation; +import org.apache.maven.model.Profile; +import org.apache.maven.model.interpolator.InterpolatorProperty; + +import junit.framework.TestCase; + +public class JdkMatcherTest extends TestCase +{ + public void testJdkMatch() + throws Exception + { + Profile p = new Profile(); + Activation a = new Activation(); + a.setJdk("(1.3,100)"); + p.setActivation(a); + + JdkMatcher m = new JdkMatcher(); + assertTrue(m.isMatch(p, Collections.singletonList(new InterpolatorProperty("${java.version}", "1.5.0_16")))); + } +} diff --git a/maven-project/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-project/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 6ae14389b1..d3fd99cbbb 100644 --- a/maven-project/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-project/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -135,7 +135,7 @@ public abstract class AbstractMavenProjectTestCase ProjectBuilderConfiguration pbc = new DefaultProjectBuilderConfiguration(); pbc.setLocalRepository( getLocalRepository() ); - pbc.setGlobalProfileManager( new DefaultProfileManager( getContainer(), ctx ) ); + pbc.setGlobalProfileManager( new DefaultProfileManager( ctx ) ); return projectBuilder.build( pom, pbc ); } diff --git a/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java index 97c68ad64c..e3398fce4a 100644 --- a/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -24,6 +24,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.Properties; import org.apache.maven.artifact.repository.DefaultArtifactRepository; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; @@ -32,7 +34,6 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.profiles.DefaultProfileManager; import org.apache.maven.profiles.ProfileActivationContext; import org.apache.maven.project.harness.PomTestWrapper; -import org.apache.maven.repository.RepositorySystem; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; @@ -47,8 +48,6 @@ public class PomConstructionTest private DefaultMavenProjectBuilder mavenProjectBuilder; - private RepositorySystem mavenTools; - private File testDirectory; private File testMixinDirectory; @@ -59,7 +58,6 @@ public class PomConstructionTest testDirectory = new File( getBasedir(), BASE_POM_DIR ); testMixinDirectory = new File( getBasedir(), BASE_MIXIN_DIR ); mavenProjectBuilder = (DefaultMavenProjectBuilder) lookup( MavenProjectBuilder.class ); - mavenTools = lookup( RepositorySystem.class ); } /** @@ -71,7 +69,7 @@ public class PomConstructionTest public void testEmptyUrl() throws Exception { - buildPomFromMavenProject( "empty-distMng-repo-url", null ); + buildPom( "empty-distMng-repo-url" ); } /** @@ -79,11 +77,11 @@ public class PomConstructionTest * * @throws Exception */ - /* FIXME: cf MNG-786 + /* MNG-786*/ public void testProfileModules() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "profile-module", "a" ); + PomTestWrapper pom = buildPom( "profile-module", "a" ); assertEquals( "test-prop", pom.getValue( "properties[1]/b" ) );// verifies profile applied assertEquals( 4, ( (List) pom.getValue( "modules" ) ).size() ); assertEquals( "module-2", pom.getValue( "modules[1]" ) ); @@ -91,7 +89,6 @@ public class PomConstructionTest assertEquals( "module-3", pom.getValue( "modules[3]" ) ); assertEquals( "module-4", pom.getValue( "modules[4]" ) ); } - //*/ /** * Will throw exception if doesn't find parent(s) in build @@ -124,7 +121,7 @@ public class PomConstructionTest public void testProfilePropertiesInterpolation() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "profile-properties-interpolation", "interpolation-profile" ); + PomTestWrapper pom = buildPom( "profile-properties-interpolation", "interpolation-profile" ); assertEquals("PASSED", pom.getValue("properties[1]/test")); assertEquals("PASSED", pom.getValue("properties[1]/property")); } @@ -136,17 +133,12 @@ public class PomConstructionTest // them into a resolver, create the expression to extract the data to validate the Model, and the URI // to validate the properties. We also need a way to navigate from the Tex specification documents to // the test in question and vice versa. A little Eclipse plugin would do the trick. - /* - TODO: Not sure why this test is failing after removing resolver. Logic is the same. - */ public void testThatExecutionsWithoutIdsAreMergedAndTheChildWins() throws Exception { - // This should be 2 - //assertEquals( 2, model.getLineageCount() ); PomTestWrapper tester = buildPom("micromailer"); - // System.out.println(tester.getDomainModel().asString()); - // assertModelEquals( tester, "child-descriptor", "build/plugins[1]/executions[1]/goals[1]" ); + assertEquals( 2, tester.getDomainModel().getLineageCount() ); + assertModelEquals( tester, "child-descriptor", "build/plugins[1]/executions[1]/goals[1]" ); } /*MNG- @@ -196,12 +188,24 @@ public class PomConstructionTest public void testParentInterpolation() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "parent-interpolation/sub", null ); + PomTestWrapper pom = buildPom( "parent-interpolation/sub" ); pom = new PomTestWrapper(pom.getMavenProject().getParent()); assertEquals( "1.3.0-SNAPSHOT", pom.getValue( "build/plugins[1]/version" ) ); } - +/* + public void testMaven() + throws Exception + { + PomTestWrapper pom = buildPomFromMavenProject( "maven-build/sub/pom.xml", null ); + + for(String s: pom.getMavenProject().getTestClasspathElements()){ + System.out.println(s); + } + + } + */ + /* MNG-3567*/ public void testPluginManagementInherited() throws Exception @@ -214,7 +218,7 @@ public class PomConstructionTest public void testPluginManagementDependencies() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "plugin-management-dependencies/sub", "test" ); + PomTestWrapper pom = buildPom( "plugin-management-dependencies/sub", "test" ); assertEquals( "1.0-alpha-21", pom.getValue( "build/plugins[1]/version" ) ); assertEquals( "1.0", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) ); } @@ -224,7 +228,7 @@ public class PomConstructionTest public void testReportingInterpolation() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "reporting-interpolation", null ); + PomTestWrapper pom = buildPom( "reporting-interpolation" ); pom = new PomTestWrapper(pom.getMavenProject()); assertEquals( createPath(Arrays.asList(System.getProperty("user.dir"), "src", "test", "resources-project-builder", "reporting-interpolation", "target", "site")), @@ -284,16 +288,17 @@ public class PomConstructionTest } */ - /* FIX - REGRESSION + public void testSingleConfigurationInheritance() throws Exception { PomTestWrapper pom = buildPom( "single-configuration-inheritance" ); + assertEquals( 2, ( (List) pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules" ) ).size() ); assertEquals("2.0.6", pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/requireMavenVersion[1]/version" ) ); - assertEquals("[2.0.6,)", pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[2]/requireMavenVersion[1]/version" ) ); + assertEquals("[1.4,)", pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/requireJavaVersion[1]/version" ) ); } -*/ + public void testConfigWithPluginManagement() throws Exception { @@ -311,15 +316,6 @@ public class PomConstructionTest assertEquals( 2, ( (List) pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/bannedDependencies" ) ).size() ); } - /** MNG- - public void testFoo() - throws Exception - { - PomTestWrapper pom = buildPom( "foo/sub" ); - //System.out.println(pom.getDomainModel().asString()); - } - */ - /** MNG-3985 */ public void testMultipleRepositories() throws Exception @@ -344,7 +340,6 @@ public class PomConstructionTest pom.getDomainModel().asString(); } - //*/ public void testOrderOfGoalsFromPluginExecutionWithoutPluginManagement() throws Exception { @@ -357,7 +352,7 @@ public class PomConstructionTest assertEquals( "e", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) ); } - /* FIXME: cf. MNG-3886*/ + /* MNG-3886*/ public void testOrderOfGoalsFromPluginExecutionWithPluginManagement() throws Exception { @@ -369,7 +364,6 @@ public class PomConstructionTest assertEquals( "c", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) ); assertEquals( "e", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) ); } - //*/ public void testOrderOfPluginExecutionsWithoutPluginManagement() throws Exception @@ -383,7 +377,7 @@ public class PomConstructionTest assertEquals( "e", pom.getValue( "build/plugins[1]/executions[5]/id" ) ); } - /* FIXME: cf. MNG-3887 */ + /* MNG-3887 */ public void testOrderOfPluginExecutionsWithPluginManagement() throws Exception { @@ -395,7 +389,6 @@ public class PomConstructionTest assertEquals( "c", pom.getValue( "build/plugins[1]/executions[4]/id" ) ); assertEquals( "e", pom.getValue( "build/plugins[1]/executions[5]/id" ) ); } - //*/ public void testMergeOfPluginExecutionsWhenChildInheritsPluginVersion() throws Exception @@ -420,12 +413,11 @@ public class PomConstructionTest assertEquals( "Tom&Jerry", pom.getValue( "properties/xmlTest" ) ); } - /* FIXME: cf. MNG-3925 + /* MNG-3925 */ public void testOrderOfMergedPluginExecutionsWithoutPluginManagement() throws Exception { PomTestWrapper pom = buildPom( "merged-plugin-exec-order/wo-plugin-mngt/sub" ); - System.out.println(pom.getDomainModel().asString()); assertEquals( 5, ( (List) pom.getValue( "build/plugins[1]/executions" ) ).size() ); assertEquals( "parent-1", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) ); assertEquals( "parent-2", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) ); @@ -445,7 +437,6 @@ public class PomConstructionTest assertEquals( "child-1", pom.getValue( "build/plugins[1]/executions[4]/goals[1]" ) ); assertEquals( "child-2", pom.getValue( "build/plugins[1]/executions[5]/goals[1]" ) ); } - //*/ /* MNG-3984*/ public void testDifferentContainersWithSameId() @@ -457,11 +448,11 @@ public class PomConstructionTest } /* MNG-3937*/ - /* FIX - REGRESSION public void testOrderOfMergedPluginExecutionGoalsWithoutPluginManagement() throws Exception { PomTestWrapper pom = buildPom( "merged-plugin-exec-goals-order/wo-plugin-mngt/sub" ); + assertEquals( 5, ( (List) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() ); assertEquals( "child-a", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) ); assertEquals( "merged", pom.getValue( "build/plugins[1]/executions[1]/goals[2]" ) ); @@ -469,7 +460,7 @@ public class PomConstructionTest assertEquals( "parent-b", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) ); assertEquals( "parent-a", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) ); } -*/ + public void testOrderOfMergedPluginExecutionGoalsWithPluginManagement() throws Exception { @@ -481,17 +472,17 @@ public class PomConstructionTest assertEquals( "parent-b", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) ); assertEquals( "parent-a", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) ); } - //*/ -/* FIX - REGRESSION + + /*MNG-3938*/ public void testOverridingOfInheritedPluginExecutionsWithoutPluginManagement() throws Exception { PomTestWrapper pom = buildPom( "plugin-exec-merging/wo-plugin-mngt/sub" ); assertEquals( 2, ( (List) pom.getValue( "build/plugins[1]/executions" ) ).size() ); - assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[@id='default-execution-id']/phase" ) ); + assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[@id='default']/phase" ) ); assertEquals( "child-non-default", pom.getValue( "build/plugins[1]/executions[@id='non-default']/phase" ) ); } -*/ + /* MNG-3938 */ public void testOverridingOfInheritedPluginExecutionsWithPluginManagement() throws Exception @@ -501,24 +492,26 @@ public class PomConstructionTest assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[@id='default']/phase" ) ); assertEquals( "child-non-default", pom.getValue( "build/plugins[1]/executions[@id='non-default']/phase" ) ); } - - /* FIXME: cf. MNG-3906 + + /* MNG-3906*/ public void testOrderOfMergedPluginDependenciesWithoutPluginManagement() throws Exception { PomTestWrapper pom = buildPom( "merged-plugin-class-path-order/wo-plugin-mngt/sub" ); + assertEquals( 5, ( (List) pom.getValue( "build/plugins[1]/dependencies" ) ).size() ); - assertEquals( "c", pom.getValue( "build/plugins[1]/dependency[1]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[1]/version" ) ); - assertEquals( "a", pom.getValue( "build/plugins[1]/dependency[2]/artifactId" ) ); - assertEquals( "2", pom.getValue( "build/plugins[1]/dependency[2]/version" ) ); - assertEquals( "b", pom.getValue( "build/plugins[1]/dependency[3]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[3]/version" ) ); - assertEquals( "e", pom.getValue( "build/plugins[1]/dependency[4]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[4]/version" ) ); - assertEquals( "e", pom.getValue( "build/plugins[1]/dependency[5]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[5]/version" ) ); + assertNotNull( pom.getValue( "build/plugins[1]/dependencies[1]" )); + assertEquals( "c", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) ); + assertEquals( "a", pom.getValue( "build/plugins[1]/dependencies[2]/artifactId" ) ); + assertEquals( "2", pom.getValue( "build/plugins[1]/dependencies[2]/version" ) ); + assertEquals( "b", pom.getValue( "build/plugins[1]/dependencies[3]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[3]/version" ) ); + assertEquals( "e", pom.getValue( "build/plugins[1]/dependencies[4]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[4]/version" ) ); + assertEquals( "d", pom.getValue( "build/plugins[1]/dependencies[5]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[5]/version" ) ); } public void testOrderOfMergedPluginDependenciesWithPluginManagement() @@ -526,18 +519,17 @@ public class PomConstructionTest { PomTestWrapper pom = buildPom( "merged-plugin-class-path-order/w-plugin-mngt/sub" ); assertEquals( 5, ( (List) pom.getValue( "build/plugins[1]/dependencies" ) ).size() ); - assertEquals( "c", pom.getValue( "build/plugins[1]/dependency[1]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[1]/version" ) ); - assertEquals( "a", pom.getValue( "build/plugins[1]/dependency[2]/artifactId" ) ); - assertEquals( "2", pom.getValue( "build/plugins[1]/dependency[2]/version" ) ); - assertEquals( "b", pom.getValue( "build/plugins[1]/dependency[3]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[3]/version" ) ); - assertEquals( "e", pom.getValue( "build/plugins[1]/dependency[4]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[4]/version" ) ); - assertEquals( "e", pom.getValue( "build/plugins[1]/dependency[5]/artifactId" ) ); - assertEquals( "1", pom.getValue( "build/plugins[1]/dependency[5]/version" ) ); + assertEquals( "c", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) ); + assertEquals( "a", pom.getValue( "build/plugins[1]/dependencies[2]/artifactId" ) ); + assertEquals( "2", pom.getValue( "build/plugins[1]/dependencies[2]/version" ) ); + assertEquals( "b", pom.getValue( "build/plugins[1]/dependencies[3]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[3]/version" ) ); + assertEquals( "e", pom.getValue( "build/plugins[1]/dependencies[4]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[4]/version" ) ); + assertEquals( "d", pom.getValue( "build/plugins[1]/dependencies[5]/artifactId" ) ); + assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[5]/version" ) ); } - //*/ public void testInterpolationOfNestedBuildDirectories() throws Exception @@ -569,6 +561,26 @@ public class PomConstructionTest assertEquals( "http://parent.url/download", pom.getValue( "distributionManagement/downloadUrl" ) ); } + /* MNG-3846*/ + public void testAppendArtifactIdOfParentAndChildToInheritedUrls() + throws Exception + { + PomTestWrapper pom = buildPom( "url-inheritance/another-parent/sub" ); + assertEquals( "http://parent.url/ap/child", pom.getValue( "url" ) ); + assertEquals( "http://parent.url/org/", pom.getValue( "organization/url" ) ); + assertEquals( "http://parent.url/license.txt", pom.getValue( "licenses[1]/url" ) ); + assertEquals( "http://parent.url/viewvc/ap/child", pom.getValue( "scm/url" ) ); + assertEquals( "http://parent.url/scm/ap/child", pom.getValue( "scm/connection" ) ); + assertEquals( "https://parent.url/scm/ap/child", pom.getValue( "scm/developerConnection" ) ); + assertEquals( "http://parent.url/issues", pom.getValue( "issueManagement/url" ) ); + assertEquals( "http://parent.url/ci", pom.getValue( "ciManagement/url" ) ); + assertEquals( "http://parent.url/dist", pom.getValue( "distributionManagement/repository/url" ) ); + assertEquals( "http://parent.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) ); + assertEquals( "http://parent.url/site/ap/child", pom.getValue( "distributionManagement/site/url" ) ); + assertEquals( "http://parent.url/download", pom.getValue( "distributionManagement/downloadUrl" ) ); + } + //*/ + public void testNonInheritedElementsInSubtreesOverriddenByChild() throws Exception { @@ -576,12 +588,18 @@ public class PomConstructionTest assertEquals( null, pom.getValue( "organization/url" ) ); assertEquals( null, pom.getValue( "issueManagement/system" ) ); assertEquals( 0, ( (List) pom.getValue( "ciManagement/notifiers" ) ).size() ); + assertEquals( "child-distros", pom.getValue( "distributionManagement/repository/id" ) ); + assertEquals( "ssh://child.url/distros", pom.getValue( "distributionManagement/repository/url" ) ); assertEquals( null, pom.getValue( "distributionManagement/repository/name" ) ); assertEquals( true, pom.getValue( "distributionManagement/repository/uniqueVersion" ) ); assertEquals( "default", pom.getValue( "distributionManagement/repository/layout" ) ); + assertEquals( "child-snaps", pom.getValue( "distributionManagement/snapshotRepository/id" ) ); + assertEquals( "ssh://child.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) ); assertEquals( null, pom.getValue( "distributionManagement/snapshotRepository/name" ) ); assertEquals( true, pom.getValue( "distributionManagement/snapshotRepository/uniqueVersion" ) ); assertEquals( "default", pom.getValue( "distributionManagement/snapshotRepository/layout" ) ); + assertEquals( "child-site", pom.getValue( "distributionManagement/site/id" ) ); + assertEquals( "scp://child.url/site", pom.getValue( "distributionManagement/site/url" ) ); assertEquals( null, pom.getValue( "distributionManagement/site/name" ) ); } @@ -610,6 +628,7 @@ public class PomConstructionTest throws Exception { PomTestWrapper pom = buildPom( "unprefixed-expression-interpolation/child" ); + assertEquals( pom.getBasedir(), new File( pom.getValue( "properties/projectDir" ).toString() ) ); assertEquals( "org.apache.maven.its.mng3831.child", pom.getValue( "properties/projectGroupId" ) ); @@ -659,7 +678,7 @@ public class PomConstructionTest new File( pom.getValue( "properties/siteOut" ).toString() ) ); } - /* FIXME: cf. MNG-3944*/ + /* MNG-3944*/ public void testInterpolationOfBasedirInPomWithUnusualName() throws Exception { @@ -675,7 +694,6 @@ public class PomConstructionTest PomTestWrapper pom = buildPom( "id-container-joining-with-empty-elements/sub" ); assertNotNull( pom ); } - //*/ public void testOrderOfPluginConfigurationElementsWithoutPluginManagement() throws Exception @@ -687,7 +705,7 @@ public class PomConstructionTest assertEquals( "four", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[4]" ) ); } - /* FIXME: cf. MNG-3827*/ + /* MNG-3827*/ public void testOrderOfPluginConfigurationElementsWithPluginManagement() throws Exception { @@ -697,7 +715,6 @@ public class PomConstructionTest assertEquals( "three", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[3]" ) ); assertEquals( "four", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[4]" ) ); } - //*/ public void testOrderOfPluginExecutionConfigurationElementsWithoutPluginManagement() throws Exception @@ -712,7 +729,7 @@ public class PomConstructionTest assertEquals( "key2", pom.getValue( prefix + "propertiesParam/property[2]/name" ) ); } - /* FIXME: cf. MNG-3864*/ + /* MNG-3864*/ public void testOrderOfPluginExecutionConfigurationElementsWithPluginManagement() throws Exception { @@ -725,32 +742,44 @@ public class PomConstructionTest assertEquals( "key1", pom.getValue( prefix + "propertiesParam/property[1]/name" ) ); assertEquals( "key2", pom.getValue( prefix + "propertiesParam/property[2]/name" ) ); } - //*/ - /* FIXME: cf. MNG-3836 + /* MNG-3836*/ public void testMergeOfInheritedPluginConfiguration() throws Exception { PomTestWrapper pom = buildPom( "plugin-config-merging/child" ); + String prefix = "build/plugins[1]/configuration/"; assertEquals( "PASSED", pom.getValue( prefix + "propertiesFile" ) ); assertEquals( "PASSED", pom.getValue( prefix + "parent" ) ); assertEquals( "PASSED-1", pom.getValue( prefix + "stringParams/stringParam[1]" ) ); - assertEquals( "PASSED-2", pom.getValue( prefix + "stringParams/stringParam[2]" ) ); - assertEquals( "PASSED-3", pom.getValue( prefix + "stringParams/stringParam[3]" ) ); + assertEquals( "PASSED-3", pom.getValue( prefix + "stringParams/stringParam[2]" ) ); + assertEquals( "PASSED-2", pom.getValue( prefix + "stringParams/stringParam[3]" ) ); assertEquals( "PASSED-4", pom.getValue( prefix + "stringParams/stringParam[4]" ) ); assertEquals( "PASSED-1", pom.getValue( prefix + "listParam/listParam[1]" ) ); - assertEquals( "PASSED-2", pom.getValue( prefix + "listParam/listParam[2]" ) ); - assertEquals( "PASSED-3", pom.getValue( prefix + "listParam/listParam[3]" ) ); + assertEquals( "PASSED-3", pom.getValue( prefix + "listParam/listParam[2]" ) ); + assertEquals( "PASSED-2", pom.getValue( prefix + "listParam/listParam[3]" ) ); assertEquals( "PASSED-4", pom.getValue( prefix + "listParam/listParam[4]" ) ); } - //*/ - /* FIXME: cf. MNG-2591 - public void testAppendOfInheritedPluginConfiguration() + /* MNG-2591 */ + public void testAppendOfInheritedPluginConfigurationWithNoProfile() throws Exception { - PomTestWrapper pom = buildPom( "plugin-config-append/subproject" ); + testAppendOfInheritedPluginConfiguration( "no-profile" ); + } + + /* MNG-2591*/ + public void testAppendOfInheritedPluginConfigurationWithActiveProfile() + throws Exception + { + testAppendOfInheritedPluginConfiguration( "with-profile" ); + } + + private void testAppendOfInheritedPluginConfiguration( String test ) + throws Exception + { + PomTestWrapper pom = buildPom( "plugin-config-append/" + test + "/subproject" ); String prefix = "build/plugins[1]/configuration/"; assertEquals( "PARENT-1", pom.getValue( prefix + "stringParams/stringParam[1]" ) ); assertEquals( "PARENT-3", pom.getValue( prefix + "stringParams/stringParam[2]" ) ); @@ -760,6 +789,7 @@ public class PomConstructionTest assertEquals( "CHILD-3", pom.getValue( prefix + "stringParams/stringParam[6]" ) ); assertEquals( "CHILD-2", pom.getValue( prefix + "stringParams/stringParam[7]" ) ); assertEquals( "CHILD-4", pom.getValue( prefix + "stringParams/stringParam[8]" ) ); + assertEquals( null, pom.getValue( prefix + "stringParams/stringParam[9]" ) ); assertEquals( "PARENT-1", pom.getValue( prefix + "listParam/listParam[1]" ) ); assertEquals( "PARENT-3", pom.getValue( prefix + "listParam/listParam[2]" ) ); assertEquals( "PARENT-2", pom.getValue( prefix + "listParam/listParam[3]" ) ); @@ -768,10 +798,10 @@ public class PomConstructionTest assertEquals( "CHILD-3", pom.getValue( prefix + "listParam/listParam[6]" ) ); assertEquals( "CHILD-2", pom.getValue( prefix + "listParam/listParam[7]" ) ); assertEquals( "CHILD-4", pom.getValue( prefix + "listParam/listParam[8]" ) ); + assertEquals( null, pom.getValue( prefix + "listParam/listParam[9]" ) ); } - //*/ - /* FIXME: cf. MNG-4000 */ + /* MNG-4000 */ public void testMultiplePluginExecutionsWithAndWithoutIdsWithoutPluginManagement() throws Exception { @@ -780,7 +810,6 @@ public class PomConstructionTest assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) ); assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) ); } - //*/ public void testMultiplePluginExecutionsWithAndWithoutIdsWithPluginManagement() throws Exception @@ -834,7 +863,6 @@ public class PomConstructionTest { PomTestWrapper pom = buildPom( "merged-filter-order/sub" ); - System.out.println(pom.getValue( "build/filters" )); assertEquals( 7, ( (List) pom.getValue( "build/filters" ) ).size() ); assertTrue( pom.getValue( "build/filters[1]" ).toString().endsWith( "child-a.properties" ) ); assertTrue( pom.getValue( "build/filters[2]" ).toString().endsWith( "child-c.properties" ) ); @@ -845,7 +873,7 @@ public class PomConstructionTest assertTrue( pom.getValue( "build/filters[7]" ).toString().endsWith( "parent-d.properties" ) ); } - /** MNG-4027 + /** MNG-4027*/ public void testProfileInjectedDependencies() throws Exception { @@ -856,13 +884,20 @@ public class PomConstructionTest assertEquals( "b", pom.getValue( "dependencies[3]/artifactId" ) ); assertEquals( "d", pom.getValue( "dependencies[4]/artifactId" ) ); } - //*/ - + + public void testDependencyInheritance() + throws Exception + { + PomTestWrapper pom = buildPom( "dependency-inheritance/sub" ); + assertEquals(1, ( (List) pom.getValue( "dependencies" ) ).size() ); + assertEquals("4.4", pom.getValue("dependencies[1]/version") ); + } + /** MNG-4034 */ public void testManagedProfileDependency() throws Exception { - PomTestWrapper pom = this.buildPomFromMavenProject( "managed-profile-dependency/sub", "maven-core-it" ); + PomTestWrapper pom = this.buildPom( "managed-profile-dependency/sub", "maven-core-it" ); assertEquals( 1, ( (List) pom.getValue( "dependencies" ) ).size() ); assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/groupId" ) ); assertEquals( "maven-core-it-support", pom.getValue( "dependencies[1]/artifactId" ) ); @@ -871,17 +906,51 @@ public class PomConstructionTest assertEquals( 1, ( (List) pom.getValue( "dependencies[1]/exclusions" ) ).size() ); assertEquals( "commons-lang", pom.getValue( "dependencies[1]/exclusions[1]/groupId" ) ); } - //*/ /** MNG-4040 */ public void testProfileModuleInheritance() throws Exception { - PomTestWrapper pom = this.buildPomFromMavenProject( "profile-module-inheritance/sub", "dist" ); + PomTestWrapper pom = this.buildPom( "profile-module-inheritance/sub", "dist" ); assertEquals(0, ( (List) pom.getValue( "modules" ) ).size()); - } + + /** MNG-3621 */ + public void testUncPath() + throws Exception + { + PomTestWrapper pom = this.buildPom( "unc-path/sub" ); + assertEquals("file:////host/site/test-child", pom.getValue( "distributionManagement/site/url" )); + } + + /** MNG-2006 */ + public void testUrlAppend() + throws Exception + { + PomTestWrapper pom = this.buildPom( "url-append/child" ); + assertEquals("http://project.url/child", pom.getValue( "url" )); + assertEquals("http://viewvc.project.url/child", pom.getValue( "scm/url" )); + assertEquals("http://scm.project.url/child", pom.getValue( "scm/connection" )); + assertEquals("https://scm.project.url/child", pom.getValue( "scm/developerConnection" )); + assertEquals("http://site.project.url/child", pom.getValue( "distributionManagement/site/url" )); + } + /** MNG-0479 */ + public void testRepoInheritance() + throws Exception + { + PomTestWrapper pom = this.buildPom( "repo-inheritance" ); + assertEquals(1, ( (List) pom.getValue( "repositories" ) ).size()); + assertEquals( "it0043", pom.getValue( "repositories[1]/name" ) ); + } + + public void testEmptyScm() + throws Exception + { + PomTestWrapper pom = this.buildPom( "empty-scm" ); + assertNull(pom.getValue( "scm" )); + } + public void testPluginConfigurationUsingAttributesWithoutPluginManagement() throws Exception { @@ -893,7 +962,7 @@ public class PomConstructionTest assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@overwrite" ) ); } - /** FIXME: MNG-4053 + /** MNG-4053*/ public void testPluginConfigurationUsingAttributesWithPluginManagement() throws Exception { @@ -908,14 +977,13 @@ public class PomConstructionTest public void testPluginConfigurationUsingAttributesWithPluginManagementAndProfile() throws Exception { - PomTestWrapper pom = buildPomFromMavenProject( "plugin-config-attributes/w-profile", "maven-core-it" ); + PomTestWrapper pom = buildPom( "plugin-config-attributes/w-profile", "maven-core-it" ); assertEquals( "src", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@todir" ) ); assertEquals( "true", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@overwrite" ) ); assertEquals( "target", pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@dir" ) ); assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@todir" ) ); assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@overwrite" ) ); } - //*/ public void testPomEncoding() throws Exception @@ -926,33 +994,446 @@ public class PomConstructionTest assertEquals( "TEST-CHARS: \u00C4\u00D6\u00DC\u00E4\u00F6\u00FC\u00DF", pom.getValue( "description" ) ); } - /* FIXME: MNG-4070, fixed in model-builder trunk, awaiting update to model-builder:1.7+ + /* MNG-4070 */ public void testXmlWhitespaceHandling() throws Exception { PomTestWrapper pom = buildPom( "xml-whitespace/sub" ); assertEquals( "org.apache.maven.its.mng4070", pom.getValue( "groupId" ) ); } - //*/ + + /* MNG-3760*/ + public void testInterpolationOfBaseUrl() + throws Exception + { + PomTestWrapper pom = buildPom( "baseurl-interpolation/pom.xml" ); + assertEquals( pom.getBasedir().toURI().toString(), pom.getValue( "properties/prop1" ).toString() ); + } + + /* MNG-3811*/ + public void testReportingPluginConfig() + throws Exception + { + PomTestWrapper pom = buildPom( "reporting-plugin-config/sub" ); + + assertEquals(2, ( (List) pom.getValue( "reporting/plugins[1]/configuration/stringParams" ) ).size()); + assertEquals("parentParam", pom.getValue( "reporting/plugins[1]/configuration/stringParams[1]/stringParam[1]")); + assertEquals("childParam", pom.getValue( "reporting/plugins[1]/configuration/stringParams[1]/stringParam[2]")); + assertEquals("true", pom.getValue( "reporting/plugins[1]/configuration/booleanParam")); + } + + public void testPropertiesNoDuplication() + throws Exception + { + PomTestWrapper pom = buildPom( "properties-no-duplication/sub" ); + assertEquals(1, ( (Properties) pom.getValue( "properties" ) ).size()); + assertEquals("child", pom.getValue( "properties/pomProfile" ) ); + } + + public void testPomInheritance() + throws Exception + { + PomTestWrapper pom = buildPom( "pom-inheritance/sub" ); + assertEquals("parent-description", pom.getValue("description")); + } + + public void testCompleteModelWithoutParent() + throws Exception + { + PomTestWrapper pom = buildPom( "complete-model/wo-parent" ); + + testCompleteModel( pom ); + } + + public void testCompleteModelWithParent() + throws Exception + { + PomTestWrapper pom = buildPom( "complete-model/w-parent/sub" ); + + testCompleteModel( pom ); + } + + private void testCompleteModel( PomTestWrapper pom ) + throws Exception + { + assertEquals( "4.0.0", pom.getValue( "modelVersion" ) ); + + assertEquals( "org.apache.maven.its.mng", pom.getValue( "groupId" ) ); + assertEquals( "test", pom.getValue( "artifactId" ) ); + assertEquals( "0.2", pom.getValue( "version" ) ); + assertEquals( "pom", pom.getValue( "packaging" ) ); + + assertEquals( "project-name", pom.getValue( "name" ) ); + assertEquals( "project-description", pom.getValue( "description" ) ); + assertEquals( "http://project.url/", pom.getValue( "url" ) ); + assertEquals( "2009", pom.getValue( "inceptionYear" ) ); + + assertEquals( "project-org", pom.getValue( "organization/name" ) ); + assertEquals( "http://project-org.url/", pom.getValue( "organization/url" ) ); + + assertEquals( 1, ( (List) pom.getValue( "licenses" ) ).size() ); + assertEquals( "project-license", pom.getValue( "licenses[1]/name" ) ); + assertEquals( "http://project.url/license", pom.getValue( "licenses[1]/url" ) ); + assertEquals( "repo", pom.getValue( "licenses[1]/distribution" ) ); + assertEquals( "free", pom.getValue( "licenses[1]/comments" ) ); + + assertEquals( 1, ( (List) pom.getValue( "developers" ) ).size() ); + assertEquals( "dev", pom.getValue( "developers[1]/id" ) ); + assertEquals( "project-developer", pom.getValue( "developers[1]/name" ) ); + assertEquals( "developer@", pom.getValue( "developers[1]/email" ) ); + assertEquals( "http://developer", pom.getValue( "developers[1]/url" ) ); + assertEquals( "developer", pom.getValue( "developers[1]/organization" ) ); + assertEquals( "http://devel.org", pom.getValue( "developers[1]/organizationUrl" ) ); + assertEquals( "-1", pom.getValue( "developers[1]/timezone" ) ); + assertEquals( "yes", pom.getValue( "developers[1]/properties/developer" ) ); + assertEquals( 1, ( (List) pom.getValue( "developers[1]/roles" ) ).size() ); + assertEquals( "devel", pom.getValue( "developers[1]/roles[1]" ) ); + + assertEquals( 1, ( (List) pom.getValue( "contributors" ) ).size() ); + assertEquals( "project-contributor", pom.getValue( "contributors[1]/name" ) ); + assertEquals( "contributor@", pom.getValue( "contributors[1]/email" ) ); + assertEquals( "http://contributor", pom.getValue( "contributors[1]/url" ) ); + assertEquals( "contributor", pom.getValue( "contributors[1]/organization" ) ); + assertEquals( "http://contrib.org", pom.getValue( "contributors[1]/organizationUrl" ) ); + assertEquals( "+1", pom.getValue( "contributors[1]/timezone" ) ); + assertEquals( "yes", pom.getValue( "contributors[1]/properties/contributor" ) ); + assertEquals( 1, ( (List) pom.getValue( "contributors[1]/roles" ) ).size() ); + assertEquals( "contrib", pom.getValue( "contributors[1]/roles[1]" ) ); + + assertEquals( 1, ( (List) pom.getValue( "mailingLists" ) ).size() ); + assertEquals( "project-mailing-list", pom.getValue( "mailingLists[1]/name" ) ); + assertEquals( "subscribe@", pom.getValue( "mailingLists[1]/subscribe" ) ); + assertEquals( "unsubscribe@", pom.getValue( "mailingLists[1]/unsubscribe" ) ); + assertEquals( "post@", pom.getValue( "mailingLists[1]/post" ) ); + assertEquals( "mail-archive", pom.getValue( "mailingLists[1]/archive" ) ); + assertEquals( 1, ( (List) pom.getValue( "mailingLists[1]/otherArchives" ) ).size() ); + assertEquals( "other-archive", pom.getValue( "mailingLists[1]/otherArchives[1]" ) ); + + assertEquals( "2.0.1", pom.getValue( "prerequisites/maven" ) ); + + assertEquals( "http://project.url/trunk", pom.getValue( "scm/url" ) ); + assertEquals( "http://project.url/scm", pom.getValue( "scm/connection" ) ); + assertEquals( "https://project.url/scm", pom.getValue( "scm/developerConnection" ) ); + assertEquals( "TAG", pom.getValue( "scm/tag" ) ); + + assertEquals( "issues", pom.getValue( "issueManagement/system" ) ); + assertEquals( "http://project.url/issues", pom.getValue( "issueManagement/url" ) ); + + assertEquals( "ci", pom.getValue( "ciManagement/system" ) ); + assertEquals( "http://project.url/ci", pom.getValue( "ciManagement/url" ) ); + assertEquals( 1, ( (List) pom.getValue( "ciManagement/notifiers" ) ).size() ); + assertEquals( "irc", pom.getValue( "ciManagement/notifiers[1]/type" ) ); + assertEquals( "ci@", pom.getValue( "ciManagement/notifiers[1]/address" ) ); + assertEquals( Boolean.TRUE, pom.getValue( "ciManagement/notifiers[1]/sendOnError" ) ); + assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnFailure" ) ); + assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnWarning" ) ); + assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnSuccess" ) ); + assertEquals( "ci", pom.getValue( "ciManagement/notifiers[1]/configuration/ciProp" ) ); + + assertEquals( "project.distros", pom.getValue( "distributionManagement/repository/id" ) ); + assertEquals( "distros", pom.getValue( "distributionManagement/repository/name" ) ); + assertEquals( "http://project.url/dist", pom.getValue( "distributionManagement/repository/url" ) ); + assertEquals( Boolean.TRUE, pom.getValue( "distributionManagement/repository/uniqueVersion" ) ); + + assertEquals( "project.snaps", pom.getValue( "distributionManagement/snapshotRepository/id" ) ); + assertEquals( "snaps", pom.getValue( "distributionManagement/snapshotRepository/name" ) ); + assertEquals( "http://project.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) ); + assertEquals( Boolean.FALSE, pom.getValue( "distributionManagement/snapshotRepository/uniqueVersion" ) ); + + assertEquals( "project.site", pom.getValue( "distributionManagement/site/id" ) ); + assertEquals( "docs", pom.getValue( "distributionManagement/site/name" ) ); + assertEquals( "http://project.url/site", pom.getValue( "distributionManagement/site/url" ) ); + + assertEquals( "http://project.url/download", pom.getValue( "distributionManagement/downloadUrl" ) ); + assertEquals( "reloc-gid", pom.getValue( "distributionManagement/relocation/groupId" ) ); + assertEquals( "reloc-aid", pom.getValue( "distributionManagement/relocation/artifactId" ) ); + assertEquals( "reloc-version", pom.getValue( "distributionManagement/relocation/version" ) ); + assertEquals( "project-reloc-msg", pom.getValue( "distributionManagement/relocation/message" ) ); + + assertEquals( 1, ( (List) pom.getValue( "modules" ) ).size() ); + assertEquals( "sub", pom.getValue( "modules[1]" ) ); + + assertEquals( 1, ( (Map) pom.getValue( "properties" ) ).size() ); + assertEquals( "project-property", pom.getValue( "properties[1]/itProperty" ) ); + + assertEquals( 1, ( (List) pom.getValue( "dependencyManagement/dependencies" ) ).size() ); + assertEquals( "org.apache.maven.its", pom.getValue( "dependencyManagement/dependencies[1]/groupId" ) ); + assertEquals( "managed-dep", pom.getValue( "dependencyManagement/dependencies[1]/artifactId" ) ); + assertEquals( "0.1", pom.getValue( "dependencyManagement/dependencies[1]/version" ) ); + assertEquals( "war", pom.getValue( "dependencyManagement/dependencies[1]/type" ) ); + assertEquals( "runtime", pom.getValue( "dependencyManagement/dependencies[1]/scope" ) ); + assertEquals( Boolean.FALSE, pom.getValue( "dependencyManagement/dependencies[1]/optional" ) ); + assertEquals( 1, ( (List) pom.getValue( "dependencyManagement/dependencies[1]/exclusions" ) ).size() ); + assertEquals( "org.apache.maven.its", + pom.getValue( "dependencyManagement/dependencies[1]/exclusions[1]/groupId" ) ); + assertEquals( "excluded-managed-dep", + pom.getValue( "dependencyManagement/dependencies[1]/exclusions[1]/artifactId" ) ); + + assertEquals( 1, ( (List) pom.getValue( "dependencies" ) ).size() ); + assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/groupId" ) ); + assertEquals( "dep", pom.getValue( "dependencies[1]/artifactId" ) ); + assertEquals( "0.2", pom.getValue( "dependencies[1]/version" ) ); + assertEquals( "ejb", pom.getValue( "dependencies[1]/type" ) ); + assertEquals( "test", pom.getValue( "dependencies[1]/scope" ) ); + assertEquals( Boolean.TRUE, pom.getValue( "dependencies[1]/optional" ) ); + assertEquals( 1, ( (List) pom.getValue( "dependencies[1]/exclusions" ) ).size() ); + assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/exclusions[1]/groupId" ) ); + assertEquals( "excluded-dep", pom.getValue( "dependencies[1]/exclusions[1]/artifactId" ) ); + + assertEquals( "test", pom.getValue( "build/defaultGoal" ) ); + assertEquals( "coreit", pom.getValue( "build/finalName" ) ); + + assertPathSuffixEquals( "build", pom.getValue( "build/directory" ) ); + assertPathSuffixEquals( "build/main", pom.getValue( "build/outputDirectory" ) ); + assertPathSuffixEquals( "build/test", pom.getValue( "build/testOutputDirectory" ) ); + assertPathSuffixEquals( "sources/main", pom.getValue( "build/sourceDirectory" ) ); + assertPathSuffixEquals( "sources/test", pom.getValue( "build/testSourceDirectory" ) ); + assertPathSuffixEquals( "sources/scripts", pom.getValue( "build/scriptSourceDirectory" ) ); + + assertEquals( 1, ( (List) pom.getValue( "build/filters" ) ).size() ); + assertPathSuffixEquals( "src/main/filter/it.properties", pom.getValue( "build/filters[1]" ) ); + + assertEquals( 1, ( (List) pom.getValue( "build/resources" ) ).size() ); + assertPathSuffixEquals( "res/main", pom.getValue( "build/resources[1]/directory" ) ); + assertPathSuffixEquals( "main", pom.getValue( "build/resources[1]/targetPath" ) ); + assertEquals( Boolean.TRUE, pom.getValue( "build/resources[1]/filtering" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/resources[1]/includes" ) ).size() ); + assertPathSuffixEquals( "main.included", pom.getValue( "build/resources[1]/includes[1]" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/resources[1]/excludes" ) ).size() ); + assertPathSuffixEquals( "main.excluded", pom.getValue( "build/resources[1]/excludes[1]" ) ); + + assertEquals( 1, ( (List) pom.getValue( "build/testResources" ) ).size() ); + assertPathSuffixEquals( "res/test", pom.getValue( "build/testResources[1]/directory" ) ); + assertPathSuffixEquals( "test", pom.getValue( "build/testResources[1]/targetPath" ) ); + assertEquals( Boolean.TRUE, pom.getValue( "build/testResources[1]/filtering" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/testResources[1]/includes" ) ).size() ); + assertPathSuffixEquals( "test.included", pom.getValue( "build/testResources[1]/includes[1]" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/testResources[1]/excludes" ) ).size() ); + assertPathSuffixEquals( "test.excluded", pom.getValue( "build/testResources[1]/excludes[1]" ) ); + + assertEquals( 1, ( (List) pom.getValue( "build/extensions" ) ).size() ); + assertEquals( "org.apache.maven.its.ext", pom.getValue( "build/extensions[1]/groupId" ) ); + assertEquals( "ext", pom.getValue( "build/extensions[1]/artifactId" ) ); + assertEquals( "3.0", pom.getValue( "build/extensions[1]/version" ) ); + + assertEquals( 1, ( (List) pom.getValue( "build/plugins" ) ).size() ); + assertEquals( "org.apache.maven.its.plugins", pom.getValue( "build/plugins[1]/groupId" ) ); + assertEquals( "maven-it-plugin-build", pom.getValue( "build/plugins[1]/artifactId" ) ); + assertEquals( "2.1-SNAPSHOT", pom.getValue( "build/plugins[1]/version" ) ); + assertEquals( "test.properties", pom.getValue( "build/plugins[1]/configuration/outputFile" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/plugins[1]/executions" ) ).size() ); + assertEquals( "test", pom.getValue( "build/plugins[1]/executions[1]/id" ) ); + assertEquals( "validate", pom.getValue( "build/plugins[1]/executions[1]/phase" ) ); + assertEquals( "pom.properties", pom.getValue( "build/plugins[1]/executions[1]/configuration/outputFile" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() ); + assertEquals( "eval", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/plugins[1]/dependencies" ) ).size() ); + assertEquals( "org.apache.maven.its", pom.getValue( "build/plugins[1]/dependencies[1]/groupId" ) ); + assertEquals( "build-plugin-dep", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) ); + assertEquals( "0.3", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) ); + assertEquals( "zip", pom.getValue( "build/plugins[1]/dependencies[1]/type" ) ); + assertEquals( 1, ( (List) pom.getValue( "build/plugins[1]/dependencies[1]/exclusions" ) ).size() ); + assertEquals( "org.apache.maven.its", pom.getValue( "build/plugins[1]/dependencies[1]/exclusions[1]/groupId" ) ); + assertEquals( "excluded-build-plugin-dep", + pom.getValue( "build/plugins[1]/dependencies[1]/exclusions[1]/artifactId" ) ); + + assertEquals( Boolean.TRUE, pom.getValue( "reporting/excludeDefaults" ) ); + assertPathSuffixEquals( "docs", pom.getValue( "reporting/outputDirectory" ) ); + + assertEquals( 1, ( (List) pom.getValue( "reporting/plugins" ) ).size() ); + assertEquals( "org.apache.maven.its.plugins", pom.getValue( "reporting/plugins[1]/groupId" ) ); + assertEquals( "maven-it-plugin-reporting", pom.getValue( "reporting/plugins[1]/artifactId" ) ); + assertEquals( "2.0-SNAPSHOT", pom.getValue( "reporting/plugins[1]/version" ) ); + assertEquals( "test.html", pom.getValue( "reporting/plugins[1]/configuration/outputFile" ) ); + assertEquals( 1, ( (List) pom.getValue( "reporting/plugins[1]/reportSets" ) ).size() ); + assertEquals( "it", pom.getValue( "reporting/plugins[1]/reportSets[1]/id" ) ); + assertEquals( "index.html", pom.getValue( "reporting/plugins[1]/reportSets[1]/configuration/outputFile" ) ); + assertEquals( 1, ( (List) pom.getValue( "reporting/plugins[1]/reportSets[1]/reports" ) ).size() ); + assertEquals( "run", pom.getValue( "reporting/plugins[1]/reportSets[1]/reports[1]" ) ); + } + + /* MNG-2309*/ + + public void testProfileInjectionOrder() + throws Exception + { + PomTestWrapper pom = + buildPom( "profile-injection-order", "pom-a", "pom-b", "pom-e", "pom-c", "pom-d" ); + assertEquals( "e", pom.getValue( "properties[1]/pomProperty" ) ); + } + + public void testPropertiesInheritance() + throws Exception + { + PomTestWrapper pom = buildPom( "properties-inheritance/sub" ); + assertEquals( "parent-property", pom.getValue( "properties/parentProperty" ) ); + assertEquals( "child-property", pom.getValue( "properties/childProperty" ) ); + assertEquals( "child-override", pom.getValue( "properties/overriddenProperty" ) ); + } + + /* MNG-4102*/ + public void testInheritedPropertiesInterpolatedWithValuesFromChildWithoutProfiles() + throws Exception + { + PomTestWrapper pom = buildPom( "inherited-properties-interpolation/no-profile/sub" ); + + assertEquals( "CHILD", pom.getValue( "properties/overridden" ) ); + assertEquals( "CHILD", pom.getValue( "properties/interpolated" ) ); + } + + /* MNG-4102 */ + public void testInheritedPropertiesInterpolatedWithValuesFromChildWithActiveProfiles() + throws Exception + { + PomTestWrapper pom = buildPom( "inherited-properties-interpolation/active-profile/sub" ); + + assertEquals(1, pom.getDomainModel().getModel().getProfiles().size()); + + buildPom( "inherited-properties-interpolation/active-profile/sub", "it-parent", "it-child" ); + assertEquals( "CHILD", pom.getValue( "properties/overridden" ) ); + assertEquals( "CHILD", pom.getValue( "properties/interpolated" ) ); + } + + /* MNG-3545 */ + public void testProfileDefaultActivation() + throws Exception + { + PomTestWrapper pom = buildPom( "profile-default-deactivation" , "profile4"); + assertEquals(1, pom.getMavenProject().getActiveProfiles().size() ); + assertEquals(1, ( (List) pom.getValue( "build/plugins" )).size() ); + assertEquals("2.1", pom.getValue( "build/plugins[1]/version" )); + } + + /* MNG-1995 */ + public void testBooleanInterpolation() + throws Exception + { + PomTestWrapper pom = buildPom( "boolean-interpolation" ); + assertTrue ((Boolean) pom.getValue( "repositories[2]/releases/enabled" ) ); + assertTrue((Boolean) pom.getValue( "build/resources[1]/filtering" ) ); + } + + + /* MNG-3899 */ + public void testBuildExtensionInheritance() + throws Exception + { + PomTestWrapper pom = buildPom( "build-extension-inheritance/sub" ); + assertEquals(3, ( (List) pom.getValue( "build/extensions" )).size() ); + assertEquals("b", pom.getValue( "build/extensions[1]/artifactId" ) ); + assertEquals("a", pom.getValue( "build/extensions[2]/artifactId" ) ); + assertEquals("0.2", pom.getValue( "build/extensions[2]/version" ) ); + assertEquals("c", pom.getValue( "build/extensions[3]/artifactId" ) ); + } + + /*MNG-1957*/ + public void testJdkActivation() + throws Exception + { + Properties props = new Properties(); + props.put("java.version", "1.5.0_15"); + + PomTestWrapper pom = buildPom( "jdk-activation", props ); + assertEquals(3, pom.getMavenProject().getActiveProfiles().size()); + assertEquals("PASSED", pom.getValue("properties/jdkProperty3")); + assertEquals("PASSED", pom.getValue("properties/jdkProperty2")); + assertEquals("PASSED", pom.getValue("properties/jdkProperty1")); + } + + /* MNG-2174 */ + public void testProfilePluginMngDependencies() + throws Exception + { + PomTestWrapper pom = buildPom( "profile-plugin-mng-dependencies/sub" , "maven-core-it"); + assertEquals("a", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) ); + } + + /** MNG-4116 */ + public void testPercentEncodedUrlsMustNotBeDecoded() + throws Exception + { + PomTestWrapper pom = this.buildPom( "url-no-decoding" ); + assertEquals( "http://maven.apache.org/spacy%20path", pom.getValue( "url" ) ); + assertEquals( "http://svn.apache.org/viewvc/spacy%20path", pom.getValue( "scm/url" ) ); + assertEquals( "scm:svn:svn+ssh://svn.apache.org/spacy%20path", pom.getValue( "scm/connection" ) ); + assertEquals( "scm:svn:svn+ssh://svn.apache.org/spacy%20path", pom.getValue( "scm/developerConnection" ) ); + assertEquals( "http://issues.apache.org/spacy%20path", pom.getValue( "issueManagement/url" ) ); + assertEquals( "http://ci.apache.org/spacy%20path", pom.getValue( "ciManagement/url" ) ); + assertEquals( "scm:svn:svn+ssh://dist.apache.org/spacy%20path", + pom.getValue( "distributionManagement/repository/url" ) ); + assertEquals( "scm:svn:svn+ssh://snap.apache.org/spacy%20path", + pom.getValue( "distributionManagement/snapshotRepository/url" ) ); + assertEquals( "scm:svn:svn+ssh://site.apache.org/spacy%20path", + pom.getValue( "distributionManagement/site/url" ) ); + } + + public void testPluginManagementInheritance() + throws Exception + { + PomTestWrapper pom = this.buildPom( "plugin-management-inheritance"); + assertEquals("0.1-stub-SNAPSHOT", pom.getValue( "build/pluginManagement/plugins[1]/version" ) ); + } + + public void testProfilePlugins() + throws Exception + { + PomTestWrapper pom = this.buildPom( "profile-plugins", "standard"); + assertEquals( 2, ( (List) pom.getValue( "build/plugins" ) ).size() ); + assertEquals("maven-assembly2-plugin", pom.getValue( "build/plugins[2]/artifactId" ) ); + } + + public void testPluginInheritanceSimple() + throws Exception + { + PomTestWrapper pom = this.buildPom( "plugin-inheritance-simple/sub"); + assertEquals( 2, ( (List) pom.getValue( "build/plugins" ) ).size() ); + } + + public void testPluginManagementDuplicate() + throws Exception + { + PomTestWrapper pom = this.buildPom( "plugin-management-duplicate/sub"); + assertEquals( 20, ( (List) pom.getValue( "build/pluginManagement/plugins" ) ).size() ); + } + + public void testDistributionManagement() + throws Exception + { + PomTestWrapper pom = this.buildPom( "distribution-management"); + assertEquals("legacy", pom.getValue( "distributionManagement/repository/layout" )); +} + + private void assertPathSuffixEquals( String expected, Object actual ) + { + String a = actual.toString(); + a = a.substring( a.length() - expected.length() ).replace( '\\', '/' ); + assertEquals( expected, a ); + } private void assertPathWithNormalizedFileSeparators( Object value ) { assertEquals( new File( value.toString() ).getPath(), value.toString() ); } - - private PomTestWrapper buildPom( String pomPath ) - throws IOException - { - File pomFile = new File( testDirectory , pomPath ); - if ( pomFile.isDirectory() ) - { - pomFile = new File( pomFile, "pom.xml" ); - } - return new PomTestWrapper( pomFile, mavenProjectBuilder.buildModel( pomFile, null, null, null ) ); - } - - private PomTestWrapper buildPomFromMavenProject( String pomPath, String profileId ) - throws IOException + + private PomTestWrapper buildPom( String pomPath, Properties properties) + throws Exception + { + File pomFile = new File( testDirectory , pomPath ); + if ( pomFile.isDirectory() ) + { + pomFile = new File( pomFile, "pom.xml" ); + } + ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration(); + config.setLocalRepository(new DefaultArtifactRepository("default", "", new DefaultRepositoryLayout())); + ProfileActivationContext pCtx = new ProfileActivationContext(null, true); + + config.setExecutionProperties(properties); + config.setGlobalProfileManager(new DefaultProfileManager(pCtx)); + return new PomTestWrapper( pomFile, mavenProjectBuilder.build( pomFile, config ) ); + } + + private PomTestWrapper buildPom( String pomPath, String... profileIds ) + throws Exception { File pomFile = new File( testDirectory , pomPath ); if ( pomFile.isDirectory() ) @@ -962,14 +1443,13 @@ public class PomConstructionTest ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration(); config.setLocalRepository(new DefaultArtifactRepository("default", "", new DefaultRepositoryLayout())); ProfileActivationContext pCtx = new ProfileActivationContext(null, true); - if(profileId != null) + if ( profileIds != null ) { - pCtx.setExplicitlyActiveProfileIds(Arrays.asList(profileId)); + pCtx.setExplicitlyActiveProfileIds( Arrays.asList( profileIds ) ); } - config.setGlobalProfileManager(new DefaultProfileManager(this.getContainer(), pCtx)); - return new PomTestWrapper( pomFile, mavenProjectBuilder.buildFromLocalPath( pomFile, null, null, null, - config, mavenProjectBuilder ) ); + config.setGlobalProfileManager(new DefaultProfileManager(pCtx)); + return new PomTestWrapper( pomFile, mavenProjectBuilder.build( pomFile, config ) ); } private Model buildMixin( String mixinPath ) diff --git a/maven-project/src/test/java/org/apache/maven/project/ProjectClasspathTest.java b/maven-project/src/test/java/org/apache/maven/project/ProjectClasspathTest.java index 3edb1230e4..8ea4444f41 100644 --- a/maven-project/src/test/java/org/apache/maven/project/ProjectClasspathTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/ProjectClasspathTest.java @@ -59,6 +59,8 @@ public class ProjectClasspathTest assertNull( "Check no test dependencies are transitive", artifact ); artifact = getArtifact( project, "maven-test-test", "scope-compile" ); + assertNotNull(artifact); + System.out.println( "a = " + artifact ); System.out.println( "b = " + artifact.getScope() ); assertEquals( "Check scope", "test", artifact.getScope() ); diff --git a/maven-project/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java b/maven-project/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java index 86d3317771..b0b95231c7 100644 --- a/maven-project/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java +++ b/maven-project/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java @@ -20,22 +20,13 @@ package org.apache.maven.project.harness; */ import java.io.*; -import java.util.HashMap; import java.util.Iterator; -import java.util.List; -import java.util.Map; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.JXPathNotFoundException; import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl; -import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.apache.maven.project.builder.PomClassicDomainModel; +import org.apache.maven.model.PomClassicDomainModel; import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.model.ModelProperty; -import org.codehaus.plexus.util.WriterFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; public class PomTestWrapper { @@ -68,11 +59,7 @@ public class PomTestWrapper } this.domainModel = domainModel; this.pomFile = pomFile; - try { - context = JXPathContext.newContext( new MavenXpp3Reader().read(domainModel.getInputStream())); - } catch (XmlPullParserException e) { - throw new IOException(e.getMessage()); - } + context = JXPathContext.newContext( domainModel.getModel()); } public PomTestWrapper( File pomFile, MavenProject mavenProject ) @@ -107,11 +94,7 @@ public class PomTestWrapper } this.domainModel = new PomClassicDomainModel( file ); - try { - context = JXPathContext.newContext( new MavenXpp3Reader().read(domainModel.getInputStream())); - } catch (XmlPullParserException e) { - throw new IOException(e.getMessage()); - } + context = JXPathContext.newContext( domainModel.getModel() ); } public MavenProject getMavenProject() @@ -120,58 +103,26 @@ public class PomTestWrapper } public PomClassicDomainModel getDomainModel() - { - if(domainModel == null && mavenProject != null) + throws IOException { + if ( domainModel == null && mavenProject != null ) { - try { - return convertToDomainModel(mavenProject.getModel()); - } catch (IOException e) { - - } + domainModel = new PomClassicDomainModel( mavenProject.getModel() ); + int lineageCount = 1; + for ( MavenProject parent = mavenProject.getParent(); parent != null; parent = parent.getParent() ) + { + lineageCount++; + } + domainModel.setLineageCount( lineageCount ); } return this.domainModel; } - private PomClassicDomainModel convertToDomainModel(Model model) throws IOException - { - if ( model == null ) - { - throw new IllegalArgumentException( "model: null" ); - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Writer out = null; - MavenXpp3Writer writer = new MavenXpp3Writer(); - try - { - out = WriterFactory.newXmlWriter( baos ); - writer.write( out, model ); - } - finally - { - if ( out != null ) - { - out.close(); - } - } - return new PomClassicDomainModel(new ByteArrayInputStream(baos.toByteArray())); - } - public File getBasedir() { return ( pomFile != null ) ? pomFile.getParentFile() : null; } - public String getValueOfProjectUri( String projectUri, boolean withResolvedValue ) - throws IOException - { - if ( projectUri.contains( "#collection" ) || projectUri.contains( "#set" ) ) - { - throw new IllegalArgumentException( "projectUri: contains a collection or set" ); - } - return asMap( withResolvedValue ).get( projectUri ); - } - public void setValueOnModel( String expression, Object value ) { context.setValue( expression, value ); @@ -218,106 +169,4 @@ public class PomTestWrapper return context.getValue( expression ) != null && context.getValue( expression ).equals( value ); } - public Map asMap( boolean withResolvedValues ) - throws IOException - { - Map map = new HashMap(); - for ( ModelProperty mp : domainModel.getModelProperties() ) - { - if ( withResolvedValues ) - { - map.put( mp.getUri(), mp.getResolvedValue() ); - } - else - { - map.put( mp.getUri(), mp.getValue() ); - } - - } - return map; - } - - public boolean containsModelProperty( ModelProperty modelProperty ) - throws IOException - { - return domainModel.getModelProperties().contains( modelProperty ); - } - - public boolean containsAllModelPropertiesOf( List modelProperties ) - throws IOException - { - for ( ModelProperty mp : modelProperties ) - { - if ( !containsModelProperty( mp ) ) - { - return false; - } - } - return true; - } - - public boolean matchModelProperties( List hasProperties, List doesNotHaveProperties ) - throws IOException - { - return containsAllModelPropertiesOf( hasProperties ) && containNoModelPropertiesOf( doesNotHaveProperties ); - } - - public boolean matchUris( List hasAllUris, List doesNotHaveUris ) - throws IOException - { - return hasAllUris( hasAllUris ) && hasNoUris( doesNotHaveUris ); - } - - public boolean containNoModelPropertiesOf( List modelProperties ) - throws IOException - { - for ( ModelProperty mp : modelProperties ) - { - if ( containsModelProperty( mp ) ) - { - return false; - } - } - return true; - } - - public boolean hasUri( String uri ) - throws IOException - { - for ( ModelProperty mp : domainModel.getModelProperties() ) - { - if ( mp.getValue().equals( uri ) ) - { - return true; - } - } - return false; - } - - public boolean hasAllUris( List uris ) - throws IOException - { - for ( String s : uris ) - { - if ( !hasUri( s ) ) - { - return false; - } - } - return true; - } - - public boolean hasNoUris( List uris ) - throws IOException - { - for ( String s : uris ) - { - if ( hasUri( s ) ) - { - return false; - } - } - return true; - } - } diff --git a/maven-project/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java b/maven-project/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java index 5da9a35f26..a928589fd2 100644 --- a/maven-project/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java @@ -82,7 +82,8 @@ public class ProjectInheritanceTest assertNotNull( c ); // inherited from depMgmt - assertTrue("Incorrect scope for " + a.getDependencyConflictId(), a.getScope().equals("compile")); + System.out.println(a.getScope()); + assertTrue("Incorrect scope for " + a.getDependencyConflictId(), a.getScope().equals("test")); // transitive dep, overridden b depMgmt assertTrue("Incorrect scope for " + b.getDependencyConflictId(), b.getScope().equals("runtime")); diff --git a/maven-project/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java b/maven-project/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java index df19eadcea..de63e3063f 100644 --- a/maven-project/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java +++ b/maven-project/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java @@ -69,12 +69,12 @@ public class ProjectInheritanceTest System.out.println( "Child SCM developer connection is: " + project1.getScm().getDeveloperConnection() ); - assertEquals( project1.getScm().getUrl(), project0.getScm().getUrl() + "/p1" ); + assertEquals( project1.getScm().getUrl(), project0.getScm().getUrl() + "/modules/p1" ); assertEquals( project1.getScm().getConnection(), project0.getScm().getConnection() - + "/p1" ); + + "/modules/p1" ); assertEquals( project1.getScm().getDeveloperConnection(), project0.getScm() .getDeveloperConnection() - + "/p1" ); + + "/modules/p1" ); } public void testScmInfoCalculatedCorrectlyOnChildOnlyRead() @@ -93,10 +93,9 @@ public class ProjectInheritanceTest System.out.println( "Child SCM developer connection is: " + project1.getScm().getDeveloperConnection() ); - assertEquals( project1.getScm().getUrl(), "http://host/viewer?path=/p0/p1" ); - assertEquals( project1.getScm().getConnection(), "scm:svn:http://host/p0/p1" ); - assertEquals( project1.getScm().getDeveloperConnection(), - "scm:svn:https://host/p0/p1" ); + assertEquals( "http://host/viewer?path=/p0/modules/p1", project1.getScm().getUrl() ); + assertEquals( "scm:svn:http://host/p0/modules/p1", project1.getScm().getConnection() ); + assertEquals( "scm:svn:https://host/p0/modules/p1", project1.getScm().getDeveloperConnection() ); } // public void testScmInfoCalculatedCorrectlyOnChildReadFromLocalRepository() diff --git a/maven-project/src/test/java/org/apache/maven/project/processor/ModelProcessorTest.java b/maven-project/src/test/java/org/apache/maven/project/processor/ModelProcessorTest.java deleted file mode 100644 index cec5a9797e..0000000000 --- a/maven-project/src/test/java/org/apache/maven/project/processor/ModelProcessorTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.ArrayList; - -import junit.framework.TestCase; - -import org.apache.maven.model.Model; -import org.apache.maven.model.Parent; - -public class ModelProcessorTest extends TestCase -{ - public void testModelProcessorVersion() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setVersion("1.0"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("1.0", targetModel.getVersion()); - } - - public void testModelProcessorVersionFromParent() - { - Model targetModel = new Model(); - Model childModel = new Model(); - - Parent parent = new Parent(); - parent.setVersion("1.0"); - childModel.setParent(parent); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("1.0", targetModel.getVersion()); - } - - public void testModelProcessorGroupId() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setGroupId("gid"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("gid", targetModel.getGroupId()); - } - - public void testModelProcessorGroupIdFromParent() - { - Model targetModel = new Model(); - Model childModel = new Model(); - - Parent parent = new Parent(); - parent.setGroupId("gid"); - childModel.setParent(parent); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("gid", targetModel.getGroupId()); - } - - public void testModelVersion() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setModelVersion("4.0"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("4.0", targetModel.getModelVersion()); - } - - public void testPackaging() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setPackaging("pom"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertEquals("pom", targetModel.getPackaging()); - } - - public void testNameSpecialized() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setName("name"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, true); - assertEquals("name", targetModel.getName()); - } - - public void testNameNotSpecialized() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setName("name"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertNull (targetModel.getName()); - } - - public void testDescriptionSpecialized() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setDescription("description"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, true); - assertEquals("description", targetModel.getDescription()); - } - - public void testDescriptionNotSpecialized() - { - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setDescription("description"); - - ModelProcessor mp = new ModelProcessor( new ArrayList()); - mp.process(null, childModel, targetModel, false); - assertNull(targetModel.getDescription()); - } -} diff --git a/maven-project/src/test/java/org/apache/maven/project/processor/ModuleTest.java b/maven-project/src/test/java/org/apache/maven/project/processor/ModuleTest.java deleted file mode 100644 index e21f27b61c..0000000000 --- a/maven-project/src/test/java/org/apache/maven/project/processor/ModuleTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.apache.maven.project.processor; - -import java.util.Arrays; - -import org.apache.maven.model.Model; - -import junit.framework.TestCase; - -public class ModuleTest extends TestCase { - - public void testIsMostSpecialized() - { - ModuleProcessor proc = new ModuleProcessor(); - - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setModules(Arrays.asList("m1", "m2")); - - proc.process(null, childModel, targetModel, true); - - assertEquals(2, targetModel.getModules().size()); - assertEquals("m1", targetModel.getModules().get(0)); - assertEquals("m2", targetModel.getModules().get(1)); - } - - public void testIsNotMostSpecialized() - { - ModuleProcessor proc = new ModuleProcessor(); - - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setModules(Arrays.asList("m1", "m2")); - - proc.process(null, childModel, targetModel, false); - - assertEquals(0, targetModel.getModules().size()); - } - - public void testImmutable() - { - ModuleProcessor proc = new ModuleProcessor(); - - Model targetModel = new Model(); - Model childModel = new Model(); - childModel.setModules(Arrays.asList("m1", "m2")); - - proc.process(null, childModel, targetModel, true); - - childModel.getModules().set(0, "m0"); - - assertEquals("m1", targetModel.getModules().get(0)); - } - -} diff --git a/maven-project/src/test/resources-project-builder/baseurl-interpolation/pom.xml b/maven-project/src/test/resources-project-builder/baseurl-interpolation/pom.xml new file mode 100644 index 0000000000..206a54ccc6 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/baseurl-interpolation/pom.xml @@ -0,0 +1,38 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng3760 + test1 + 1.0-SNAPSHOT + + Maven Integration Test :: MNG-3760 + + Test interpolation of ${project.baseUri} + + + + + ${project.baseUri} + + diff --git a/maven-project/src/test/resources-project-builder/boolean-interpolation/pom.xml b/maven-project/src/test/resources-project-builder/boolean-interpolation/pom.xml new file mode 100644 index 0000000000..98dc8ef0fb --- /dev/null +++ b/maven-project/src/test/resources-project-builder/boolean-interpolation/pom.xml @@ -0,0 +1,82 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng1995 + test1 + 1.0 + + Maven Integration Test :: MNG-1995 + + Verify that POM fields that are of type boolean can be interpolated with expressions. + + + + true + true + + + + + maven-core-it + file:///${basedir}/repo + + + ${releasesEnabled} + + + + + + + + src/main/resources + + ${filter.resources} + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + target/expression.properties + + project/build/resources/0/filtering + project/repositories + + + + + test + validate + + eval + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/build-extension-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/build-extension-inheritance/pom.xml new file mode 100644 index 0000000000..2d95cb1c5d --- /dev/null +++ b/maven-project/src/test/resources-project-builder/build-extension-inheritance/pom.xml @@ -0,0 +1,49 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng3899 + parent + 0.1 + pom + + Maven Integration Test :: MNG-3899 + + Test that build extensions are properly merged during inheritance. + + + + + + org.apache.maven.its.mng3899 + a + 0.1 + + + org.apache.maven.its.mng3899 + c + 0.1 + + + + diff --git a/maven-project/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml b/maven-project/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml new file mode 100644 index 0000000000..4411b8929f --- /dev/null +++ b/maven-project/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml @@ -0,0 +1,75 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng3899 + parent + 0.1 + + + child + + Maven Integration Test :: MNG-3899 + + Test that build extensions are properly merged during inheritance. + + + + + + + org.apache.maven.its.mng3899 + b + 0.1 + + + + org.apache.maven.its.mng3899 + a + 0.2 + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/extension.properties + + project/build/extensions + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/complete-model/w-parent/pom.xml b/maven-project/src/test/resources-project-builder/complete-model/w-parent/pom.xml new file mode 100644 index 0000000000..ebcd7d1ee9 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/complete-model/w-parent/pom.xml @@ -0,0 +1,31 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng + parent + 0.1 + pom + + + diff --git a/maven-project/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml b/maven-project/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml new file mode 100644 index 0000000000..2fe674abb6 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml @@ -0,0 +1,319 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng + parent + 0.1 + + + org.apache.maven.its.mng + test + 0.2 + pom + + project-name + project-description + http://project.url/ + 2009 + + project-org + http://project-org.url/ + + + + project-license + http://project.url/license + repo + free + + + + + + dev + project-developer + developer@ + http://developer + developer + http://devel.org + + devel + + -1 + + yes + + + + + + project-contributor + contributor@ + http://contributor + contributor + http://contrib.org + + contrib + + +1 + + yes + + + + + + + project-mailing-list + subscribe@ + unsubscribe@ + post@ + mail-archive + + other-archive + + + + + + 2.0.1 + + + + http://project.url/trunk + http://project.url/scm + https://project.url/scm + TAG + + + issues + http://project.url/issues + + + ci + http://project.url/ci + + + irc +
ci@
+ true + false + false + false + + ci + +
+
+
+ + + http://project.url/dist + project.distros + distros + + + http://project.url/snaps + project.snaps + snaps + false + + + http://project.url/site + project.site + docs + + http://project.url/download + + reloc-gid + reloc-aid + reloc-version + project-reloc-msg + + + + + sub + + + + project-property + + + + + + org.apache.maven.its + managed-dep + 0.1 + war + runtime + + + org.apache.maven.its + excluded-managed-dep + + + + + + + + + org.apache.maven.its + dep + 0.2 + ejb + test + true + + + org.apache.maven.its + excluded-dep + + + + + + + + project-remote-repo + http://project.url/remote + repo + + + + + + + org.apache.maven.its.ext + ext + 3.0 + + + + test + build + sources/main + sources/scripts + sources/test + build/main + build/test + coreit + + + res/main + true + main + + main.included + + + main.excluded + + + + + + res/test + true + test + + test.included + + + test.excluded + + + + + src/main/filter/it.properties + + + + + org.apache.maven.its.plugins + maven-it-plugin-build + 2.1-SNAPSHOT + + test.properties + + + + test + validate + + eval + + + pom.properties + + + + + + org.apache.maven.its + build-plugin-dep + 0.3 + zip + + + org.apache.maven.its + excluded-build-plugin-dep + + + + + + + + + + true + docs + + + + org.apache.maven.its.plugins + maven-it-plugin-reporting + 2.0-SNAPSHOT + + test.html + + + + it + + run + + + index.html + + + + + + +
diff --git a/maven-project/src/test/resources-project-builder/complete-model/wo-parent/pom.xml b/maven-project/src/test/resources-project-builder/complete-model/wo-parent/pom.xml new file mode 100644 index 0000000000..72dd787276 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/complete-model/wo-parent/pom.xml @@ -0,0 +1,313 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng + test + 0.2 + pom + + project-name + project-description + http://project.url/ + 2009 + + project-org + http://project-org.url/ + + + + project-license + http://project.url/license + repo + free + + + + + + dev + project-developer + developer@ + http://developer + developer + http://devel.org + + devel + + -1 + + yes + + + + + + project-contributor + contributor@ + http://contributor + contributor + http://contrib.org + + contrib + + +1 + + yes + + + + + + + project-mailing-list + subscribe@ + unsubscribe@ + post@ + mail-archive + + other-archive + + + + + + 2.0.1 + + + + http://project.url/trunk + http://project.url/scm + https://project.url/scm + TAG + + + issues + http://project.url/issues + + + ci + http://project.url/ci + + + irc +
ci@
+ true + false + false + false + + ci + +
+
+
+ + + http://project.url/dist + project.distros + distros + + + http://project.url/snaps + project.snaps + snaps + false + + + http://project.url/site + project.site + docs + + http://project.url/download + + reloc-gid + reloc-aid + reloc-version + project-reloc-msg + + + + + sub + + + + project-property + + + + + + org.apache.maven.its + managed-dep + 0.1 + war + runtime + + + org.apache.maven.its + excluded-managed-dep + + + + + + + + + org.apache.maven.its + dep + 0.2 + ejb + test + true + + + org.apache.maven.its + excluded-dep + + + + + + + + project-remote-repo + http://project.url/remote + repo + + + + + + + org.apache.maven.its.ext + ext + 3.0 + + + + test + build + sources/main + sources/scripts + sources/test + build/main + build/test + coreit + + + res/main + true + main + + main.included + + + main.excluded + + + + + + res/test + true + test + + test.included + + + test.excluded + + + + + src/main/filter/it.properties + + + + + org.apache.maven.its.plugins + maven-it-plugin-build + 2.1-SNAPSHOT + + test.properties + + + + test + validate + + eval + + + pom.properties + + + + + + org.apache.maven.its + build-plugin-dep + 0.3 + zip + + + org.apache.maven.its + excluded-build-plugin-dep + + + + + + + + + + true + docs + + + + org.apache.maven.its.plugins + maven-it-plugin-reporting + 2.0-SNAPSHOT + + test.html + + + + it + + run + + + index.html + + + + + + +
diff --git a/maven-project/src/test/resources-project-builder/dependencies-with-different-versions/pom.xml b/maven-project/src/test/resources-project-builder/dependencies-with-different-versions/pom.xml index dad056c78d..8d4631935c 100644 --- a/maven-project/src/test/resources-project-builder/dependencies-with-different-versions/pom.xml +++ b/maven-project/src/test/resources-project-builder/dependencies-with-different-versions/pom.xml @@ -3,6 +3,7 @@ 4.0.0 a b + 1.0 commons-collections diff --git a/maven-project/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml b/maven-project/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml new file mode 100644 index 0000000000..6d642626c3 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml @@ -0,0 +1,31 @@ + + + + + + 4.0.0 + + org.apache.maven + maven-parent + 11 + pom + + Apache Maven + diff --git a/maven-project/src/test/resources-project-builder/dependency-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/dependency-inheritance/pom.xml new file mode 100644 index 0000000000..c2c061c327 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/dependency-inheritance/pom.xml @@ -0,0 +1,48 @@ + + + + + + 4.0.0 + + org.apache.maven + maven-parent + 11 + maven-parent.xml + + org.apache.maven + maven + 3.0-SNAPSHOT + pom + + + 3.8.1 + + + + + junit + junit + ${junitVersion} + test + + + + diff --git a/maven-project-builder/pom.xml b/maven-project/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml similarity index 85% rename from maven-project-builder/pom.xml rename to maven-project/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml index f5a1229580..116e5bd051 100644 --- a/maven-project-builder/pom.xml +++ b/maven-project/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml @@ -21,15 +21,7 @@ maven-project-builder 3.0-SNAPSHOT Maven Project Builder - - - org.sonatype.spice - model-builder - - - org.codehaus.plexus - plexus-utils - + junit junit diff --git a/maven-project/src/test/resources-project-builder/distribution-management/pom.xml b/maven-project/src/test/resources-project-builder/distribution-management/pom.xml new file mode 100644 index 0000000000..0c98793eca --- /dev/null +++ b/maven-project/src/test/resources-project-builder/distribution-management/pom.xml @@ -0,0 +1,39 @@ + + + + + + 4.0.0 + + org.apache.maven.its.it0061 + maven-it-it0061 + 1.0 + jar + + Maven Integration Test :: it0061 + + + + test + file:target/test-repo + legacy + + + diff --git a/maven-project/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml b/maven-project/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml index 8e799af3ec..fde9e14965 100644 --- a/maven-project/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml +++ b/maven-project/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml @@ -26,7 +26,7 @@ 1.0 - default-execution-id + default process diff --git a/maven-project/src/test/resources-project-builder/empty-scm/pom.xml b/maven-project/src/test/resources-project-builder/empty-scm/pom.xml new file mode 100644 index 0000000000..a0462ddd95 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/empty-scm/pom.xml @@ -0,0 +1,58 @@ + + + + + + 4.0.0 + + + + org.apache.maven.its.mng3843 + test-1 + 0.1 + + test + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/pom.properties + + project + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml b/maven-project/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml index 513c6c48b3..5b65ea6501 100644 --- a/maven-project/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml +++ b/maven-project/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml @@ -1,6 +1,7 @@ 4.0.0 + test nexus pom Nexus Repository Manager diff --git a/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml new file mode 100644 index 0000000000..640cf2881c --- /dev/null +++ b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml @@ -0,0 +1,50 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4102 + parent + 0.1 + pom + + Maven Integration Test :: MNG-4102 + + Verify that the effective value of an inherited property reflects the values of any nested property + as defined by the child. This boils down to the order of inheritance and (parent) interpolation. + + + + PARENT + + ${overridden} + + + + + it-parent + + true + + + + diff --git a/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml new file mode 100644 index 0000000000..2aa40dedd7 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml @@ -0,0 +1,54 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng4102 + parent + 0.1 + + + org.apache.maven.its.mng4102 + test + 0.1 + jar + + Maven Integration Test :: MNG-4102 :: Child + + Verify that the effective value of an inherited property reflects the values of any nested property + as defined by the child. This boils down to the order of inheritance and (parent) interpolation. + + + + CHILD + + + + + it-child + + true + + + + diff --git a/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml new file mode 100644 index 0000000000..3e11a6d63c --- /dev/null +++ b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml @@ -0,0 +1,41 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4102 + parent + 0.1 + pom + + Maven Integration Test :: MNG-4102 + + Verify that the effective value of an inherited property reflects the values of any nested property + as defined by the child. This boils down to the order of inheritance and (parent) interpolation. + + + + PARENT + + ${overridden} + + diff --git a/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml new file mode 100644 index 0000000000..49c8fd21e3 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml @@ -0,0 +1,45 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng4102 + parent + 0.1 + + + org.apache.maven.its.mng4102 + test + 0.1 + jar + + Maven Integration Test :: MNG-4102 :: Child + + Verify that the effective value of an inherited property reflects the values of any nested property + as defined by the child. This boils down to the order of inheritance and (parent) interpolation. + + + + CHILD + + diff --git a/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml b/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml new file mode 100644 index 0000000000..c0431f5807 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/jdk-activation/pom.xml @@ -0,0 +1,105 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng1957 + test + 1.0-SNAPSHOT + + Maven Integration Test :: MNG-1957 + + Test that JDK profile activation allows version ranges. + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/jdk.properties + + project/properties + + + + + + + + + + + test-1 + + [1.4,) + + + PASSED + + + + test-2 + + (,100) + + + PASSED + + + + test-3 + + (1.3,100) + + + PASSED + + + + test-4 + + (100,) + + + FAILED + + + + test-5 + + (,1.4) + + + FAILED + + + + diff --git a/maven-project/src/test/resources-project-builder/micromailer/pom.xml b/maven-project/src/test/resources-project-builder/micromailer/pom.xml index 91013e9846..57f85dd801 100644 --- a/maven-project/src/test/resources-project-builder/micromailer/pom.xml +++ b/maven-project/src/test/resources-project-builder/micromailer/pom.xml @@ -1,124 +1,124 @@ - - - 4.0.0 - - - org.sonatype.spice - spice-parent - 11 - spice-parent-9.pom - - - org.sonatype.micromailer - micromailer - 1.0.3 - jar - Micro Mailer - - - scm:svn:http://svn.sonatype.org/spice/trunk/micromailer - http://svn.sonatype.org/spice/trunk/micromailer - scm:svn:https://svn.sonatype.org/spice/trunk/micromailer - - - - - - org.codehaus.plexus - plexus-container-default - 1.0-alpha-47 - jar - compile - - - commons-logging - commons-logging - - - commons-logging - commons-logging-api - - - log4j - log4j - - - - - - org.codehaus.plexus - plexus-utils - 1.5.5 - jar - compile - - - - - org.codehaus.plexus - plexus-velocity - 1.1.7 - jar - compile - - - org.codehaus.plexus - plexus-component-api - - - velocity - velocity - - - commons-collections - commons-collections - - - - - - org.apache.velocity - velocity - 1.5 - jar - compile - - - - - javax.mail - mail - 1.4 - jar - compile - - - - - junit - junit - 3.8.2 - jar - test - - - - - - - - org.codehaus.plexus - plexus-maven-plugin - 1.3.8 - - - - child-descriptor - - - - - - - - + + + 4.0.0 + + + org.sonatype.spice + spice-parent + 11 + spice-parent-9.pom + + + org.sonatype.micromailer + micromailer + 1.0.3 + jar + Micro Mailer + + + scm:svn:http://svn.sonatype.org/spice/trunk/micromailer + http://svn.sonatype.org/spice/trunk/micromailer + scm:svn:https://svn.sonatype.org/spice/trunk/micromailer + + + + + + org.codehaus.plexus + plexus-container-default + 1.0-alpha-47 + jar + compile + + + commons-logging + commons-logging + + + commons-logging + commons-logging-api + + + log4j + log4j + + + + + + org.codehaus.plexus + plexus-utils + 1.5.5 + jar + compile + + + + + org.codehaus.plexus + plexus-velocity + 1.1.7 + jar + compile + + + org.codehaus.plexus + plexus-component-api + + + velocity + velocity + + + commons-collections + commons-collections + + + + + + org.apache.velocity + velocity + 1.5 + jar + compile + + + + + javax.mail + mail + 1.4 + jar + compile + + + + + junit + junit + 3.8.2 + jar + test + + + + + + + + org.codehaus.plexus + plexus-maven-plugin + 1.3.8 + + + + child-descriptor + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/multiple-filters/pom.xml b/maven-project/src/test/resources-project-builder/multiple-filters/pom.xml index aa61a6006b..1141efb5a7 100644 --- a/maven-project/src/test/resources-project-builder/multiple-filters/pom.xml +++ b/maven-project/src/test/resources-project-builder/multiple-filters/pom.xml @@ -3,6 +3,7 @@ 4.0.0 a b + 1.0 diff --git a/maven-project/src/test/resources-project-builder/plugin-config-append/pom.xml b/maven-project/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml similarity index 100% rename from maven-project/src/test/resources-project-builder/plugin-config-append/pom.xml rename to maven-project/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml diff --git a/maven-project/src/test/resources-project-builder/plugin-config-append/subproject/pom.xml b/maven-project/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml similarity index 100% rename from maven-project/src/test/resources-project-builder/plugin-config-append/subproject/pom.xml rename to maven-project/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml diff --git a/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml b/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml new file mode 100644 index 0000000000..48a8d393ba --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml @@ -0,0 +1,90 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng2591 + parent + 1.0 + pom + + Maven Integration Test :: MNG-2591 + + Test aggregation of list configuration items for build plugins when using + 'combine.children=append' attribute. + + + + subproject + + + + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + true + + + + PARENT-1 + PARENT-3 + PARENT-2 + PARENT-4 + + + + + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + true + + + + PARENT-1 + PARENT-3 + PARENT-2 + PARENT-4 + + + + + + + + + + parent + + true + + + + diff --git a/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml b/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml new file mode 100644 index 0000000000..7023503089 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml @@ -0,0 +1,80 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng2591 + parent + 1.0 + + + subproject + 1.0 + jar + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + + target/config.properties + + + CHILD-1 + CHILD-3 + CHILD-2 + CHILD-4 + + + + CHILD-1 + CHILD-3 + CHILD-2 + CHILD-4 + + + + + test + validate + + config + + + + + + + + + + + child + + true + + + + diff --git a/maven-project/src/test/resources-project-builder/plugin-config-properties/pom.xml b/maven-project/src/test/resources-project-builder/plugin-config-properties/pom.xml index c92fbb5f3b..e56603919b 100644 --- a/maven-project/src/test/resources-project-builder/plugin-config-properties/pom.xml +++ b/maven-project/src/test/resources-project-builder/plugin-config-properties/pom.xml @@ -3,6 +3,7 @@ 4.0.0 a b + 1.0 diff --git a/maven-project/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml b/maven-project/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml index a3f4ff6101..827b907535 100644 --- a/maven-project/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml +++ b/maven-project/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml @@ -45,7 +45,7 @@ under the License. - default-execution-id + default child-default diff --git a/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml b/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml new file mode 100644 index 0000000000..37e004440c --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + gid + aid + 1.0 + + + + org.codehaus.modello + modello-maven-plugin + 1.0-alpha-21 + + + + + \ No newline at end of file diff --git a/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml b/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml new file mode 100644 index 0000000000..f6ed4dd499 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml @@ -0,0 +1,20 @@ + + + gid + aid + 1.0 + + 4.0.0 + org.sonatype.nexus + nexus + 1.3.0-SNAPSHOT + + + + org.codehaus.modello + modello-maven-plugin2 + 1.0-alpha-21 + + + + \ No newline at end of file diff --git a/maven-project/src/test/resources-project-builder/plugin-management-duplicate/pom.xml b/maven-project/src/test/resources-project-builder/plugin-management-duplicate/pom.xml index f7df30821b..b59e68befb 100644 --- a/maven-project/src/test/resources-project-builder/plugin-management-duplicate/pom.xml +++ b/maven-project/src/test/resources-project-builder/plugin-management-duplicate/pom.xml @@ -1,70 +1,37 @@ - + http://www.apache.org/licenses/LICENSE-2.0 Unless required by + applicable law or agreed to in writing, software distributed under the + License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. See the License for + the specific language governing permissions and limitations under the + License. + --> - 4.0.0 - org.apache.maven.its.mng4053 - test2 - 1.0-SNAPSHOT - - Maven Integration Test :: MNG-4053 - - Verify that attributes in plugin configuration elements are not erroneously duplicated to other elements when - plugin management is used. - - - - - - - - org.apache.maven.its.plugins - maven-it-plugin-configuration - 2.1-SNAPSHOT - - - - - - org.apache.maven.its.plugins - maven-it-plugin-configuration - 2.1-SNAPSHOT - - - validate - - config - - - target/config.properties - - - - - - - - - - - + gid + aid + 1.0 + + + + + org.apache.maven.its.plugins + + maven-it-plugin-configuration + + 2.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/maven-project/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml b/maven-project/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml new file mode 100644 index 0000000000..5e844b7987 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml @@ -0,0 +1,64 @@ + + + + + + + gid + aid + 1.0 + + 4.0.0 + + org.apache.maven.its.mng4053 + test2 + 1.0-SNAPSHOT + + + + + + maven-compiler-plugin + 0.1-stub-SNAPSHOT + + + maven-jar-plugin + 0.1-stub-SNAPSHOT + + + maven-javadoc-plugin + 0.1-stub-SNAPSHOT + + + maven-resources-plugin + 0.1-stub-SNAPSHOT + + + maven-source-plugin + 0.1-stub-SNAPSHOT + + + maven-surefire-plugin + 0.1-stub-SNAPSHOT + + + + + \ No newline at end of file diff --git a/maven-project/src/test/resources-project-builder/plugin-management-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/plugin-management-inheritance/pom.xml new file mode 100644 index 0000000000..ac4da04b86 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/plugin-management-inheritance/pom.xml @@ -0,0 +1,64 @@ + + + + + + 4.0.0 + + org.apache.maven.its.it0052 + maven-it-it0052 + 1.0 + jar + + Maven Integration Test :: it0052 + Test that source attachment doesn't take place when -DperformRelease=true is missing. + + + + + + + maven-compiler-plugin + 0.1-stub-SNAPSHOT + + + maven-jar-plugin + 0.1-stub-SNAPSHOT + + + maven-javadoc-plugin + 0.1-stub-SNAPSHOT + + + maven-resources-plugin + 0.1-stub-SNAPSHOT + + + maven-source-plugin + 0.1-stub-SNAPSHOT + + + maven-surefire-plugin + 0.1-stub-SNAPSHOT + + + + + diff --git a/maven-project/src/test/resources-project-builder/pom-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/pom-inheritance/pom.xml new file mode 100644 index 0000000000..59cef1d8dc --- /dev/null +++ b/maven-project/src/test/resources-project-builder/pom-inheritance/pom.xml @@ -0,0 +1,188 @@ + + + + + + 4.0.0 + + + + org.apache.maven.its.mng3843 + parent-1 + 0.1 + pom + + parent-name + parent-description + http://parent.url/ + 2008 + + parent-org + http://parent-org.url/ + + + + parent-license + http://parent.url/license + repo + + + + + + parent-developer + + + + + parent-contributor + + + + + + parent-mailing-list + + + + + 2.0 + + + + child-1 + child-2 + + + + http://parent.url/trunk + http://parent.url/scm + https://parent.url/scm + + + http://parent.url/issues + + + http://parent.url/ci + + + + http://parent.url/dist + parent.distros + + + http://parent.url/snaps + parent.snaps + + + http://parent.url/site + parent.site + + http://parent.url/download + + parent-reloc-msg + + + + + parent-property + parent-property + + + + + + org.apache.maven.its.mng3843 + parent-dep-a + 1 + test + + + + + + org.apache.maven.its.mng3843 + parent-dep-b + 1 + test + + + + + + parent-remote-repo + http://parent.url/remote + + + + + initialize + out + src/main + src/scripts + src/test + out/main + out/test + + + res/main + + + + + res/test + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/pom.properties + + project + + + + + + + + + + true + site + + + + + parent-profile + + + diff --git a/maven-project/src/test/resources-project-builder/pom-inheritance/sub/pom.xml b/maven-project/src/test/resources-project-builder/pom-inheritance/sub/pom.xml new file mode 100644 index 0000000000..ae74902875 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/pom-inheritance/sub/pom.xml @@ -0,0 +1,36 @@ + + + + + + 4.0.0 + + + + + org.apache.maven.its.mng3843 + parent-1 + 0.1 + + + child-1 + diff --git a/maven-project/src/test/resources-project-builder/profile-default-deactivation/pom.xml b/maven-project/src/test/resources-project-builder/profile-default-deactivation/pom.xml new file mode 100644 index 0000000000..dfe19253f8 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/profile-default-deactivation/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + org.apache.maven.its.mng3545 + test-artifact + 1.0-SNAPSHOT + + + profile1 + + true + + + + + org.apache.maven.its.plugins + maven-it-plugin-touch + 2.2 + + + + + + profile4 + + + + org.apache.maven.its.plugins + maven-it-plugin-touch + 2.1 + + + + + + diff --git a/maven-project/src/test/resources-project-builder/profile-injection-order/pom.xml b/maven-project/src/test/resources-project-builder/profile-injection-order/pom.xml new file mode 100644 index 0000000000..784996de5f --- /dev/null +++ b/maven-project/src/test/resources-project-builder/profile-injection-order/pom.xml @@ -0,0 +1,68 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng2309 + test + 1.0-SNAPSHOT + jar + + Maven Integration Test :: MNG-2309 + + Test that profiles are injected in declaration order, with the last profile being the most dominant. + + + + + + pom-a + + a + + + + pom-b + + b + + + + pom-c + + c + + + + pom-d + + d + + + + pom-e + + e + + + + diff --git a/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml b/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml new file mode 100644 index 0000000000..118861a34a --- /dev/null +++ b/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml @@ -0,0 +1,77 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng2174 + parent + 1.0-SNAPSHOT + pom + + Maven Integration Test :: MNG-2174 + + Verify that plugin dependencies defined by plugin management of a parent profile are not lost when the + parent's main plugin management section is also present. + + + + sub + + + + + + + org.apache.maven.its.plugins + maven-it-plugin-class-loader + 2.1-SNAPSHOT + + + + + + + + maven-core-it + + true + + + + + + org.apache.maven.its.plugins + maven-it-plugin-class-loader + + + org.apache.maven.its.mng2174 + a + 0.1 + + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml b/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml new file mode 100644 index 0000000000..9c06879520 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml @@ -0,0 +1,62 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng2174 + parent + 1.0-SNAPSHOT + + + org.apache.maven.its.mng2174 + child + 1.0-SNAPSHOT + + Maven Integration Test :: MNG-2174 + + Verify that plugin dependencies defined by plugin management of a parent profile are not lost when the + parent's main plugin management section is also present. + + + + + + org.apache.maven.its.plugins + maven-it-plugin-class-loader + + + test + validate + + mng-2174.properties + target/pcl.properties + + + load + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/profile-plugins/pom.xml b/maven-project/src/test/resources-project-builder/profile-plugins/pom.xml new file mode 100644 index 0000000000..cc305f9788 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/profile-plugins/pom.xml @@ -0,0 +1,50 @@ + + + + + + 4.0.0 + + org.apache.maven + maven + 3.0-SNAPSHOT + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + standard + + true + + + + + org.apache.maven.plugins + maven-assembly2-plugin + + + + + + diff --git a/maven-project/src/test/resources-project-builder/profile-properties-interpolation/pom.xml b/maven-project/src/test/resources-project-builder/profile-properties-interpolation/pom.xml index 71be630444..a95e253b63 100644 --- a/maven-project/src/test/resources-project-builder/profile-properties-interpolation/pom.xml +++ b/maven-project/src/test/resources-project-builder/profile-properties-interpolation/pom.xml @@ -19,8 +19,7 @@ 4.0.0 - org.apache.maven.its.mng3900 - + org.apache.maven.its.mng3900 test 0.1 jar diff --git a/maven-project/src/test/resources-project-builder/properties-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/properties-inheritance/pom.xml new file mode 100644 index 0000000000..6d17dd3a0a --- /dev/null +++ b/maven-project/src/test/resources-project-builder/properties-inheritance/pom.xml @@ -0,0 +1,34 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng3843 + parent-1 + 0.1 + pom + + + parent-property + parent-property + + diff --git a/maven-project/src/test/resources-project-builder/properties-inheritance/sub/pom.xml b/maven-project/src/test/resources-project-builder/properties-inheritance/sub/pom.xml new file mode 100644 index 0000000000..c5394df5c3 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/properties-inheritance/sub/pom.xml @@ -0,0 +1,40 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng3843 + parent-1 + 0.1 + + + org.apache.maven.its.mng3843.child + child-2 + 0.2 + jar + + + child-property + child-override + + diff --git a/maven-project/src/test/resources-project-builder/properties-no-duplication/pom.xml b/maven-project/src/test/resources-project-builder/properties-no-duplication/pom.xml new file mode 100644 index 0000000000..ebdb8b1cc1 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/properties-no-duplication/pom.xml @@ -0,0 +1,11 @@ + + + 4.0.0 + org.apache.maven.its + test-parent + 1.0-SNAPSHOT + + parent + + diff --git a/maven-project/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml b/maven-project/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml new file mode 100644 index 0000000000..9241b8bb76 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + org.apache.maven.its + test-parent + 1.0-SNAPSHOT + + org.apache.maven.its + test + 1.0-SNAPSHOT + + child + + + diff --git a/maven-project/src/test/resources-project-builder/repo-inheritance/pom.xml b/maven-project/src/test/resources-project-builder/repo-inheritance/pom.xml new file mode 100644 index 0000000000..67f9ee6fc9 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/repo-inheritance/pom.xml @@ -0,0 +1,64 @@ + + + + + + 4.0.0 + + org.apache.maven.its.it0043 + maven-it-it0043 + 1.0-SNAPSHOT + + Maven Integration Test :: it0043 + Test for repository inheritence - ensure using the same id overrides the defaults + + + + central + it0043 + file:///${basedir}/target/maven-core-it0043-repo + + + + + + central + it0043 + file:///${basedir}/target/maven-core-it0043-repo + + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + target/expression.properties + + project/repositories + project/pluginRepositories + + + + + + diff --git a/maven-project/src/test/resources-project-builder/reporting-plugin-config/pom.xml b/maven-project/src/test/resources-project-builder/reporting-plugin-config/pom.xml new file mode 100644 index 0000000000..fdb455a090 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/reporting-plugin-config/pom.xml @@ -0,0 +1,51 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng3811 + test-parent + 1.0-SNAPSHOT + pom + + MNG-3811 :: Parent + Test inheritance of reporting plugin configuration + + + child + + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + + true + + parentParam + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml b/maven-project/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml new file mode 100644 index 0000000000..e6018dd604 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml @@ -0,0 +1,47 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng3811 + test-parent + 1.0-SNAPSHOT + + test-child + + MNG-3811 :: Child + + + + + org.apache.maven.its.plugins + maven-it-plugin-configuration + 2.1-SNAPSHOT + + + childParam + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/unc-path/pom.xml b/maven-project/src/test/resources-project-builder/unc-path/pom.xml new file mode 100644 index 0000000000..1e9035c487 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/unc-path/pom.xml @@ -0,0 +1,41 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng3621 + test-parent + 1.0-SNAPSHOT + pom + + MNG-3621 :: Parent + Test inheritance of UNC paths + + + child + + + + + site + file:////host/site/ + + + diff --git a/maven-project/src/test/resources-project-builder/unc-path/sub/pom.xml b/maven-project/src/test/resources-project-builder/unc-path/sub/pom.xml new file mode 100644 index 0000000000..fddd8723bd --- /dev/null +++ b/maven-project/src/test/resources-project-builder/unc-path/sub/pom.xml @@ -0,0 +1,57 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng3621 + test-parent + 1.0-SNAPSHOT + + test-child + + MNG-3621 :: Child + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + target/pom.properties + + project/distributionManagement/site/url + + + + + test + validate + + eval + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/url-append/child/pom.xml b/maven-project/src/test/resources-project-builder/url-append/child/pom.xml new file mode 100644 index 0000000000..1f377df1ff --- /dev/null +++ b/maven-project/src/test/resources-project-builder/url-append/child/pom.xml @@ -0,0 +1,64 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.mng2006 + parent + 0.1 + ../parent/pom.xml + + + child + Child Project + + Test that inheritance of those URLs which automatically append the child's artifact id take the child's + relative location to the parent into account. + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + validate + + eval + + + target/pom.properties + + project/url + project/scm + project/distributionManagement/site + + + + + + + + diff --git a/maven-project/src/test/resources-project-builder/url-append/parent/pom.xml b/maven-project/src/test/resources-project-builder/url-append/parent/pom.xml new file mode 100644 index 0000000000..00a4a349b3 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/url-append/parent/pom.xml @@ -0,0 +1,53 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng2006 + parent + 0.1 + pom + + Maven Integration Test :: MNG-2006 + + Test that inheritance of those URLs which automatically append the child's artifact id take the child's + relative location to the parent into account. + + + + ../child + + + http://project.url/parent + + + http://viewvc.project.url/parent + http://scm.project.url/parent + https://scm.project.url/parent + + + + http://site.project.url/parent + parent.site + + + diff --git a/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml b/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml new file mode 100644 index 0000000000..463772feb2 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml @@ -0,0 +1,36 @@ + + + + + + 4.0.0 + + + + + org.apache.maven.its.mng3846 + parent + 0.1 + + + ap + pom + Another Parent to test multi-level URL adjustment + diff --git a/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml b/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml new file mode 100644 index 0000000000..128e63d12e --- /dev/null +++ b/maven-project/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml @@ -0,0 +1,35 @@ + + + + + + 4.0.0 + + + + + org.apache.maven.its.mng3846 + ap + 0.1 + + + child + Child Project + diff --git a/maven-project/src/test/resources-project-builder/url-no-decoding/pom.xml b/maven-project/src/test/resources-project-builder/url-no-decoding/pom.xml new file mode 100644 index 0000000000..5b92e23ed9 --- /dev/null +++ b/maven-project/src/test/resources-project-builder/url-no-decoding/pom.xml @@ -0,0 +1,64 @@ + + + + + + 4.0.0 + + org.apache.maven.its.mng4116 + test + 1.0-SNAPSHOT + jar + + Maven Integration Test :: MNG-4116 + + Test that the project builder does not decode URLs (which must be done by the transport layer instead). + + + + http://maven.apache.org/spacy%20path + + scm:svn:svn+ssh://svn.apache.org/spacy%20path + scm:svn:svn+ssh://svn.apache.org/spacy%20path + http://svn.apache.org/viewvc/spacy%20path + + + none + http://issues.apache.org/spacy%20path + + + none + http://ci.apache.org/spacy%20path + + + + dist + scm:svn:svn+ssh://dist.apache.org/spacy%20path + + + snap + scm:svn:svn+ssh://snap.apache.org/spacy%20path + + + site + scm:svn:svn+ssh://site.apache.org/spacy%20path + + + diff --git a/maven-repository-mercury/pom.xml b/maven-repository-mercury/pom.xml index 0b3cf1f20b..7648e27917 100644 --- a/maven-repository-mercury/pom.xml +++ b/maven-repository-mercury/pom.xml @@ -20,18 +20,21 @@ under the License. --> + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-repository-mercury + Mercury Repository implementation Mercury implementation for the Maven Repository System - 1.0-alpha-6-SNAPSHOT + 1.0-alpha-7-SNAPSHOT @@ -41,7 +44,7 @@ under the License. maven-repository ${project.version} - + 4.0.0 + - maven org.apache.maven + maven 3.0-SNAPSHOT - 4.0.0 + maven-repository + Maven Repository Repository System interface for Maven. + org.apache.maven @@ -37,7 +41,7 @@ under the License. org.codehaus.plexus plexus-utils - + org.apache.maven maven-compat @@ -50,7 +54,7 @@ under the License. org.apache.maven.wagon wagon-file test - + org.sonatype.plexus plexus-jetty6 diff --git a/maven-repository/src/main/java/org/apache/maven/repository/LegacyRepositorySystem.java b/maven-repository/src/main/java/org/apache/maven/repository/LegacyRepositorySystem.java index 3a76f102e5..63b7611be9 100644 --- a/maven-repository/src/main/java/org/apache/maven/repository/LegacyRepositorySystem.java +++ b/maven-repository/src/main/java/org/apache/maven/repository/LegacyRepositorySystem.java @@ -30,7 +30,6 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.manager.WagonManager; -import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; @@ -38,7 +37,6 @@ import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; -import org.apache.maven.artifact.resolver.ResolutionErrorHandler; import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; @@ -54,13 +52,12 @@ import org.apache.maven.wagon.proxy.ProxyInfo; import org.apache.maven.wagon.repository.RepositoryPermissions; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.StringUtils; /** * @author Jason van Zyl */ -@Component(role = RepositorySystem.class) +@Component( role = RepositorySystem.class, hint = "default" ) public class LegacyRepositorySystem implements RepositorySystem { @@ -79,18 +76,9 @@ public class LegacyRepositorySystem @Requirement private ArtifactRepositoryLayout defaultArtifactRepositoryLayout; - @Requirement - private ArtifactMetadataSource artifactMetadataSource; - @Requirement private MirrorBuilder mirrorBuilder; - @Requirement - private ResolutionErrorHandler resolutionErrorHandler; - - @Requirement - private Logger logger; - private Map proxies = new HashMap(); private Map authenticationInfoMap = new HashMap(); @@ -395,7 +383,14 @@ public class LegacyRepositorySystem public ArtifactResolutionResult resolve( ArtifactResolutionRequest request ) { - return artifactResolver.resolve( request ); + + if ( request.getRemoteRepostories() != null && request.getRemoteRepostories().size() > 10 ) + { + System.out.println( "legacy: request with " + request.getRemoteRepostories().size() + " remote repositories" ); + } + ArtifactResolutionResult res = artifactResolver.resolve( request ); + + return res; } public void setOnline( boolean online ) @@ -419,6 +414,8 @@ public class LegacyRepositorySystem proxyInfo.setPassword( password ); proxies.put( protocol, proxyInfo ); + + wagonManager.addProxy( protocol, host, port, username, password, nonProxyHosts ); } public void addAuthenticationInfo( String repositoryId, String username, String password, String privateKey, String passphrase ) @@ -469,4 +466,9 @@ public class LegacyRepositorySystem { return mirrorBuilder.getMirrors( repositories ); } + + public MetadataResolutionResult resolveMetadata( MetadataResolutionRequest request ) + { + return null; + } } diff --git a/maven-repository/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java b/maven-repository/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java new file mode 100644 index 0000000000..44455ef58d --- /dev/null +++ b/maven-repository/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java @@ -0,0 +1,122 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.maven.repository; + + +/** + * + * + * @author Oleg Gusakov + * @version $Id$ + * + */ +public class MavenArtifactMetadata +{ + public static final String DEFAULT_TYPE = "jar"; + + String groupId; + String artifactId; + String version; + String classifier; + String type; + String scope; + + transient Object datum; + + public String getGroupId() + { + return groupId; + } + + public void setGroupId( String groupId ) + { + this.groupId = groupId; + } + + public String getArtifactId() + { + return artifactId; + } + + public void setArtifactId( String artifactId ) + { + this.artifactId = artifactId; + } + + public String getVersion() + { + return version; + } + + public void setVersion( String version ) + { + this.version = version; + } + + public String getClassifier() + { + return classifier; + } + + public void setClassifier( String classifier ) + { + this.classifier = classifier; + } + + public String getType() + { + return type; + } + + public void setType( String type ) + { + this.type = type; + } + + public Object getDatum() + { + return datum; + } + + public void setDatum( Object datum ) + { + this.datum = datum; + } + + public String getScope() + { + return scope; + } + + public void setScope( String scope ) + { + this.scope = scope; + } + + @Override + public String toString() + { + return getGroupId()+":"+getArtifactId()+":"+getVersion() + +":" + (getClassifier() == null ? "" : getClassifier() ) + +":" + (getType() == null ? DEFAULT_TYPE : getType() ) + ; + } + +} diff --git a/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraph.java b/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraph.java new file mode 100644 index 0000000000..cf99eda72e --- /dev/null +++ b/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraph.java @@ -0,0 +1,94 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.maven.repository; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * This is the main graph data structure used by the RepositorySystem to present tree and graph objects. + * + * @author Oleg Gusakov + * @version $Id$ + * + */ +public class MetadataGraph +{ + /** all graph nodes */ + Collection nodes; + + /** entry point for tree-like structures */ + MetadataGraphNode entry; + + public MetadataGraph( MetadataGraphNode entry ) + { + this(); + + this.entry = entry; + } + + public MetadataGraph() + { + nodes = new ArrayList( 64 ); + } + + public void addNode( MetadataGraphNode node ) + { + nodes.add( node ); + } + + /** + * find a node by the GAV (metadata) + * + * @param md + * @return + */ + public MetadataGraphNode findNode( MavenArtifactMetadata md ) + { + for( MetadataGraphNode mgn : nodes ) + if( mgn.metadata.equals( md ) ) + return mgn; + + MetadataGraphNode node = new MetadataGraphNode( md ); + addNode( node ); + + return node; + } + + /** + * getter + * + * @return + */ + public MetadataGraphNode getEntry() + { + return entry; + } + + /** + * getter + * + * @return + */ + public Collection getNodes() + { + return nodes; + } +} diff --git a/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraphNode.java b/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraphNode.java new file mode 100644 index 0000000000..efb7a8cad8 --- /dev/null +++ b/maven-repository/src/main/java/org/apache/maven/repository/MetadataGraphNode.java @@ -0,0 +1,94 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +package org.apache.maven.repository; + +import java.util.ArrayList; +import java.util.List; + +/** + * MetadataGraph node - as it's a directed graph - holds adjacency lists for incident and exident nodes + * + * @author Oleg Gusakov + * @version $Id$ + * + */ +public class MetadataGraphNode +{ + /** node payload */ + MavenArtifactMetadata metadata; + + /** nodes, incident to this (depend on me) */ + List inNodes; + + /** nodes, exident to this (I depend on) */ + List exNodes; + + public MetadataGraphNode() + { + inNodes = new ArrayList(4); + exNodes = new ArrayList(8); + } + + public MetadataGraphNode( MavenArtifactMetadata metadata ) + { + this(); + this.metadata = metadata; + } + + public MetadataGraphNode addIncident( MetadataGraphNode node ) + { + inNodes.add( node ); + return this; + } + + public MetadataGraphNode addExident( MetadataGraphNode node ) + { + exNodes.add( node ); + return this; + } + + @Override + public boolean equals( Object obj ) + { + if( obj == null ) + return false; + + if( MetadataGraphNode.class.isAssignableFrom( obj.getClass() ) ) + { + MetadataGraphNode node2 = (MetadataGraphNode) obj; + + if( node2.metadata == null ) + return metadata == null; + + return metadata == null ? false: metadata.toString().equals( node2.metadata.toString() ); + } + else + return super.equals( obj ); + } + + @Override + public int hashCode() + { + if( metadata == null ) + return super.hashCode(); + + return metadata.toString().hashCode(); + } +} diff --git a/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java b/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java index 216c2e44f7..da9315e557 100644 --- a/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java +++ b/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java @@ -27,7 +27,6 @@ import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ResolutionListener; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; @@ -40,7 +39,9 @@ import org.apache.maven.artifact.resolver.filter.ArtifactFilter; */ public class MetadataResolutionRequest { - private Artifact artifact; + private MavenArtifactMetadata mad; + + private String scope; // Needs to go away private Set artifactDependencies; @@ -49,41 +50,40 @@ public class MetadataResolutionRequest private List remoteRepositories; - // Not sure what to do with this? - // Scope - // Lock down lists - private ArtifactFilter filter; - - // Needs to go away - private List listeners = new ArrayList(); - // This is like a filter but overrides all transitive versions private Map managedVersionMap; - // This should not be in here, it's a component - private ArtifactMetadataSource metadataSource; - - private boolean resolveRoot = true; + /** result type - flat list; the default */ + private boolean asList = true; + + /** result type - dirty tree */ + private boolean asDirtyTree = false; + + /** result type - resolved tree */ + private boolean asResolvedTree = false; + + /** result type - graph */ + private boolean asGraph = false; public MetadataResolutionRequest() { } - public MetadataResolutionRequest( Artifact artifact, ArtifactRepository localRepository, List remoteRepositories ) + public MetadataResolutionRequest( MavenArtifactMetadata md, ArtifactRepository localRepository, List remoteRepositories ) { - this.artifact = artifact; + this.mad = md; this.localRepository = localRepository; this.remoteRepositories = remoteRepositories; } - public Artifact getArtifact() + public MavenArtifactMetadata getArtifactMetadata() { - return artifact; + return mad; } - public MetadataResolutionRequest setArtifact( Artifact artifact ) + public MetadataResolutionRequest setArtifactMetadata( MavenArtifactMetadata md ) { - this.artifact = artifact; + this.mad = md; return this; } @@ -124,53 +124,6 @@ public class MetadataResolutionRequest return this; } - public ArtifactFilter getFilter() - { - return filter; - } - - public MetadataResolutionRequest setFilter( ArtifactFilter filter ) - { - this.filter = filter; - - return this; - } - - public List getListeners() - { - return listeners; - } - - public MetadataResolutionRequest setListeners( List listeners ) - { - this.listeners = listeners; - - return this; - } - - public MetadataResolutionRequest addListener( ResolutionListener listener ) - { - listeners.add( listener ); - - return this; - } - - // ------------------------------------------------------------------------ - // - // ------------------------------------------------------------------------ - - public ArtifactMetadataSource getMetadataSource() - { - return metadataSource; - } - - public MetadataResolutionRequest setMetadataSource( ArtifactMetadataSource metadataSource ) - { - this.metadataSource = metadataSource; - - return this; - } - public Map getManagedVersionMap() { return managedVersionMap; @@ -183,28 +136,71 @@ public class MetadataResolutionRequest return this; } - public MetadataResolutionRequest setResolveRoot( boolean resolveRoot ) - { - this.resolveRoot = resolveRoot; - - return this; - } - - public boolean isResolveRoot() - { - return resolveRoot; - } - public String toString() { StringBuffer sb = new StringBuffer() .append( "REQUEST: " ).append( "\n" ) - .append( "artifact: " ).append( artifact ).append( "\n" ) + .append( "artifact: " ).append( mad ).append( "\n" ) .append( artifactDependencies ).append( "\n" ) .append( "localRepository: " ).append( localRepository ).append( "\n" ) .append( "remoteRepositories: " ).append( remoteRepositories ).append( "\n" ) - .append( "metadataSource: " ).append( metadataSource ).append( "\n" ); + ; return sb.toString(); } + + public boolean isAsList() + { + return asList; + } + + public MetadataResolutionRequest setAsList( boolean asList ) + { + this.asList = asList; + return this; + } + + public boolean isAsDirtyTree() + { + return asDirtyTree; + } + + public MetadataResolutionRequest setAsDirtyTree( boolean asDirtyTree ) + { + this.asDirtyTree = asDirtyTree; + return this; + } + + public boolean isAsResolvedTree() + { + return asResolvedTree; + } + + public MetadataResolutionRequest setAsResolvedTree( boolean asResolvedTree ) + { + this.asResolvedTree = asResolvedTree; + return this; + } + + public boolean isAsGraph() + { + return asGraph; + } + + public MetadataResolutionRequest setAsGraph( boolean asGraph ) + { + this.asGraph = asGraph; + return this; + } + + public MetadataResolutionRequest setScope( String scope ) + { + this.scope = scope; + return this; + } + + public String getScope() + { + return scope; + } } diff --git a/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java b/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java index 90406b9a51..de571412ee 100644 --- a/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java +++ b/maven-repository/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java @@ -65,6 +65,12 @@ public class MetadataResolutionResult private Set requestedArtifacts; private Set artifacts; + + private MetadataGraph dirtyTree; + + private MetadataGraph resolvedTree; + + private MetadataGraph resolvedGraph; public Artifact getOriginatingArtifact() { @@ -227,13 +233,10 @@ public class MetadataResolutionResult return errorArtifactExceptions != null; } - public MetadataResolutionResult addErrorArtifactException( ArtifactResolutionException e ) + public MetadataResolutionResult addError( Exception e ) { - errorArtifactExceptions = initList( errorArtifactExceptions ); - - errorArtifactExceptions.add( e ); - - exceptions = initList( exceptions ); + if( exceptions == null ) + initList( exceptions ); exceptions.add( e ); @@ -340,4 +343,15 @@ public class MetadataResolutionResult return sb.toString(); } + + public MetadataGraph getResolvedTree() + { + return resolvedTree; + } + + public void setResolvedTree( MetadataGraph resolvedTree ) + { + this.resolvedTree = resolvedTree; + } + } diff --git a/maven-repository/src/main/java/org/apache/maven/repository/RepositorySystem.java b/maven-repository/src/main/java/org/apache/maven/repository/RepositorySystem.java index c2701ca0d1..15aee90f75 100644 --- a/maven-repository/src/main/java/org/apache/maven/repository/RepositorySystem.java +++ b/maven-repository/src/main/java/org/apache/maven/repository/RepositorySystem.java @@ -91,7 +91,16 @@ public interface RepositorySystem ArtifactResolutionResult resolve( ArtifactResolutionRequest request ); - //MetadataResolutionResult resolveMetadata( MetadataResolutionRequest request ); + /** + * this is the new metadata-based entry point into repository system. By default - it will transitively resolve metadata + * for the supplied root GAV and return a flat set of dependency metadatas. Tweaking the request allows user to ask for + * various formats of the response - resolved tree, resolved graph or dirty tree. Only the resolved tree is implemented now + * in MercuryRepositorySystem, LegacyRepositorySystem ignores this call for now. + * + * @param request - supplies all necessary details for the resolution configuration + * @return + */ + MetadataResolutionResult resolveMetadata( MetadataResolutionRequest request ); //REMOVE // Network enablement: this needs to go as we will know at a higher level from the embedder if the system is offline or not, we should not have to diff --git a/maven-project/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java b/maven-repository/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java similarity index 84% rename from maven-project/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java rename to maven-repository/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java index ac40d05759..3575d2f524 100644 --- a/maven-project/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java +++ b/maven-repository/src/test/java/org/apache/maven/repository/LegacyMavenRepositorySystemTest.java @@ -27,9 +27,10 @@ import org.codehaus.plexus.PlexusTestCase; public class LegacyMavenRepositorySystemTest extends PlexusTestCase { - protected void setUp() + public void testLookup() throws Exception { - lookup( RepositorySystem.class, "default" ); + // Yes I'm relying on the integration tests, but I'm really hoping this just goes away shortly. + //lookup( RepositorySystem.class, "default" ); } } diff --git a/maven-toolchain/pom.xml b/maven-toolchain/pom.xml index e27791d892..032f1c3465 100644 --- a/maven-toolchain/pom.xml +++ b/maven-toolchain/pom.xml @@ -1,4 +1,5 @@ + + + 4.0.0 + org.apache.maven maven 3.0-SNAPSHOT - 4.0.0 + maven-toolchain + Maven Toolchains + org.apache.maven @@ -32,8 +38,21 @@ maven-compat + + + org.codehaus.plexus + plexus-component-metadata + + + + generate-metadata + generate-test-metadata + + + + org.codehaus.modello modello-maven-plugin diff --git a/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java index 967f14813a..4cc6ca5763 100644 --- a/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java +++ b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java @@ -1,216 +1,102 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - package org.apache.maven.toolchain; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import java.util.HashMap; +import java.util.Map; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.project.MavenProject; -import org.apache.maven.toolchain.model.PersistedToolchains; import org.apache.maven.toolchain.model.ToolchainModel; -import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader; -import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; /** - * * @author mkleint */ -@Component(role = ToolchainManager.class) +@Component( role = ToolchainManager.class ) public class DefaultToolchainManager - implements ToolchainManager, ToolchainManagerPrivate -{ - @Requirement - private Logger logger; - - @Requirement - private PlexusContainer container; + implements ToolchainManager - public ToolchainPrivate[] getToolchainsForType( String type ) - throws MisconfiguredToolchainException - { - try - { - PersistedToolchains pers = readToolchainSettings(); - Map factories = container.lookupMap( ToolchainFactory.class ); - List toRet = new ArrayList(); - if ( pers != null ) - { - List lst = pers.getToolchains(); - if ( lst != null ) - { - Iterator it = lst.iterator(); - while ( it.hasNext() ) - { - ToolchainModel toolchainModel = (ToolchainModel) it.next(); - ToolchainFactory fact = factories.get( toolchainModel.getType() ); - if ( fact != null ) - { - toRet.add( fact.createToolchain( toolchainModel ) ); - } - else - { - logger.error( "Missing toolchain factory for type:" + toolchainModel.getType() + ". Possibly caused by misconfigured project." ); - } - } - } - } - for ( ToolchainFactory toolchainFactory : factories.values() ) - { - ToolchainPrivate tool = toolchainFactory.createDefaultToolchain(); - if ( tool != null ) - { - toRet.add( tool ); - } - } - ToolchainPrivate[] tc = new ToolchainPrivate[toRet.size()]; - return (ToolchainPrivate[]) toRet.toArray( tc ); - } - catch ( ComponentLookupException ex ) - { - logger.fatalError( "Error in component lookup", ex ); - } - return new ToolchainPrivate[0]; - } +{ + + @Requirement + Logger logger; + + @Requirement( role = ToolchainFactory.class ) + Map factories; public Toolchain getToolchainFromBuildContext( String type, MavenSession session ) { Map context = retrieveContext( session ); - if ( "javac".equals( type ) ) - { - //HACK to make compiler plugin happy - type = "jdk"; - } - Object obj = context.get( getStorageKey( type ) ); - ToolchainModel model = (ToolchainModel) obj; + + ToolchainModel model = (ToolchainModel) context.get( getStorageKey( type ) ); if ( model != null ) { try { - ToolchainFactory fact = container.lookup( ToolchainFactory.class, type ); - return fact.createToolchain( model ); - } - catch ( ComponentLookupException ex ) - { - logger.fatalError( "Error in component lookup", ex ); + ToolchainFactory fact = factories.get( type ); + if ( fact != null ) + { + return fact.createToolchain( model ); + } + else + { + logger.error( "Missing toolchain factory for type: " + type + + ". Possibly caused by misconfigured project." ); + } } catch ( MisconfiguredToolchainException ex ) { logger.error( "Misconfigured toolchain.", ex ); } } + return null; } - private MavenProject getCurrentProject( MavenSession session ) + Map retrieveContext( MavenSession session ) { - //use reflection since MavenSession.getCurrentProject() is not part of 2.0.8 - try - { - Method meth = session.getClass().getMethod( "getCurrentProject", new Class[0] ); - return (MavenProject) meth.invoke( session ); - } - catch ( Exception ex ) - { - //just ignore, we're running in pre- 2.0.9 - } - return null; - } + Map context = null; - private Map retrieveContext( MavenSession session ) - { - if ( session == null ) + if ( session != null ) { - return new HashMap(); - } - PluginDescriptor desc = new PluginDescriptor(); - desc.setGroupId( PluginDescriptor.getDefaultPluginGroupId() ); - desc.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( "toolchains" ) ); - MavenProject current = getCurrentProject( session ); - if ( current != null ) - { - return session.getPluginContext( desc, current ); + PluginDescriptor desc = new PluginDescriptor(); + desc.setGroupId( PluginDescriptor.getDefaultPluginGroupId() ); + desc.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( "toolchains" ) ); + MavenProject current = session.getCurrentProject(); + if ( current != null ) + { + context = session.getPluginContext( desc, current ); + } } - return new HashMap(); - } - public void storeToolchainToBuildContext( ToolchainPrivate toolchain, MavenSession session ) - { - Map context = retrieveContext( session ); - context.put( getStorageKey( toolchain.getType() ), toolchain.getModel() ); + return ( context != null ) ? context : new HashMap(); } public static final String getStorageKey( String type ) { - return "toolchain-" + type; //NOI18N + return "toolchain-" + type; // NOI18N } - private PersistedToolchains readToolchainSettings() - throws MisconfiguredToolchainException - { - //TODO how to point to the local path? - File tch = new File( System.getProperty( "user.home" ), ".m2/toolchains.xml" ); - if ( tch.exists() ) - { - MavenToolchainsXpp3Reader reader = new MavenToolchainsXpp3Reader(); - InputStreamReader in = null; - try - { - in = new InputStreamReader( new BufferedInputStream( new FileInputStream( tch ) ) ); - return reader.read( in ); - } - catch ( Exception ex ) - { - throw new MisconfiguredToolchainException( "Cannot read toolchains file at " + tch.getAbsolutePath(), ex ); - } - finally - { - if ( in != null ) - { - try - { - in.close(); - } - catch ( IOException ex ) - { - } - } - // IOUtil.close( in ); - } - } - else - { - //TODO log the fact that no toolchains file was found. - } - return null; - } -} \ No newline at end of file +} diff --git a/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java new file mode 100644 index 0000000000..81ad574c11 --- /dev/null +++ b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java @@ -0,0 +1,89 @@ +package org.apache.maven.toolchain; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.toolchain.model.PersistedToolchains; +import org.apache.maven.toolchain.model.ToolchainModel; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; + +/** + * @author mkleint + */ +@Component( role = ToolchainManagerPrivate.class ) +public class DefaultToolchainManagerPrivate + extends DefaultToolchainManager + implements ToolchainManagerPrivate +{ + + @Requirement + private ToolchainsBuilder toolchainsBuilder; + + public ToolchainPrivate[] getToolchainsForType( String type ) + throws MisconfiguredToolchainException + { + PersistedToolchains pers = toolchainsBuilder.build(); + + List toRet = new ArrayList(); + + if ( pers != null ) + { + List lst = pers.getToolchains(); + if ( lst != null ) + { + for ( ToolchainModel toolchainModel : lst ) + { + ToolchainFactory fact = factories.get( toolchainModel.getType() ); + if ( fact != null ) + { + toRet.add( fact.createToolchain( toolchainModel ) ); + } + else + { + logger.error( "Missing toolchain factory for type: " + toolchainModel.getType() + + ". Possibly caused by misconfigured project." ); + } + } + } + } + + for ( ToolchainFactory toolchainFactory : factories.values() ) + { + ToolchainPrivate tool = toolchainFactory.createDefaultToolchain(); + if ( tool != null ) + { + toRet.add( tool ); + } + } + + return toRet.toArray( new ToolchainPrivate[toRet.size()] ); + } + + public void storeToolchainToBuildContext( ToolchainPrivate toolchain, MavenSession session ) + { + Map context = retrieveContext( session ); + context.put( getStorageKey( toolchain.getType() ), toolchain.getModel() ); + } + +} diff --git a/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java new file mode 100644 index 0000000000..d51840c53c --- /dev/null +++ b/maven-toolchain/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java @@ -0,0 +1,85 @@ +package org.apache.maven.toolchain; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.io.Reader; + +import org.apache.maven.toolchain.model.PersistedToolchains; +import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; + +/** + * @author Benjamin Bentmann + */ +@Component( role = ToolchainsBuilder.class, hint = "default" ) +public class DefaultToolchainsBuilder + implements ToolchainsBuilder +{ + + @Requirement + private Logger logger; + + /** + * The path to the user's toolchains file or null if not configured. + */ + private File userToolchainsFile; + + public PersistedToolchains build() + throws MisconfiguredToolchainException + { + PersistedToolchains toolchains = null; + + if ( userToolchainsFile != null && userToolchainsFile.isFile() ) + { + Reader in = null; + try + { + in = ReaderFactory.newXmlReader( userToolchainsFile ); + toolchains = new MavenToolchainsXpp3Reader().read( in ); + } + catch ( Exception e ) + { + throw new MisconfiguredToolchainException( "Cannot read toolchains file at " + + userToolchainsFile.getAbsolutePath(), e ); + } + finally + { + IOUtil.close( in ); + } + } + else if ( userToolchainsFile != null ) + { + logger.debug( "Toolchains configuration was not found at " + userToolchainsFile ); + } + + return toolchains; + } + + public void setUserToolchainsFile( File userToolchainsFile ) + { + this.userToolchainsFile = userToolchainsFile; + } + +} diff --git a/maven-toolchain/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java b/maven-toolchain/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java new file mode 100644 index 0000000000..3849d5f878 --- /dev/null +++ b/maven-toolchain/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java @@ -0,0 +1,52 @@ +package org.apache.maven.toolchain; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; + +import org.apache.maven.toolchain.model.PersistedToolchains; + +/** + * Builds the toolchains model from a previously configured filesystem path to the toolchains file. + * Note: This is an internal component whose interface can change without prior notice. + * + * @author Benjamin Bentmann + */ +public interface ToolchainsBuilder +{ + + /** + * Builds the toolchains model from the configured toolchain files. + * + * @return The toolchains model or null if no toolchain file was configured or the configured files do + * not exist. + * @throws MisconfiguredToolchainException If the toolchain files exist but cannot be parsed. + */ + PersistedToolchains build() + throws MisconfiguredToolchainException; + + /** + * Sets the path to the file from which to read the available toolchains. + * + * @param userToolchainsFile The path to the toolchains file, may be null to disable parsing. + */ + void setUserToolchainsFile( File userToolchainsFile ); + +} diff --git a/maven-toolchain/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolchainFactory.java b/maven-toolchain/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolchainFactory.java index d3aa897486..55184b7724 100644 --- a/maven-toolchain/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolchainFactory.java +++ b/maven-toolchain/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolchainFactory.java @@ -35,7 +35,7 @@ import org.codehaus.plexus.util.xml.Xpp3Dom; * * @author mkleint */ -@Component(role=ToolchainFactory.class) +@Component( role = ToolchainFactory.class, hint = "jdk" ) public class DefaultJavaToolchainFactory implements ToolchainFactory, LogEnabled { diff --git a/mercury-ant-tasks-1.0-alpha-6-SNAPSHOT.jar b/mercury-ant-tasks-1.0-alpha-6-SNAPSHOT.jar index cd7bebb0f9cbf2e2c7339edd40d18047a37b94ba..7a9871a1476054251796c4292e98adba5ace68fa 100644 GIT binary patch delta 383843 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 delta 279614 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%0AAJRs6S0;ce(LdX{VjbA;SwfE-6yut4^bR<_WL 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⪻UC$1*EG6-(U#H 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%0As^q2W5bro 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 diff --git a/pom.xml b/pom.xml index 2030d8de13..dfa1577329 100644 --- a/pom.xml +++ b/pom.xml @@ -21,16 +21,18 @@ under the License. 4.0.0 + org.apache.maven maven-parent 11 ../pom/maven/pom.xml - org.apache.maven + maven 3.0-SNAPSHOT pom + Apache Maven Maven is a project development management and comprehension tool. Based on the concept of a project object model: @@ -42,31 +44,36 @@ under the License. http://maven.apache.org/ 2001 + 1.3 1.0 + + 1.0-alpha-9 1.2_Java1.3 - 3.8.1 + 3.8.1 1.0-beta-4-SNAPSHOT 1.0-alpha-6 - 1.7 + 1.1 1.0-alpha-1 1.5.8 1.6 - 1.0 - 1.0-beta-4 - 1.7-SNAPSHOT - 1.0-alpha-6-SNAPSHOT + 1.0 + 1.0-beta-5 + 1.8 + 1.0-alpha-7-SNAPSHOT 1.0-alpha-1 1.2 3.2.6 1.0.1 1.3 + 1.0.1 - - jira - http://jira.codehaus.org/browse/MNG - Maven Developer List @@ -142,11 +149,330 @@ under the License. + + + maven-core + apache-maven + maven-model + maven-plugin-api + maven-project + maven-model-builder + maven-mercury + maven-embedder + maven-toolchain + maven-compat + maven-repository + + scm:svn:http://svn.apache.org/repos/asf/maven/components/trunk scm:svn:https://svn.apache.org/repos/asf/maven/components/trunk http://svn.apache.org/viewcvs.cgi/maven/components/trunk + + jira + http://jira.codehaus.org/browse/MNG + + + + apache.website + scp://people.apache.org/www/maven.apache.org/ref/${project.version}/ + + + + + + + + + + + org.apache.maven + maven-mercury + ${project.version} + + + org.apache.maven + maven-lifecycle + ${project.version} + + + org.apache.maven + maven-reporting-api + ${project.version} + + + org.apache.maven + maven-profile + ${project.version} + + + org.apache.maven + maven-model + ${project.version} + + + org.apache.maven + maven-project + ${project.version} + + + org.apache.maven + maven-plugin-api + ${project.version} + + + org.apache.maven + maven-toolchain + ${project.version} + + + org.apache.maven + maven-embedder + ${project.version} + + + org.apache.maven + maven-core + ${project.version} + + + org.apache.maven + maven-model-builder + ${project.version} + + + org.apache.maven + maven-repository + ${project.version} + + + org.apache.maven + maven-compat + ${project.version} + + + + + org.codehaus.plexus + plexus-utils + ${plexusUtilsVersion} + + + org.codehaus.plexus + plexus-container-default + ${plexusVersion} + + + org.codehaus.plexus + plexus-component-annotations + ${plexusVersion} + + + org.codehaus.plexus + plexus-classworlds + ${classWorldsVersion} + + + org.codehaus.plexus + plexus-interpolation + ${plexusInterpolationVersion} + + + org.codehaus.plexus + plexus-interactivity-api + ${plexusInteractivityVersion} + + + org.codehaus.plexus + plexus-component-api + + + + + + + org.sonatype.plexus + plexus-jetty6 + ${plexusJetty6Version} + test + + + org.sonatype.spice + plexus-webdav + ${plexusWebdavVersion} + test + + + + + org.apache.maven.wagon + wagon-provider-api + ${wagonVersion} + + + org.apache.maven.wagon + wagon-file + ${wagonVersion} + + + org.apache.maven.wagon + wagon-http-lightweight + ${wagonVersion} + + + org.apache.maven.wagon + wagon-ssh + ${wagonVersion} + + + org.apache.maven.wagon + wagon-ssh-external + ${wagonVersion} + + + + org.apache.maven.doxia + doxia-sink-api + ${doxiaVersion} + + + + org.sonatype.spice + model-builder + ${modelBuilderVersion} + + + org.codehaus.woodstox + wstx-asl + ${woodstoxVersion} + + + stax + stax-api + ${staxVersion} + + + + commons-cli + commons-cli + ${commonsCliVersion} + + + commons-lang + commons-lang + + + commons-logging + commons-logging + + + + + commons-jxpath + commons-jxpath + ${jxpathVersion} + + + + + org.apache.maven.mercury + mercury-artifact + ${mercuryVersion} + + + org.apache.maven.mercury + mercury-external + ${mercuryVersion} + + + org.apache.maven.mercury + mercury-plexus + ${mercuryVersion} + + + org.apache.maven.mercury + mercury-repo-virtual + ${mercuryVersion} + + + org.sonatype.mercury + mercury-mp3-cli + ${mercuryMp3Version} + + + org.sonatype.plexus + plexus-sec-dispatcher + ${securityDispatcherVersion} + + + + + + org.apache.maven.mercury + mercury-repo-local-m2 + ${mercuryVersion} + test + + + org.apache.maven.mercury + mercury-repo-remote-m2 + ${mercuryVersion} + test + + + org.apache.maven.mercury + mercury-md-sat + ${mercuryVersion} + test + + + org.apache.maven.mercury + mercury-util + ${mercuryVersion} + test + + + org.apache.maven.mercury + mercury-transport-http + ${mercuryVersion} + test + + + org.apache.maven.mercury + mercury-transport-http + ${mercuryVersion} + test-jar + test + + + org.sonatype.plexus + plexus-plugin-manager + ${plexusPluginManagerVersion} + + + + easymock + easymock + ${easyMockVersion} + test + + + + + + + + + + junit + junit + ${junitVersion} + test + + + + @@ -212,7 +538,7 @@ under the License. org.apache.maven.plugins maven-surefire-plugin - 2.4.3 + 2.4.2 org.apache.maven.plugins @@ -227,310 +553,7 @@ under the License. - - maven-core - apache-maven - maven-model - maven-plugin-api - maven-project - maven-project-builder - maven-mercury - maven-embedder - maven-toolchain - maven-compat - maven-repository - maven-repository-mercury - - - - - spice.snapshots - http://repository.sonatype.org/content/repositories/snapshots - - false - - - - - - - junit - junit - ${junitVersion} - test - - - - - - - - - org.apache.maven - maven-mercury - ${project.version} - - - org.apache.maven - maven-reporting-api - ${project.version} - - - org.apache.maven - maven-profile - ${project.version} - - - org.apache.maven - maven-model - ${project.version} - - - org.apache.maven - maven-project - ${project.version} - - - org.apache.maven - maven-plugin-api - ${project.version} - - - org.apache.maven - maven-toolchain - ${project.version} - - - org.apache.maven - maven-embedder - ${project.version} - - - org.apache.maven - maven-core - ${project.version} - - - org.apache.maven - maven-project-builder - ${project.version} - - - org.apache.maven - maven-repository - ${project.version} - - - org.apache.maven - maven-compat - ${project.version} - - - - - org.codehaus.plexus - plexus-utils - ${plexusUtilsVersion} - - - org.codehaus.plexus - plexus-container-default - ${plexusVersion} - - - org.codehaus.plexus - plexus-component-annotations - ${plexusVersion} - - - org.codehaus.plexus - plexus-classworlds - ${classWorldsVersion} - - - org.codehaus.plexus - plexus-interpolation - ${plexusInterpolationVersion} - - - org.codehaus.plexus - plexus-interactivity-api - ${plexusInteractivityVersion} - - - org.codehaus.plexus - plexus-component-api - - - - - - - org.sonatype.plexus - plexus-jetty6 - ${plexusJetty6Version} - test - - - org.sonatype.spice - plexus-webdav - ${plexusWebdavVersion} - test - - - - - org.apache.maven.wagon - wagon-provider-api - ${wagonVersion} - - - org.apache.maven.wagon - wagon-file - ${wagonVersion} - - - org.apache.maven.wagon - wagon-http-lightweight - ${wagonVersion} - - - org.apache.maven.wagon - wagon-ssh - ${wagonVersion} - - - org.apache.maven.wagon - wagon-ssh-external - ${wagonVersion} - - - - org.sonatype.spice - model-builder - ${modelBuilderVersion} - - - org.codehaus.woodstox - wstx-asl - ${woodstoxVersion} - - - - commons-cli - commons-cli - ${commonsCliVersion} - - - commons-lang - commons-lang - - - commons-logging - commons-logging - - - - - commons-jxpath - commons-jxpath - ${jxpathVersion} - - - - org.apache.maven.mercury - mercury-artifact - ${mercuryVersion} - - - org.apache.maven.mercury - mercury-external - ${mercuryVersion} - - - org.apache.maven.mercury - mercury-plexus - ${mercuryVersion} - - - org.apache.maven.mercury - mercury-repo-virtual - ${mercuryVersion} - - - org.sonatype.mercury - mercury-mp3-cli - ${mercuryMp3Version} - - - org.sonatype.plexus - plexus-sec-dispatcher - ${securityDispatcherVersion} - - - - - - org.apache.maven.mercury - mercury-repo-local-m2 - ${mercuryVersion} - test - - - org.apache.maven.mercury - mercury-repo-remote-m2 - ${mercuryVersion} - test - - - org.apache.maven.mercury - mercury-md-sat - ${mercuryVersion} - test - - - org.apache.maven.mercury - mercury-util - ${mercuryVersion} - test - - - org.apache.maven.mercury - mercury-transport-http - ${mercuryVersion} - test - - - org.apache.maven.mercury - mercury-transport-http - ${mercuryVersion} - test-jar - test - - - org.sonatype.plexus - plexus-plugin-manager - ${plexusPluginManagerVersion} - - - - easymock - easymock - ${easyMockVersion} - test - - - - - - - - - apache.website - scp://people.apache.org/www/maven.apache.org/ref/${project.version}/ - - osgi