Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Jenkinsfile2
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin.equinox/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin.equinox/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin.equinox/src/org/eclipse/equinox/internal/frameworkadmin/equinox/EquinoxManipulatorImpl.java9
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin.test/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.frameworkadmin/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.checksums.bouncycastle/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.processors/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/Messages.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java197
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/messages.properties8
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java12
-rw-r--r--bundles/org.eclipse.equinox.p2.console/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.core/META-INF/MANIFEST.MF10
-rw-r--r--bundles/org.eclipse.equinox.p2.core/META-INF/p2.inf5
-rw-r--r--bundles/org.eclipse.equinox.p2.core/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/internal/p2/core/helpers/SecureXMLUtil.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/p2/core/UIServices.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF7
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java16
-rw-r--r--bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.director/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/DirectorActivator.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/PlanExecutionHelper.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.directorywatcher/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java3
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF3
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/plugin.xml1
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/schema/pgp.exsd107
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java486
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CheckTrust.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.garbagecollector/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.installer/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.installer/installer.product4
-rw-r--r--bundles/org.eclipse.equinox.p2.installer/installer.properties4
-rw-r--r--bundles/org.eclipse.equinox.p2.installer/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.jarprocessor/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.jarprocessor/forceQualifierUpdate.txt4
-rw-r--r--bundles/org.eclipse.equinox.p2.jarprocessor/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.operations/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/.settings/org.eclipse.jdt.ui.prefs2
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/.settings/.api_filters11
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/IPublisherInfo.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/Bootstrap.product4
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.repository.tools/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/.options3
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF14
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/OSGI-INF/pgpPublicKeyService.xml8
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/build.properties3
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/PGPKeyServiceComponent.java22
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/DebugHelper.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/provisional/p2/repository/DefaultPGPPublicKeyService.java869
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/IArtifactUIServices.java96
-rw-r--r--bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/PGPPublicKeyService.java243
-rw-r--r--bundles/org.eclipse.equinox.p2.sar/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.optimizers/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.reconciler.product/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.reconciler.product/reconciler.product10
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.ui/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/actions/ElementUtilsTest.java10
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.verifier/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF7
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/plugin.xml6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/TestData.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/PGPSignatureVerifierTest.java89
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/PGPVerifierTest.java72
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/TransferTest.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/director/DirectorApplicationTest.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/CertificateCheckerTest.java121
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/GeneratorTests.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/MetadataRepositoryManagerTest.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/MetadataMirrorApplicationTest.java8
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java12
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AccumulateConfigDataActionTest.java24
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java41
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AdviceMatcher.java54
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java212
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/CaptureList.java39
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java46
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java258
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/LocalUpdateSiteActionTest.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionCapturingTest.java52
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTest.java165
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTestMac.java41
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileAdviceTest.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootFilesActionTest.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootIUActionTest.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/reconciler/dropins/AbstractReconcilerTest.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/eclipse/SetLauncherNameActionTest.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/generator/Europa/site.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform.source_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.sdk_3.3.0.v20070607-7M7J-BIolz-OcxWxvWAPSfLPqevO/feature.xml6
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/importexport/unknownformat.p2f2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/mirror/mirrorSourceRepoWithRefs/content.xml8
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/pausefeature/artifacts.xml10
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/pgp/signer2-publickey.asc29
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/updatesite/CategoryXMLActionTest/associateSites.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.testserver/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html8
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.eclipse/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties2
-rw-r--r--bundles/org.eclipse.equinox.p2.transport.ecf/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.transport.ecf/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/Activator.java15
-rw-r--r--bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileReader.java12
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.admin.rcp/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.admin.rcp/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.admin.rcp/rcp.product4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.admin/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.importexport/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java29
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF5
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java22
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java437
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties26
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF9
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/plugin.xml7
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/pom.xml4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/IProvHelpContextIds.java22
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java184
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ServiceUIComponent.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java322
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PGPPublicKeyViewDialog.java248
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/TrustCertificateDialog.java875
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties36
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/viewers/CertificateLabelProvider.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.updatechecker/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.updatesite/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.simpleconfigurator.manipulator/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.simpleconfigurator/pom.xml2
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.discovery/META-INF/MANIFEST.MF4
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.discovery/cloud.product8
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.discovery/plugin.xml6
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.discovery/pom.xml2
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/META-INF/MANIFEST.MF4
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/pom.xml2
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/META-INF/MANIFEST.MF4
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/pom.xml2
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/sdkbundlevisibility.product8
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/META-INF/MANIFEST.MF4
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/pom.xml2
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdkui/META-INF/MANIFEST.MF4
-rw-r--r--examples/org.eclipse.equinox.p2.examples.rcp.sdkui/pom.xml2
-rw-r--r--examples/pom.xml2
-rw-r--r--features/org.eclipse.equinox.p2.core.feature/feature.xml6
-rw-r--r--features/org.eclipse.equinox.p2.core.feature/forceQualifierUpdate.txt3
-rw-r--r--features/org.eclipse.equinox.p2.core.feature/pom.xml4
-rw-r--r--features/org.eclipse.equinox.p2.discovery.feature/feature.xml2
-rw-r--r--features/org.eclipse.equinox.p2.discovery.feature/pom.xml4
-rw-r--r--features/org.eclipse.equinox.p2.extras.feature/feature.xml2
-rw-r--r--features/org.eclipse.equinox.p2.extras.feature/pom.xml4
-rw-r--r--features/org.eclipse.equinox.p2.rcp.feature/feature.xml2
-rw-r--r--features/org.eclipse.equinox.p2.rcp.feature/pom.xml4
-rw-r--r--features/org.eclipse.equinox.p2.sdk/feature.xml4
-rw-r--r--features/org.eclipse.equinox.p2.sdk/pom.xml4
-rw-r--r--features/org.eclipse.equinox.p2.user.ui/feature.xml2
-rw-r--r--features/org.eclipse.equinox.p2.user.ui/pom.xml4
-rw-r--r--org.eclipse.equinox.p2.releng/default.target2
-rw-r--r--org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent/pom.xml2
-rw-r--r--pom.xml2
205 files changed, 5045 insertions, 1515 deletions
diff --git a/Jenkinsfile b/Jenkinsfile
index 180fdac75..4f0e0ff28 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -49,7 +49,7 @@ pipeline {
}
}
steps {
- sh "wget https://git.eclipse.org/c/platform/eclipse.platform.releng.aggregator.git/plain/scripts/verifyFreezePeriod.sh"
+ sh "wget https://raw.githubusercontent.com/eclipse-platform/eclipse.platform.releng.aggregator/master/scripts/verifyFreezePeriod.sh"
sh "chmod +x verifyFreezePeriod.sh"
withCredentials([string(credentialsId: 'google-api-key', variable: 'GOOGLE_API_KEY')]) {
sh './verifyFreezePeriod.sh'
diff --git a/bundles/org.eclipse.equinox.frameworkadmin.equinox/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.frameworkadmin.equinox/META-INF/MANIFEST.MF
index 655b1355f..5ad6e58c5 100644
--- a/bundles/org.eclipse.equinox.frameworkadmin.equinox/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.frameworkadmin.equinox/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.frameworkadmin.equinox;singleton:=true
-Bundle-Version: 1.2.100.qualifier
+Bundle-Version: 1.2.200.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Import-Package: org.eclipse.equinox.frameworkadmin;version="[2.0.0,3.0.0)",
@@ -20,7 +20,7 @@ Import-Package: org.eclipse.equinox.frameworkadmin;version="[2.0.0,3.0.0)",
org.osgi.util.tracker;version="1.3.0"
Export-Package: org.eclipse.equinox.internal.frameworkadmin.equinox;x-friends:="org.eclipse.equinox.p2.publisher,org.eclipse.equinox.p2.publisher.eclipse,org.eclipse.equinox.simpleconfigurator.manipulator",
org.eclipse.equinox.internal.frameworkadmin.equinox.utils;x-friends:="org.eclipse.equinox.p2.publisher.eclipse"
-Require-Bundle: org.eclipse.equinox.common
+Require-Bundle: org.eclipse.equinox.common;bundle-version="3.16.000"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Service-Component: OSGI-INF/fwadmin.xml
Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.equinox.frameworkadmin.equinox/pom.xml b/bundles/org.eclipse.equinox.frameworkadmin.equinox/pom.xml
index 33bf8e699..c3ecc7ec9 100644
--- a/bundles/org.eclipse.equinox.frameworkadmin.equinox/pom.xml
+++ b/bundles/org.eclipse.equinox.frameworkadmin.equinox/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.frameworkadmin.equinox</artifactId>
- <version>1.2.100-SNAPSHOT</version>
+ <version>1.2.200-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.frameworkadmin.equinox/src/org/eclipse/equinox/internal/frameworkadmin/equinox/EquinoxManipulatorImpl.java b/bundles/org.eclipse.equinox.frameworkadmin.equinox/src/org/eclipse/equinox/internal/frameworkadmin/equinox/EquinoxManipulatorImpl.java
index 5b73611ae..8e16a04c8 100644
--- a/bundles/org.eclipse.equinox.frameworkadmin.equinox/src/org/eclipse/equinox/internal/frameworkadmin/equinox/EquinoxManipulatorImpl.java
+++ b/bundles/org.eclipse.equinox.frameworkadmin.equinox/src/org/eclipse/equinox/internal/frameworkadmin/equinox/EquinoxManipulatorImpl.java
@@ -328,20 +328,19 @@ public class EquinoxManipulatorImpl implements Manipulator {
BundleInfo[] bInfos = new BundleInfo[bundles.length];
for (int i = 0; i < bundles.length; i++) {
// System.out.println("bundles[" + i + "]=" + bundles[i]);
- try {
+ Optional<File> bundleFile = FileLocator.getBundleFileLocation(bundles[i]);
+ if (bundleFile.isPresent()) {
if (bundles[i].getBundleId() == 0) // SystemBundle
bInfos[i] = new BundleInfo(bundles[i].getSymbolicName(),
bundles[i].getHeaders("").get(Constants.BUNDLE_VERSION), //$NON-NLS-1$
- FileLocator.getBundleFile(bundles[i]).getAbsoluteFile().toURI(), -1, true);
+ bundleFile.get().getAbsoluteFile().toURI(), -1, true);
else {
bInfos[i] = new BundleInfo(bundles[i].getSymbolicName(),
bundles[i].getHeaders("").get(Constants.BUNDLE_VERSION), //$NON-NLS-1$
- FileLocator.getBundleFile(bundles[i]).getAbsoluteFile().toURI(),
+ bundleFile.get().getAbsoluteFile().toURI(),
bundles[i].adapt(BundleStartLevel.class).getStartLevel(),
bundles[i].adapt(BundleStartLevel.class).isPersistentlyStarted());
}
- } catch (IOException e) {
- e.printStackTrace();
}
}
configData.setBundles(bInfos);
diff --git a/bundles/org.eclipse.equinox.frameworkadmin.test/pom.xml b/bundles/org.eclipse.equinox.frameworkadmin.test/pom.xml
index a717a575d..d48775cd2 100644
--- a/bundles/org.eclipse.equinox.frameworkadmin.test/pom.xml
+++ b/bundles/org.eclipse.equinox.frameworkadmin.test/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.frameworkadmin/pom.xml b/bundles/org.eclipse.equinox.frameworkadmin/pom.xml
index aedce9f7a..433dcf50f 100644
--- a/bundles/org.eclipse.equinox.frameworkadmin/pom.xml
+++ b/bundles/org.eclipse.equinox.frameworkadmin/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.checksums.bouncycastle/pom.xml b/bundles/org.eclipse.equinox.p2.artifact.checksums.bouncycastle/pom.xml
index 8e091d594..72d6db126 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.checksums.bouncycastle/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.artifact.checksums.bouncycastle/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/pom.xml b/bundles/org.eclipse.equinox.p2.artifact.optimizers/pom.xml
index ca540db6b..8d09d7881 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.processors/pom.xml b/bundles/org.eclipse.equinox.p2.artifact.processors/pom.xml
index 1d3ab96a1..08e7da3c8 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.processors/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.artifact.processors/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
index 49e639b77..05dc70a3c 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/META-INF/MANIFEST.MF
@@ -10,7 +10,7 @@ Export-Package: org.eclipse.equinox.internal.p2.artifact.processing;x-friends:="
org.eclipse.equinox.internal.p2.artifact.processors.checksum;x-friends:="org.eclipse.equinox.p2.publisher",
org.eclipse.equinox.internal.p2.artifact.processors.md5;x-internal:=true,
org.eclipse.equinox.internal.p2.artifact.processors.pack200;x-friends:="org.eclipse.equinox.p2.artifact.processors,org.eclipse.equinox.p2.artifact.optimizers",
- org.eclipse.equinox.internal.p2.artifact.processors.pgp;x-friends:="org.eclipse.equinox.p2.engine,org.eclipse.equinox.p2.ui.sdk",
+ org.eclipse.equinox.internal.p2.artifact.processors.pgp;x-friends:="org.eclipse.equinox.p2.engine,org.eclipse.equinox.p2.ui.sdk,org.eclipse.equinox.p2.ui",
org.eclipse.equinox.internal.p2.artifact.repository;
x-friends:="org.eclipse.equinox.p2.publisher,
org.eclipse.equinox.p2.reconciler.dropins,
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/pom.xml b/bundles/org.eclipse.equinox.p2.artifact.repository/pom.xml
index 896b53571..bc016ef5a 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/Messages.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/Messages.java
index 4ae7cc402..4f522f0a0 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/Messages.java
@@ -15,11 +15,15 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.artifact.processors.pgp.messages"; //$NON-NLS-1$
+ public static String Error_SignatureAfterKeyExpiration;
+
+ public static String Error_SignatureAfterKeyRevocation;
+
public static String Error_SignatureAndFileDontMatch;
public static String Error_CouldNotLoadSignature;
- public static String Error_publicKeyNotFound;
+ public static String Warning_publicKeyNotFound;
static {
// initialize resource bundle
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
index 688765ff7..8f3d15083 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
@@ -14,6 +14,7 @@ import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
@@ -21,20 +22,21 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.artifact.repository.Activator;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
public class PGPPublicKeyStore {
- private Map<Long, PGPPublicKey> keys = new HashMap<>();
+ private Map<String, PGPPublicKey> keys = new LinkedHashMap<>();
public PGPPublicKey addKey(PGPPublicKey key) {
if (key == null) {
return null;
}
- PGPPublicKey alreadyStoredKey = keys.putIfAbsent(key.getKeyID(), key);
+ PGPPublicKey alreadyStoredKey = keys.putIfAbsent(PGPPublicKeyService.toHexFingerprint(key), key);
return alreadyStoredKey == null ? key : alreadyStoredKey;
}
- public PGPPublicKey getKey(long id) {
- return keys.get(id);
+ public Collection<PGPPublicKey> getKeys(long id) {
+ return keys.values().stream().filter(key -> key.getKeyID() == id).collect(Collectors.toList());
}
public void addKeys(String... armoredPublicKeys) {
@@ -63,9 +65,7 @@ public class PGPPublicKeyStore {
public String toArmoredString() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ArmoredOutputStream armoredOut = new ArmoredOutputStream(out);
- // PGPPublicKeyRing ring = new PGPPublicKeyRing(new ArrayList<>(keys.values()));
- // ring.encode(armoredOut);
- for (PGPPublicKey key : keys.values()) {
+ for (PGPPublicKey key : all()) {
key.encode(armoredOut);
}
armoredOut.close();
@@ -74,14 +74,14 @@ public class PGPPublicKeyStore {
}
public void remove(PGPPublicKey selectedKey) {
- keys.remove(selectedKey.getKeyID());
+ keys.remove(PGPPublicKeyService.toHexFingerprint(selectedKey));
}
public void add(File file) {
try (InputStream stream = new FileInputStream(file)) {
readPublicKeys(stream).forEach(this::addKey);
} catch (IOException e) {
- // TODO: how to log?
+ LogHelper.log(new Status(IStatus.ERROR, Activator.ID, "Could not read PGP key from " + file, e)); //$NON-NLS-1$
}
}
@@ -96,7 +96,8 @@ public class PGPPublicKeyStore {
}
Set<PGPPublicKey> res = new HashSet<>();
try (InputStream stream = PGPUtil.getDecoderStream(new ByteArrayInputStream(
- PGPSignatureVerifier.unnormalizedPGPProperty(armoredPublicKeyring).getBytes()))) {
+ PGPSignatureVerifier.unnormalizedPGPProperty(armoredPublicKeyring)
+ .getBytes(StandardCharsets.US_ASCII)))) {
new JcaPGPObjectFactory(stream).forEach(o -> {
if (o instanceof PGPPublicKeyRingCollection) {
collectKeys((PGPPublicKeyRingCollection) o, res::add);
@@ -108,7 +109,7 @@ public class PGPPublicKeyStore {
res.add((PGPPublicKey) o);
}
});
- } catch (IOException e) {
+ } catch (IOException | PGPRuntimeOperationException e) {
LogHelper.log(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
}
return res;
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
index d752d1b61..b994b7740 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
@@ -11,22 +11,30 @@
package org.eclipse.equinox.internal.p2.artifact.processors.pgp;
import java.io.*;
+import java.nio.charset.StandardCharsets;
import java.util.*;
+import java.util.Map.Entry;
import org.bouncycastle.bcpg.ArmoredInputStream;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory;
+import org.bouncycastle.openpgp.operator.PGPContentVerifier;
+import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilder;
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.repository.Activator;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStep;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.repository.artifact.*;
+import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
import org.eclipse.osgi.util.NLS;
/**
- * This processing step verifies PGP signatures are correct (ie artifact was not
- * tampered during fetch). Note that is does <b>not</b> deal with trust. Dealing
- * with trusted signers is done as part of CheckTrust touchpoint and phase.
+ * This processing step verifies PGP signatures are correct (i.e., the artifact
+ * was not tampered during fetch). Note that is does <b>not</b> deal with trust.
+ * Dealing with trusted signers is done as part of CheckTrust and touchpoint
+ * phase.
*/
public final class PGPSignatureVerifier extends ProcessingStep {
@@ -37,11 +45,19 @@ public final class PGPSignatureVerifier extends ProcessingStep {
*/
public static final String ID = "org.eclipse.equinox.p2.processing.PGPSignatureCheck"; //$NON-NLS-1$
- public static final PGPPublicKeyStore KNOWN_KEYS = new PGPPublicKeyStore();
-
public static final String PGP_SIGNER_KEYS_PROPERTY_NAME = "pgp.publicKeys"; //$NON-NLS-1$
+
public static final String PGP_SIGNATURES_PROPERTY_NAME = "pgp.signatures"; //$NON-NLS-1$
- private Collection<PGPSignature> signaturesToVerify;
+
+ private PGPPublicKeyService keyService;
+
+ private IArtifactDescriptor sourceDescriptor;
+
+ private Map<PGPSignature, List<PGPContentVerifier>> signaturesToVerify = new LinkedHashMap<>();
+
+ private Map<PGPContentVerifier, PGPPublicKey> verifierKeys = new LinkedHashMap<>();
+
+ private List<OutputStream> signatureVerifiers = new ArrayList<>();
public PGPSignatureVerifier() {
super();
@@ -55,7 +71,8 @@ public final class PGPSignatureVerifier extends ProcessingStep {
return Collections.emptyList();
}
List<PGPSignature> res = new ArrayList<>();
- try (InputStream in = new ArmoredInputStream(new ByteArrayInputStream(signatureText.getBytes()))) {
+ try (InputStream in = new ArmoredInputStream(
+ new ByteArrayInputStream(signatureText.getBytes(StandardCharsets.US_ASCII)))) {
PGPObjectFactory pgpFactory = new BcPGPObjectFactory(in);
Object o = pgpFactory.nextObject();
PGPSignatureList signatureList = new PGPSignatureList(new PGPSignature[0]);
@@ -71,43 +88,74 @@ public final class PGPSignatureVerifier extends ProcessingStep {
return res;
}
+ public static PGPPublicKeyStore getKeys(IArtifactDescriptor artifact) {
+ PGPPublicKeyStore keyStore = new PGPPublicKeyStore();
+ String keyText = artifact.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME);
+ PGPPublicKeyStore.readPublicKeys(keyText).stream().forEach(keyStore::addKey);
+ return keyStore;
+ }
+
@Override
public void initialize(IProvisioningAgent agent, IProcessingStepDescriptor descriptor,
IArtifactDescriptor context) {
super.initialize(agent, descriptor, context);
+
+ sourceDescriptor = context;
+ keyService = agent.getService(PGPPublicKeyService.class);
+
// 1. verify declared public keys have signature from a trusted key, if so, add to KeyStore
-// 2. verify artifact signature matches signture of given keys, and at least 1 of this key is trusted
+// 2. verify artifact signature matches signature of given keys, and at least 1 of this key is trusted
String signatureText = unnormalizedPGPProperty(context.getProperty(PGP_SIGNATURES_PROPERTY_NAME));
if (signatureText == null) {
setStatus(Status.OK_STATUS);
return;
}
+
+ Collection<PGPSignature> signatures;
try {
- signaturesToVerify = getSignatures(context);
+ signatures = getSignatures(context);
} catch (Exception ex) {
setStatus(new Status(IStatus.ERROR, Activator.ID, Messages.Error_CouldNotLoadSignature, ex));
return;
}
- if (signaturesToVerify.isEmpty()) {
+
+ if (signatures.isEmpty()) {
setStatus(Status.OK_STATUS);
return;
}
IArtifactRepository repository = context.getRepository();
- KNOWN_KEYS.addKeys(context.getProperty(PGP_SIGNER_KEYS_PROPERTY_NAME),
- repository != null ? repository.getProperty(PGP_SIGNER_KEYS_PROPERTY_NAME) : null);
- for (PGPSignature signature : signaturesToVerify) {
- PGPPublicKey publicKey = KNOWN_KEYS.getKey(signature.getKeyID());
- if (publicKey == null) {
- setStatus(new Status(IStatus.ERROR, Activator.ID,
- NLS.bind(Messages.Error_publicKeyNotFound, Long.toHexString(signature.getKeyID()))));
- return;
- }
- try {
- signature.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
- } catch (PGPException ex) {
- setStatus(new Status(IStatus.ERROR, Activator.ID, ex.getMessage(), ex));
- return;
+
+ PGPPublicKeyStore.readPublicKeys(context.getProperty(PGP_SIGNER_KEYS_PROPERTY_NAME))
+ .forEach(keyService::addKey);
+ if (repository != null) {
+ PGPPublicKeyStore.readPublicKeys(repository.getProperty(PGP_SIGNER_KEYS_PROPERTY_NAME))
+ .forEach(keyService::addKey);
+ }
+
+ for (PGPSignature signature : signatures) {
+ long keyID = signature.getKeyID();
+ Collection<PGPPublicKey> keys = keyService.getKeys(keyID);
+ if (keys.isEmpty()) {
+ LogHelper.log(new Status(IStatus.WARNING, Activator.ID,
+ NLS.bind(Messages.Warning_publicKeyNotFound, PGPPublicKeyService.toHex(keyID),
+ context.getArtifactKey().getId())));
+ } else {
+ try {
+ PGPContentVerifierBuilder verifierBuilder = new BcPGPContentVerifierBuilderProvider()
+ .get(signature.getKeyAlgorithm(), signature.getHashAlgorithm());
+ List<PGPContentVerifier> verifiers = new ArrayList<>();
+ signaturesToVerify.put(signature, verifiers);
+ for (PGPPublicKey key : keys) {
+ PGPContentVerifier verifier = verifierBuilder.build(key);
+ verifierKeys.put(verifier, key);
+ verifiers.add(verifier);
+ signatureVerifiers.add(verifier.getOutputStream());
+ }
+ } catch (PGPException ex) {
+ setStatus(new Status(IStatus.ERROR, Activator.ID, ex.getMessage(), ex));
+ return;
+ }
}
}
}
@@ -134,51 +182,94 @@ public final class PGPSignatureVerifier extends ProcessingStep {
}
@Override
- public void write(int b) {
- if (signaturesToVerify != null) {
- signaturesToVerify.iterator().forEachRemaining(signature -> signature.update((byte) b));
- }
-
- }
-
- @Override
- public void write(byte[] b) throws IOException {
+ public void write(int b) throws IOException {
getDestination().write(b);
- if (signaturesToVerify != null) {
- signaturesToVerify.iterator().forEachRemaining(signature -> signature.update(b));
+ for (OutputStream verifier : signatureVerifiers) {
+ verifier.write(b);
}
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
getDestination().write(b, off, len);
- if (signaturesToVerify != null) {
- signaturesToVerify.iterator().forEachRemaining(signature -> signature.update(b, off, len));
+ for (OutputStream verifier : signatureVerifiers) {
+ verifier.write(b, off, len);
}
}
@Override
- public void close() {
- if (!getStatus().isOK()) {
- return;
- }
- if (signaturesToVerify == null || signaturesToVerify.isEmpty()) {
- return;
- }
- Iterator<PGPSignature> iterator = signaturesToVerify.iterator();
- while (iterator.hasNext()) {
- PGPSignature signature = iterator.next();
- try {
- if (!signature.verify()) {
+ public void close() throws IOException {
+ try {
+ if (!getStatus().isOK()) {
+ return;
+ }
+
+ if (signaturesToVerify.isEmpty()) {
+ return;
+ }
+
+ PGPPublicKeyStore keyStore = new PGPPublicKeyStore();
+ for (Entry<PGPSignature, List<PGPContentVerifier>> entry : signaturesToVerify.entrySet()) {
+ PGPSignature signature = entry.getKey();
+ List<PGPContentVerifier> verifiers = entry.getValue();
+ boolean verified = false;
+ for (PGPContentVerifier verifier : verifiers) {
+ try {
+ verifier.getOutputStream().write(signature.getSignatureTrailer());
+ if (verifier.verify(signature.getSignature())) {
+ PGPPublicKey verifyingKey = verifierKeys.get(verifier);
+ if (!Boolean.FALSE.toString()
+ .equalsIgnoreCase(System.getProperty("p2.pgp.verifyExpiration"))) { //$NON-NLS-1$
+ if (PGPPublicKeyService.compareSignatureTimeToKeyValidityTime(signature,
+ verifyingKey) != 0) {
+ LogHelper.log(new Status(IStatus.WARNING, Activator.ID,
+ NLS.bind(Messages.Error_SignatureAfterKeyExpiration, PGPPublicKeyService
+ .toHexFingerprint(verifyingKey))));
+ }
+ }
+
+ if (!Boolean.FALSE.toString()
+ .equalsIgnoreCase(System.getProperty("p2.pgp.verifyRevocation"))) { //$NON-NLS-1$
+ if (!keyService.isCreatedBeforeRevocation(signature, verifyingKey)) {
+ setStatus(new Status(IStatus.ERROR, Activator.ID,
+ NLS.bind(Messages.Error_SignatureAfterKeyRevocation, PGPPublicKeyService
+ .toHexFingerprint(verifyingKey))));
+ return;
+ }
+ }
+
+ keyStore.addKey(verifyingKey);
+ verified = true;
+ break;
+ }
+ } catch (PGPException ex) {
+ LogHelper.log(new Status(IStatus.ERROR, Activator.ID, ex.getMessage(), ex));
+ }
+ }
+
+ if (!verified) {
setStatus(new Status(IStatus.ERROR, Activator.ID, Messages.Error_SignatureAndFileDontMatch));
return;
}
- } catch (PGPException ex) {
- setStatus(new Status(IStatus.ERROR, Activator.ID, ex.getMessage(), ex));
- return;
}
+
+ // Update the destination artifact descriptor with the signatures that have been
+ // verified and the keys used for that verification.
+ OutputStream destination = getDestination();
+ if (destination instanceof IAdaptable) {
+ ArtifactDescriptor destinationDescriptor = ((IAdaptable) destination)
+ .getAdapter(ArtifactDescriptor.class);
+ destinationDescriptor.setProperty(PGP_SIGNATURES_PROPERTY_NAME,
+ sourceDescriptor.getProperty(PGP_SIGNATURES_PROPERTY_NAME));
+ destinationDescriptor.setProperty(PGP_SIGNER_KEYS_PROPERTY_NAME, keyStore.toArmoredString());
+ }
+
+ setStatus(Status.OK_STATUS);
+ } finally
+
+ {
+ super.close();
}
- setStatus(Status.OK_STATUS);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/messages.properties b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/messages.properties
index 90d95f756..09a1e7292 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/messages.properties
@@ -9,6 +9,8 @@
# SPDX-License-Identifier: EPL-2.0
###############################################################################
-Error_SignatureAndFileDontMatch=Signature is invalid for current content.
-Error_CouldNotLoadSignature=Could not load signature
-Error_publicKeyNotFound=Public key not found for {0}.
+Error_SignatureAfterKeyRevocation=The signature is created after the revocation time of the signature's key {0}
+Error_SignatureAfterKeyExpiration=The signature is created after the expiration time of the signature's key {0}
+Error_SignatureAndFileDontMatch=The signature is invalid for current content
+Error_CouldNotLoadSignature=The signatures could not be loaded
+Warning_publicKeyNotFound=A public key with ID {0} needed to verify the signatures of {1} could not be found
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
index d9f4dfe22..ccd932110 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
@@ -23,7 +23,6 @@ import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactDescriptor;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.repository.Transport;
@@ -201,14 +200,6 @@ public class MirrorRequest extends ArtifactRequest {
((ArtifactDescriptor) destinationDescriptor).addProperties(targetDescriptorProperties);
if (targetRepositoryProperties != null && destinationDescriptor instanceof SimpleArtifactDescriptor)
((SimpleArtifactDescriptor) destinationDescriptor).addRepositoryProperties(targetRepositoryProperties);
- if (isCanonical && destinationDescriptor instanceof ArtifactDescriptor) {
- // keep some safety properties
- if (sourceDescriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME) != null) {
- ((ArtifactDescriptor) destinationDescriptor)
- .addProperties(Map.of(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME,
- sourceDescriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME)));
- }
- }
return destinationDescriptor;
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
index d627642d0..b13c03692 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/simple/SimpleArtifactRepository.java
@@ -121,7 +121,7 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
private long cacheTimestamp = 0l;
- public class ArtifactOutputStream extends OutputStream implements IStateful {
+ public class ArtifactOutputStream extends OutputStream implements IStateful, IAdaptable {
private boolean closed;
private long count = 0;
private IArtifactDescriptor descriptor;
@@ -205,6 +205,14 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
public void setFirstLink(OutputStream value) {
firstLink = value;
}
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ if (adapter.isInstance(descriptor)) {
+ return adapter.cast(descriptor);
+ }
+ return null;
+ }
}
// TODO: optimize
@@ -506,7 +514,7 @@ public class SimpleArtifactRepository extends AbstractArtifactRepository impleme
Set<String> skipChecksums = DOWNLOAD_MD5_CHECKSUM_ENABLED ? Collections.emptySet() : Collections.singleton(ChecksumHelper.MD5);
ArrayList<ProcessingStep> downloadChecksumSteps = new ArrayList<>();
addChecksumVerifiers(descriptor, downloadChecksumSteps, skipChecksums, IArtifactDescriptor.DOWNLOAD_CHECKSUM);
- if (downloadChecksumSteps.isEmpty()) {
+ if (downloadChecksumSteps.isEmpty() && !isLocal()) {
LogHelper.log(new Status(IStatus.WARNING, Activator.ID,
NLS.bind(Messages.noDigestAlgorithmToVerifyDownload, descriptor.getArtifactKey())));
}
diff --git a/bundles/org.eclipse.equinox.p2.console/pom.xml b/bundles/org.eclipse.equinox.p2.console/pom.xml
index b069fcb80..6be37ac24 100644
--- a/bundles/org.eclipse.equinox.p2.console/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.console/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.core/META-INF/MANIFEST.MF
index fdd4ec76f..73462bd3e 100644
--- a/bundles/org.eclipse.equinox.p2.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.core;singleton:=true
-Bundle-Version: 2.8.100.qualifier
+Bundle-Version: 2.9.100.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.equinox.internal.p2.core.Activator
Bundle-Vendor: %providerName
@@ -64,14 +64,16 @@ Export-Package: org.eclipse.equinox.internal.p2.core;x-friends:="org.eclipse.equ
org.eclipse.equinox.p2.updatesite,
org.eclipse.equinox.p2.director.app,
org.eclipse.equinox.p2.transport.ecf",
- org.eclipse.equinox.p2.core;version="2.7.0",
- org.eclipse.equinox.p2.core.spi;version="2.1.0"
-Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)"
+ org.eclipse.equinox.p2.core;version="2.8.0";uses:="org.eclipse.core.runtime",
+ org.eclipse.equinox.p2.core.spi;version="2.1.0";uses:="org.eclipse.equinox.p2.core"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/eventBus.xml, OSGI-INF/agentProvider.xml
Import-Package: org.bouncycastle.bcpg;version="1.65.0",
org.bouncycastle.openpgp;version="1.65.0",
+ org.eclipse.core.runtime;common=split;version="[3.5.0,4.0.0)",
+ org.eclipse.equinox.p2.core;version="[2.8.0,2.9.0)";resolution:=optional,
+ org.eclipse.equinox.p2.core.spi;version="[2.1.0,2.2.0)";resolution:=optional,
org.eclipse.osgi.framework.eventmgr;version="1.2.0",
org.eclipse.osgi.framework.log;version="1.0.0",
org.eclipse.osgi.service.debug;version="1.0.0",
diff --git a/bundles/org.eclipse.equinox.p2.core/META-INF/p2.inf b/bundles/org.eclipse.equinox.p2.core/META-INF/p2.inf
new file mode 100644
index 000000000..0983c41b7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.core/META-INF/p2.inf
@@ -0,0 +1,5 @@
+# Workaround https://bugs.eclipse.org/bugs/show_bug.cgi?id=525368
+# we hint about which bundle to download at install that is capable of
+# resolving packages
+requires.0.namespace = osgi.bundle
+requires.0.name = org.eclipse.equinox.common \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.core/pom.xml b/bundles/org.eclipse.equinox.p2.core/pom.xml
index 4126209ae..3913f722d 100644
--- a/bundles/org.eclipse.equinox.p2.core/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.core/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.core</artifactId>
- <version>2.8.100-SNAPSHOT</version>
+ <version>2.9.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/internal/p2/core/helpers/SecureXMLUtil.java b/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/internal/p2/core/helpers/SecureXMLUtil.java
index 202921c17..0afeb2936 100644
--- a/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/internal/p2/core/helpers/SecureXMLUtil.java
+++ b/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/internal/p2/core/helpers/SecureXMLUtil.java
@@ -16,7 +16,6 @@ package org.eclipse.equinox.internal.p2.core.helpers;
import javax.xml.XMLConstants;
import javax.xml.parsers.*;
import org.xml.sax.*;
-import org.xml.sax.helpers.XMLReaderFactory;
/**
* A utility class for creating an XML-related factories suitable for
@@ -52,10 +51,11 @@ public class SecureXMLUtil {
* Create a new {@link XMLReader}.
*
* @throws SAXException
+ * @throws ParserConfigurationException
*/
- public static XMLReader newSecureXMLReader() throws SAXException {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- return reader;
+ public static XMLReader newSecureXMLReader() throws SAXException, ParserConfigurationException {
+ SAXParserFactory factory = newSecureSAXParserFactory();
+ factory.setNamespaceAware(true);
+ return factory.newSAXParser().getXMLReader();
}
}
diff --git a/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/p2/core/UIServices.java b/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/p2/core/UIServices.java
index 7a29b1d9b..5be838d4b 100644
--- a/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/p2/core/UIServices.java
+++ b/bundles/org.eclipse.equinox.p2.core/src/org/eclipse/equinox/p2/core/UIServices.java
@@ -73,13 +73,14 @@ public abstract class UIServices {
}
/**
- * Trust information returned from a trust request. *
+ * Trust information returned from a trust request.
*/
public static class TrustInfo {
private final Certificate[] trustedCertificates;
private final Collection<PGPPublicKey> trustedPGPKeys;
private final boolean saveTrustedCertificates;
private final boolean trustUnsigned;
+ private final boolean trustAlways;
/**
*
@@ -96,6 +97,7 @@ public abstract class UIServices {
this.trustedPGPKeys = Collections.emptyList();
this.saveTrustedCertificates = save;
this.trustUnsigned = trustUnsigned;
+ trustAlways = false;
}
/**
@@ -112,6 +114,28 @@ public abstract class UIServices {
public TrustInfo(Collection<Certificate> trustedCertificates, Collection<PGPPublicKey> trustedPGPKeys,
boolean save,
boolean trustUnsigned) {
+ this(trustedCertificates, trustedPGPKeys, save, trustUnsigned, false);
+ }
+
+ /**
+ * @param trustedCertificates Trusted certificates
+ * @param trustedPGPKeys Trusted PGP public keys
+ * @param save Whether to store trusted certificates and keys or
+ * not.
+ * @param trustUnsigned Whether to trust unsigned content.
+ * <code>true</code> if installation should continue
+ * despite unsigned content; <code>false</code>
+ * otherwise.
+ * @param trustAlways Whether to always trust all content regardless of
+ * whether it's signed, regardless of how it's
+ * signed, and regardless of the certificate or key
+ * with which it's signed.
+ *
+ * @since 2.9
+ */
+ public TrustInfo(Collection<Certificate> trustedCertificates, Collection<PGPPublicKey> trustedPGPKeys,
+ boolean save, boolean trustUnsigned, boolean trustAlways) {
+ this.trustAlways = trustAlways;
this.trustedCertificates = trustedCertificates.toArray(Certificate[]::new);
this.trustedPGPKeys = trustedPGPKeys;
this.saveTrustedCertificates = save;
@@ -131,7 +155,10 @@ public abstract class UIServices {
/**
*
- * @return the trusted PGP keys
+ * Return a collection of the keys that should be trusted for the requested
+ * operation.
+ *
+ * @return the trusted PGP keys.
* @since 2.8
*/
public Collection<PGPPublicKey> getTrustedPGPKeys() {
@@ -159,6 +186,20 @@ public abstract class UIServices {
public boolean trustUnsignedContent() {
return trustUnsigned;
}
+
+ /**
+ * Return a boolean indicating whether to always trust all content regardless of
+ * whether it's signed, regardless of how it's signed, and regardless of the
+ * certificate or key with which it's signed, both during this operation and for
+ * all future operations.
+ *
+ * @return <code>true</code> if all content should always be trusted, and
+ * <code>false</code> otherwise.
+ * @since 2.9
+ */
+ public boolean trustAlways() {
+ return trustAlways;
+ }
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF
index 04b4a7068..7cbc86f19 100644
--- a/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.director.app/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.director.app;singleton:=true
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.2.100.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.director.app.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -10,14 +10,15 @@ Export-Package: org.eclipse.equinox.internal.p2.director.app;x-internal:=true
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
-Import-Package: org.eclipse.equinox.app,
+Import-Package: org.bouncycastle.openpgp,
+ org.eclipse.equinox.app,
org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.p2.director,
org.eclipse.equinox.internal.p2.engine,
org.eclipse.equinox.internal.provisional.p2.core.eventbus,
org.eclipse.equinox.internal.provisional.p2.director,
org.eclipse.equinox.internal.provisional.p2.repository,
- org.eclipse.equinox.p2.core;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.core;version="[2.8.0,3.0.0)",
org.eclipse.equinox.p2.core.spi;version="[2.1.0,3.0.0)",
org.eclipse.equinox.p2.engine;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.engine.query;version="[2.0.0,3.0.0)",
diff --git a/bundles/org.eclipse.equinox.p2.director.app/pom.xml b/bundles/org.eclipse.equinox.p2.director.app/pom.xml
index 0ee657185..44f4bde1c 100644
--- a/bundles/org.eclipse.equinox.p2.director.app/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.director.app/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.director.app</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
index d163af047..4710d4cc1 100644
--- a/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
+++ b/bundles/org.eclipse.equinox.p2.director.app/src/org/eclipse/equinox/internal/p2/director/app/DirectorApplication.java
@@ -32,6 +32,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import org.bouncycastle.openpgp.PGPPublicKey;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
@@ -85,6 +86,21 @@ public class DirectorApplication implements IApplication, ProvisioningListener {
}
return new TrustInfo(trusted, false, true);
}
+
+ @Override
+ public TrustInfo getTrustInfo(Certificate[][] untrustedChains, Collection<PGPPublicKey> untrustedPGPKeys,
+ String[] unsignedDetail) {
+ final Collection<Certificate> trusted;
+ if (untrustedChains == null) {
+ trusted = List.of();
+ } else {
+ trusted = new ArrayList<>(untrustedChains.length);
+ for (Certificate[] untrustedChain : untrustedChains) {
+ trusted.add(untrustedChain[0]);
+ }
+ }
+ return new TrustInfo(trusted, untrustedPGPKeys, false, true);
+ }
}
class LocationQueryable implements IQueryable<IInstallableUnit> {
diff --git a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
index 79fb04c24..8b2a73e25 100644
--- a/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.director/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.director;singleton:=true
-Bundle-Version: 2.5.100.qualifier
+Bundle-Version: 2.5.200.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.equinox.internal.p2.director.DirectorActivator
Bundle-Vendor: %providerName
diff --git a/bundles/org.eclipse.equinox.p2.director/pom.xml b/bundles/org.eclipse.equinox.p2.director/pom.xml
index 935a2cc28..0a32c8db0 100644
--- a/bundles/org.eclipse.equinox.p2.director/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.director/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.director</artifactId>
- <version>2.5.100-SNAPSHOT</version>
+ <version>2.5.200-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/DirectorActivator.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/DirectorActivator.java
index 7d331936f..a2960e384 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/DirectorActivator.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/DirectorActivator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2017 IBM Corporation and others.
+ * Copyright (c) 2007, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,24 +10,26 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Christoph Läubrich - access activator static singelton in a safe way
*******************************************************************************/
package org.eclipse.equinox.internal.p2.director;
+import java.util.Optional;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class DirectorActivator implements BundleActivator {
public static final String PI_DIRECTOR = "org.eclipse.equinox.p2.director"; //$NON-NLS-1$
- public static BundleContext context;
+ public static volatile Optional<BundleContext> context = Optional.empty();
@Override
public void start(BundleContext ctx) throws Exception {
- context = ctx;
+ context = Optional.of(ctx);
}
@Override
public void stop(BundleContext ctx) throws Exception {
- DirectorActivator.context = null;
+ DirectorActivator.context = Optional.empty();
}
}
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
index ae30164ad..458a8fb86 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/p2/director/Projector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2020 IBM Corporation and others.
+ * Copyright (c) 2007, 2022 IBM Corporation and others.
*
* This
* program and the accompanying materials are made available under the terms of
@@ -17,6 +17,7 @@
* Sonatype, Inc. - ongoing development
* Rapicorp, Inc. - split the optimization function
* Red Hat, Inc. - support for remediation page
+ * Christoph Läubrich - access activator static singelton in a safe way
******************************************************************************/
package org.eclipse.equinox.internal.p2.director;
@@ -207,7 +208,8 @@ public class Projector {
// allow the user to specify a longer timeout.
// only set the value if it is a positive integer larger than the default.
// see https://bugs.eclipse.org/336967
- timeoutString = DirectorActivator.context.getProperty(PROP_PROJECTOR_TIMEOUT);
+ timeoutString = DirectorActivator.context.map(ctx -> ctx.getProperty(PROP_PROJECTOR_TIMEOUT))
+ .orElse(null);
if (timeoutString != null)
timeout = Math.max(timeout, Integer.parseInt(timeoutString));
} catch (Exception e) {
diff --git a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/PlanExecutionHelper.java b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/PlanExecutionHelper.java
index 4c51ca1a9..83ac500b7 100644
--- a/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/PlanExecutionHelper.java
+++ b/bundles/org.eclipse.equinox.p2.director/src/org/eclipse/equinox/internal/provisional/p2/director/PlanExecutionHelper.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2015 IBM Corporation and others.
+ * Copyright (c) 2009, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -11,6 +11,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Red Hat Inc. - Bug 460967
+ * Christoph Läubrich - access activator static singelton in a safe way
*******************************************************************************/
package org.eclipse.equinox.internal.provisional.p2.director;
@@ -36,7 +37,8 @@ public class PlanExecutionHelper {
.getService(IEngine.class).perform(result.getInstallerPlan(), phaseSet, progress);
if (!installerPlanStatus.isOK())
return installerPlanStatus;
- Configurator configChanger = ServiceHelper.getService(DirectorActivator.context, Configurator.class);
+ Configurator configChanger = DirectorActivator.context
+ .map(ctx -> ServiceHelper.getService(ctx, Configurator.class)).orElse(null);
try {
configChanger.applyConfiguration();
} catch (IOException e) {
diff --git a/bundles/org.eclipse.equinox.p2.directorywatcher/pom.xml b/bundles/org.eclipse.equinox.p2.directorywatcher/pom.xml
index 5505474fc..ece589593 100644
--- a/bundles/org.eclipse.equinox.p2.directorywatcher/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.directorywatcher/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF
index 277ae2f5f..fbfa7e023 100644
--- a/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.equinox.p2.discovery.compatibility;singleton:=true
-Bundle-Version: 1.2.100.qualifier
+Bundle-Version: 1.2.200.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.3.0",
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/pom.xml b/bundles/org.eclipse.equinox.p2.discovery.compatibility/pom.xml
index 23c6cc4d1..b926dd577 100644
--- a/bundles/org.eclipse.equinox.p2.discovery.compatibility/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/pom.xml
@@ -14,11 +14,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.discovery.compatibility</artifactId>
- <version>1.2.100-SNAPSHOT</version>
+ <version>1.2.200-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java
index 97a21448c..9cbb8d0a3 100644
--- a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java
@@ -16,6 +16,7 @@ package org.eclipse.equinox.internal.p2.discovery.compatibility;
import java.io.IOException;
import java.io.Reader;
+import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.equinox.internal.p2.core.helpers.SecureXMLUtil;
import org.eclipse.equinox.internal.p2.discovery.compatibility.Directory.Entry;
import org.eclipse.equinox.internal.p2.discovery.compatibility.util.DefaultSaxErrorHandler;
@@ -42,7 +43,7 @@ public class DirectoryParser {
XMLReader xmlReader;
try {
xmlReader = SecureXMLUtil.newSecureXMLReader();
- } catch (SAXException e) {
+ } catch (SAXException | ParserConfigurationException e) {
throw new IOWithCauseException(e.getMessage(), e);
}
xmlReader.setErrorHandler(new DefaultSaxErrorHandler());
diff --git a/bundles/org.eclipse.equinox.p2.discovery/pom.xml b/bundles/org.eclipse.equinox.p2.discovery/pom.xml
index 6930630fe..08c1a9a53 100644
--- a/bundles/org.eclipse.equinox.p2.discovery/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.discovery/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF
index d1e7137aa..561283093 100644
--- a/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF
@@ -46,9 +46,10 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.p2.query;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.artifact;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.repository.artifact.spi;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.metadata;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.metadata.spi;version="[2.0.0,3.0.0)",
- org.eclipse.equinox.p2.repository.spi;version="2.0.0",
+ org.eclipse.equinox.p2.repository.spi;version="[2.0.0,3.0.0)",
org.eclipse.osgi.service.datalocation;version="1.0.0",
org.eclipse.osgi.service.debug;version="1.1.0",
org.eclipse.osgi.service.security;version="1.0.0",
diff --git a/bundles/org.eclipse.equinox.p2.engine/plugin.xml b/bundles/org.eclipse.equinox.p2.engine/plugin.xml
index 3d469f492..cee2c3856 100644
--- a/bundles/org.eclipse.equinox.p2.engine/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.engine/plugin.xml
@@ -4,6 +4,7 @@
<extension-point id="touchpoints" name="Touchpoints" schema="schema/touchpoints.exsd"/>
<extension-point id="actions" name="Actions" schema="schema/actions.exsd"/>
+<extension-point id="pgp" name="PGP" schema="schema/pgp.exsd"/>
<extension
id="metadataRepository"
point="org.eclipse.equinox.p2.metadata.repository.metadataRepositories">
diff --git a/bundles/org.eclipse.equinox.p2.engine/pom.xml b/bundles/org.eclipse.equinox.p2.engine/pom.xml
index cbf8386be..eb9562492 100644
--- a/bundles/org.eclipse.equinox.p2.engine/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.engine/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.engine/schema/pgp.exsd b/bundles/org.eclipse.equinox.p2.engine/schema/pgp.exsd
new file mode 100644
index 000000000..fcb06d04a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/schema/pgp.exsd
@@ -0,0 +1,107 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.equinox.p2.engine" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.equinox.p2.engine" id="pgp" name="PGP"/>
+ </appInfo>
+ <documentation>
+ Configure PGP keys and trust for p2 operations
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <element ref="trustedKeys"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="trustedKeys">
+ <annotation>
+ <documentation>
+ PGP Keys that are trusted by default.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="path" type="string">
+ <annotation>
+ <documentation>
+ Path to a file containing PGP keys in armored form.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 2.7.300
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java
index 15943a47c..3a1589f8b 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java
@@ -13,14 +13,17 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.engine.phases;
-import java.io.File;
-import java.io.IOException;
+import java.io.*;
+import java.net.URL;
+import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
-import java.security.cert.Certificate;
+import java.security.cert.*;
import java.util.*;
import java.util.Map.Entry;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
-import org.bouncycastle.openpgp.*;
+import java.util.stream.Stream;
+import org.bouncycastle.openpgp.PGPPublicKey;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPPublicKeyStore;
@@ -28,13 +31,16 @@ import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerif
import org.eclipse.equinox.internal.p2.engine.*;
import org.eclipse.equinox.p2.core.*;
import org.eclipse.equinox.p2.core.UIServices.TrustInfo;
-import org.eclipse.equinox.p2.engine.*;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.engine.ProfileScope;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.artifact.spi.IArtifactUIServices;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
import org.eclipse.osgi.service.security.TrustEngine;
import org.eclipse.osgi.signedcontent.*;
import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.*;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.util.tracker.ServiceTracker;
@@ -46,15 +52,49 @@ import org.osgi.util.tracker.ServiceTracker;
public class CertificateChecker {
private static final String DEBUG_PREFIX = "certificate checker"; //$NON-NLS-1$
+ public static final String TRUST_ALWAYS_PROPERTY = "trustAlways"; //$NON-NLS-1$
+
public static final String TRUSTED_KEY_STORE_PROPERTY = "pgp.trustedPublicKeys"; //$NON-NLS-1$
+ public static final String TRUSTED_CERTIFICATES_PROPERTY = "trustedCertificates"; //$NON-NLS-1$
+
+ /***
+ * Store the optional profile for PGP key handling
+ */
+ private IProfile profile;
+
/**
* Stores artifacts to check
*/
private Map<IArtifactDescriptor, File> artifacts = new HashMap<>();
private final IProvisioningAgent agent;
+ private final PGPPublicKeyService keyService;
- private PGPPublicKeyStore trustedKeys;
+ // Lazily loading
+ private Supplier<PGPPublicKeyStore> trustedKeys = new Supplier<>() {
+ private PGPPublicKeyStore cache = null;
+
+ public PGPPublicKeyStore get() {
+ if (cache == null) {
+ cache = getPreferenceTrustedKeys();
+ getContributedTrustedKeys().keySet().forEach(cache::addKey);
+ }
+ return cache;
+ }
+ };
+
+ // Lazily loading in case we ever add an extension point for registering
+ // certificates.
+ private Supplier<Collection<? extends Certificate>> additionalTrustedCertificates = new Supplier<>() {
+ private Collection<? extends Certificate> cache = null;
+
+ public Collection<? extends Certificate> get() {
+ if (cache == null) {
+ cache = getPreferenceTrustedCertificates();
+ }
+ return cache;
+ }
+ };
public CertificateChecker() {
this(null);
@@ -63,11 +103,14 @@ public class CertificateChecker {
public CertificateChecker(IProvisioningAgent agent) {
this.agent = agent;
artifacts = new HashMap<>();
+ keyService = agent.getService(PGPPublicKeyService.class);
+
}
public IStatus start() {
final BundleContext context = EngineActivator.getContext();
- ServiceReference<SignedContentFactory> contentFactoryRef = context.getServiceReference(SignedContentFactory.class);
+ ServiceReference<SignedContentFactory> contentFactoryRef = context
+ .getServiceReference(SignedContentFactory.class);
SignedContentFactory verifierFactory = context.getService(contentFactoryRef);
try {
return checkCertificates(verifierFactory);
@@ -77,72 +120,95 @@ public class CertificateChecker {
}
private IStatus checkCertificates(SignedContentFactory verifierFactory) {
+ if (artifacts.isEmpty()) {
+ return Status.OK_STATUS;
+ }
+
+ // If unsigned content is allowed then the flood gates are open so there is no
+ // point in checking for unrooted certificates nor for not-yet-trusted keys.
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=578583
+ String policy = getUnsignedContentPolicy();
+ if (EngineActivator.UNSIGNED_ALLOW.equals(policy)) {
+ return Status.OK_STATUS;
+ }
+
UIServices serviceUI = agent.getService(UIServices.class);
- ArrayList<Certificate> untrustedCertificates = new ArrayList<>();
- Map<IArtifactDescriptor, Collection<PGPPublicKey>> untrustedPGPArtifacts = new HashMap<>();
- Map<IArtifactDescriptor, File> unsigned = new HashMap<>();
- ArrayList<Certificate[]> untrustedChain = new ArrayList<>();
- Map<Certificate, Collection<File>> untrustedArtifacts = new HashMap<>();
- IStatus status = Status.OK_STATUS;
- if (artifacts.isEmpty() || serviceUI == null) {
- return status;
+ if (serviceUI == null) {
+ return Status.OK_STATUS;
+ }
+
+ if (isTrustAlways()) {
+ return Status.OK_STATUS;
}
- Set<Long> trustedKeysIds = new HashSet<>();
+
+ IArtifactUIServices artifactServiceUI = serviceUI instanceof IArtifactUIServices
+ ? (IArtifactUIServices) serviceUI
+ : (untrustedCertificateChains, untrustedPGPKeys, unsignedArtifacts,
+ artifactFiles) -> IArtifactUIServices.getTrustInfo(serviceUI, untrustedCertificateChains,
+ untrustedPGPKeys, unsignedArtifacts, artifactFiles);
+
+ Map<List<Certificate>, Set<IArtifactKey>> untrustedCertificates = new LinkedHashMap<>();
+ Map<PGPPublicKey, Set<IArtifactKey>> untrustedPGPKeys = new LinkedHashMap<>();
+ Set<IArtifactKey> unsignedArtifacts = new LinkedHashSet<>();
+ Set<PGPPublicKey> trustedKeySet = new HashSet<>();
+ boolean isTrustedKeySetInitialized = false;
+ Map<IArtifactKey, File> artifactFiles = new LinkedHashMap<>();
for (Entry<IArtifactDescriptor, File> artifact : artifacts.entrySet()) {
+ IArtifactDescriptor artifactDescriptor = artifact.getKey();
+ IArtifactKey artifactKey = artifactDescriptor.getArtifactKey();
File artifactFile = artifact.getValue();
+ artifactFiles.put(artifactKey, artifactFile);
try {
SignedContent content = verifierFactory.getSignedContent(artifactFile);
if (content.isSigned()) {
SignerInfo[] signerInfo = content.getSignerInfos();
- if (Arrays.stream(signerInfo).noneMatch(SignerInfo::isTrusted)) {
- // Only record the untrusted elements if there are no trusted elements.
+ // Only record the untrusted elements if there are no trusted elements.
+ // Also check previously trusted certificates from the preferences.
+ if (Arrays.stream(signerInfo).noneMatch(SignerInfo::isTrusted)
+ && Arrays.stream(signerInfo).map(SignerInfo::getCertificateChain).flatMap(Arrays::stream)
+ .noneMatch(cert -> additionalTrustedCertificates.get().contains(cert))) {
for (SignerInfo element : signerInfo) {
if (!element.isTrusted()) {
- Certificate[] certificateChain = element.getCertificateChain();
- if (!untrustedCertificates.contains(certificateChain[0])) {
- untrustedCertificates.add(certificateChain[0]);
- untrustedChain.add(certificateChain);
- }
- if (DebugHelper.DEBUG_CERTIFICATE_CHECKER_UNTRUSTED) {
- untrustedArtifacts.computeIfAbsent(certificateChain[0], key -> new ArrayList<>())
- .add(artifactFile);
- }
+ List<Certificate> certificateChain = Arrays.asList(element.getCertificateChain());
+ untrustedCertificates.computeIfAbsent(certificateChain, key -> new LinkedHashSet<>())
+ .add(artifactKey);
}
}
}
} else {
- Collection<PGPSignature> signatures = PGPSignatureVerifier.getSignatures(artifact.getKey());
- if (!signatures.isEmpty()) {
- if (trustedKeys == null) {
- trustedKeys = buildPGPTrustore();
- }
- if (trustedKeysIds.isEmpty() && !trustedKeys.isEmpty()) {
- trustedKeysIds.addAll(trustedKeys.all().stream()
- .map(PGPPublicKey::getKeyID).map(Long::valueOf).collect(Collectors.toSet()));
+ // The keys are in this destination artifact's properties if and only if the
+ // PGPSignatureVerifier verified the signatures against these keys.
+ List<PGPPublicKey> verifiedKeys = PGPPublicKeyStore
+ .readPublicKeys(
+ artifactDescriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME))
+ .stream().map(keyService::addKey).collect(Collectors.toList());
+ if (!verifiedKeys.isEmpty()) {
+ if (!isTrustedKeySetInitialized) {
+ isTrustedKeySetInitialized = true;
+ trustedKeySet.addAll(trustedKeys.get().all());
}
- if (signatures.stream().map(PGPSignature::getKeyID).noneMatch(trustedKeysIds::contains)) {
- untrustedPGPArtifacts.put(artifact.getKey(),
- signatures.stream().map(PGPSignature::getKeyID)
- .map(id -> findKey(id, artifact.getKey()))
- .filter(Objects::nonNull)
- .collect(Collectors.toList()));
+ // Only record the untrusted keys if none of the keys are trusted.
+ if (verifiedKeys.stream().noneMatch(trustedKeySet::contains)) {
+ verifiedKeys.forEach(key -> untrustedPGPKeys
+ .computeIfAbsent(key, k -> new LinkedHashSet<>()).add(artifactKey));
}
} else {
- unsigned.put(artifact.getKey(), artifactFile);
+ unsignedArtifacts.add(artifactKey);
}
}
- } catch (GeneralSecurityException | PGPException e) {
+ } catch (GeneralSecurityException e) {
return new Status(IStatus.ERROR, EngineActivator.ID, Messages.CertificateChecker_SignedContentError, e);
} catch (IOException e) {
- return new Status(IStatus.ERROR, EngineActivator.ID, Messages.CertificateChecker_SignedContentIOError, e);
+ return new Status(IStatus.ERROR, EngineActivator.ID, Messages.CertificateChecker_SignedContentIOError,
+ e);
}
}
// log the unsigned artifacts if requested
- if (DebugHelper.DEBUG_CERTIFICATE_CHECKER_UNSIGNED && !unsigned.isEmpty()) {
+ if (DebugHelper.DEBUG_CERTIFICATE_CHECKER_UNSIGNED && !unsignedArtifacts.isEmpty()) {
StringBuilder message = new StringBuilder("The following artifacts are unsigned:\n"); //$NON-NLS-1$
- for (File file : unsigned.values()) {
- message.append(NLS.bind(" {0}\n", file.getPath())); //$NON-NLS-1$
+ for (IArtifactKey key : unsignedArtifacts) {
+ message.append(NLS.bind(" {0}\n", artifactFiles.get(key).getPath())); //$NON-NLS-1$
}
DebugHelper.debug(DEBUG_PREFIX, message.toString());
}
@@ -150,130 +216,161 @@ public class CertificateChecker {
// log the untrusted certificates if requested
if (DebugHelper.DEBUG_CERTIFICATE_CHECKER_UNTRUSTED && !untrustedCertificates.isEmpty()) {
StringBuilder message = new StringBuilder("The following certificates are untrusted:\n"); //$NON-NLS-1$
- for (Certificate cert : untrustedArtifacts.keySet()) {
- message.append(cert.toString() + "\n"); //$NON-NLS-1$
+ for (Map.Entry<List<Certificate>, Set<IArtifactKey>> entry : untrustedCertificates.entrySet()) {
+ message.append(entry.getKey().get(0).toString() + "\n"); //$NON-NLS-1$
message.append(" used by the following artifacts:\n"); //$NON-NLS-1$
- for (File file : untrustedArtifacts.get(cert)) {
- message.append(NLS.bind(" {0}\n", file.getPath())); //$NON-NLS-1$
+ for (IArtifactKey key : entry.getValue()) {
+ message.append(NLS.bind(" {0}\n", artifactFiles.get(key).getPath())); //$NON-NLS-1$
}
+
}
DebugHelper.debug(DEBUG_PREFIX, message.toString());
}
- Set<PGPPublicKey> untrustedPGPKeys = untrustedPGPArtifacts.values().stream().flatMap(Collection::stream)
- .collect(Collectors.toSet());
+
if (DebugHelper.DEBUG_CERTIFICATE_CHECKER_UNTRUSTED && !untrustedPGPKeys.isEmpty()) {
StringBuilder message = new StringBuilder("The following PGP Keys are untrusted:\n"); //$NON-NLS-1$
- for (PGPPublicKey untrustedKey : untrustedPGPKeys) {
- message.append(Long.toHexString(untrustedKey.getKeyID()) + "\n"); //$NON-NLS-1$
+ for (Map.Entry<PGPPublicKey, Set<IArtifactKey>> entry : untrustedPGPKeys.entrySet()) {
+ message.append(Long.toHexString(entry.getKey().getKeyID()) + "\n"); //$NON-NLS-1$
message.append(" used by the following artifacts:\n"); //$NON-NLS-1$
- for (Entry<IArtifactDescriptor, Collection<PGPPublicKey>> entry : untrustedPGPArtifacts.entrySet()) {
- if (entry.getValue().stream().anyMatch(signer -> signer.getKeyID() == untrustedKey.getKeyID())) {
- message.append(NLS.bind(" {0}\n", entry.getKey().getArtifactKey())); //$NON-NLS-1$
- }
+ for (IArtifactKey key : entry.getValue()) {
+ message.append(NLS.bind(" {0}\n", key)); //$NON-NLS-1$
}
}
DebugHelper.debug(DEBUG_PREFIX, message.toString());
}
- String policy = getUnsignedContentPolicy();
- //if there is unsigned content and we should never allow it, then fail without further checking certificates
- if (!unsigned.isEmpty() && EngineActivator.UNSIGNED_FAIL.equals(policy)) {
- return new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.CertificateChecker_UnsignedNotAllowed, unsigned));
+ // if there is unsigned content and we should never allow it, then fail without
+ // further checking certificates
+ if (!unsignedArtifacts.isEmpty() && EngineActivator.UNSIGNED_FAIL.equals(policy)) {
+ return new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(
+ Messages.CertificateChecker_UnsignedNotAllowed,
+ unsignedArtifacts.stream().map(key -> artifactFiles.get(key)).collect(Collectors.toList())));
}
- String[] details = EngineActivator.UNSIGNED_ALLOW.equals(policy) || unsigned.isEmpty() ? null
- : unsigned.values().stream().map(Object::toString).toArray(String[]::new);
- Certificate[][] unTrustedCertificateChains = untrustedCertificates.isEmpty() ? null
- : untrustedChain.toArray(Certificate[][]::new);
// If there was no unsigned content, and nothing untrusted, no need to prompt.
- if (details == null && unTrustedCertificateChains == null && untrustedPGPArtifacts.isEmpty()) {
- return status;
+ if (unsignedArtifacts.isEmpty() && untrustedCertificates.isEmpty() && untrustedPGPKeys.isEmpty()) {
+ return Status.OK_STATUS;
}
- TrustInfo trustInfo = serviceUI.getTrustInfo(unTrustedCertificateChains,
- untrustedPGPKeys,
- details);
+ TrustInfo trustInfo = artifactServiceUI.getTrustInfo(untrustedCertificates, untrustedPGPKeys, unsignedArtifacts,
+ artifactFiles);
- // If user doesn't trust unsigned content, cancel the operation
- if (!unsigned.isEmpty() && !trustInfo.trustUnsignedContent()) {
- return Status.CANCEL_STATUS;
- }
+ setTrustAlways(trustInfo.trustAlways());
- Certificate[] trustedCertificates = trustInfo.getTrustedCertificates();
- // If we had untrusted chains and nothing was trusted, cancel the operation
- if (unTrustedCertificateChains != null && trustedCertificates == null) {
- return new Status(IStatus.CANCEL, EngineActivator.ID, Messages.CertificateChecker_CertificateRejected);
- }
- // Anything that was trusted should be removed from the untrusted list
- if (trustedCertificates != null) {
- for (Certificate trustedCertificate : trustedCertificates) {
- untrustedCertificates.remove(trustedCertificate);
+ if (!trustInfo.trustAlways()) {
+ // If there is unsigned content and user doesn't trust unsigned content, cancel
+ // the operation.
+ if (!unsignedArtifacts.isEmpty() && !trustInfo.trustUnsignedContent()) {
+ return Status.CANCEL_STATUS;
}
- }
- trustedKeysIds
- .addAll(trustInfo.getTrustedPGPKeys().stream().map(PGPPublicKey::getKeyID).collect(Collectors.toSet()));
- untrustedPGPArtifacts.values().removeIf(
- pgpKeys -> pgpKeys.stream().anyMatch(untrusted -> trustedKeysIds.contains(untrusted.getKeyID())));
-
- // If there is still untrusted content, cancel the operation
- if (!untrustedCertificates.isEmpty() || !untrustedPGPArtifacts.isEmpty()) {
- return new Status(IStatus.CANCEL, EngineActivator.ID, Messages.CertificateChecker_CertificateRejected);
- }
- // If we should persist the trusted certificates, add them to the trust engine
- if (trustInfo.persistTrust()) {
- IStatus certifactesStatus = trustInfo.getTrustedCertificates().length == 0 ? null
- : persistTrustedCertificates(trustedCertificates);
- trustInfo.getTrustedPGPKeys().forEach(trustedKeys::addKey);
- IStatus pgpStatus = trustInfo.getTrustedPGPKeys().isEmpty() ? null : persistTrustedKeys(trustedKeys);
- if (pgpStatus == null) {
- return certifactesStatus;
+
+ Certificate[] trustedCertificates = trustInfo.getTrustedCertificates();
+ // If we had untrusted chains and nothing was trusted, cancel the operation
+ if (!untrustedCertificates.isEmpty() && trustedCertificates == null) {
+ return new Status(IStatus.CANCEL, EngineActivator.ID, Messages.CertificateChecker_CertificateRejected);
+ }
+
+ // Anything that was trusted should be removed from the untrusted list
+ if (trustedCertificates != null) {
+ List<Certificate> trustedCertificateList = Arrays.asList(trustedCertificates);
+ untrustedCertificates.keySet().removeIf(it -> trustedCertificateList.contains(it.get(0)));
}
- if (certifactesStatus == null) {
- return pgpStatus;
+
+ trustedKeySet.addAll(trustInfo.getTrustedPGPKeys());
+
+ Set<IArtifactKey> trustedArtifactKeys = trustedKeySet.stream().map(untrustedPGPKeys::get)
+ .filter(Objects::nonNull).flatMap(Set::stream).collect(Collectors.toSet());
+ untrustedPGPKeys.values().forEach(it -> it.removeAll(trustedArtifactKeys));
+ untrustedPGPKeys.values().removeIf(Collection::isEmpty);
+
+ // If there is still untrusted content, cancel the operation
+ if (!untrustedCertificates.isEmpty() || !untrustedPGPKeys.isEmpty()) {
+ return new Status(IStatus.CANCEL, EngineActivator.ID, Messages.CertificateChecker_CertificateRejected);
}
- return new MultiStatus(getClass(), IStatus.OK, new IStatus[] { pgpStatus, certifactesStatus },
- pgpStatus.getMessage() + '\n' + certifactesStatus.getMessage(), null);
}
- return status;
- }
+ // If we should persist the trusted certificates and keys.
+ if (trustInfo.persistTrust()) {
+ List<IStatus> statuses = new ArrayList<>();
+ Set<Certificate> unsavedCertificates = new LinkedHashSet<>();
+ if (trustInfo.getTrustedCertificates() != null) {
+ unsavedCertificates.addAll(Arrays.asList(trustInfo.getTrustedCertificates()));
+ }
+
+ if (!unsavedCertificates.isEmpty()) {
+ // Try to save to the trust engine first.
+ IStatus status = persistTrustedCertificatesInTrustEngine(unsavedCertificates);
+ if (status != null && !status.isOK()) {
+ statuses.add(status);
+ }
- private PGPPublicKey findKey(long id, IArtifactDescriptor artifact) {
- PGPPublicKey key = PGPSignatureVerifier.KNOWN_KEYS.getKey(id);
- if (key != null) {
- return key;
+ // If we couldn't save them in the trust engine, save them in the preferences.
+ if (!unsavedCertificates.isEmpty()) {
+ // Be sure we add the new certificates to the previously saved certificates.
+ unsavedCertificates.addAll(getPreferenceTrustedCertificates());
+ IStatus preferenceStatus = persistTrustedCertificates(unsavedCertificates);
+ if (preferenceStatus != null && !preferenceStatus.isOK()) {
+ statuses.add(preferenceStatus);
+ }
+ }
+ }
+
+ if (!trustInfo.getTrustedPGPKeys().isEmpty()) {
+ // Be sure we add the new keys to the previously saved keys.
+ PGPPublicKeyStore keyStore = getPreferenceTrustedKeys();
+ trustInfo.getTrustedPGPKeys().forEach(keyStore::addKey);
+ IStatus status = persistTrustedKeys(keyStore);
+ if (status != null && !status.isOK()) {
+ statuses.add(status);
+ }
+ }
+
+ if (!statuses.isEmpty()) {
+ if (statuses.size() == 1) {
+ return statuses.get(1);
+ }
+ String message = statuses.stream().map(IStatus::getMessage).collect(Collectors.joining("\n")); //$NON-NLS-1$
+ return new MultiStatus(getClass(), IStatus.OK, statuses.toArray(IStatus[]::new), message, null);
+ }
}
- // in case keys from artifact were not imported yet in keystore, add them
- PGPSignatureVerifier.KNOWN_KEYS
- .addKeys(artifact.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
- return PGPSignatureVerifier.KNOWN_KEYS.getKey(id);
+
+ return Status.OK_STATUS;
}
- private IStatus persistTrustedCertificates(Certificate[] trustedCertificates) {
- if (trustedCertificates == null)
- // I'm pretty sure this would be a bug; trustedCertificates should never be null here.
- return new Status(IStatus.INFO, EngineActivator.ID, Messages.CertificateChecker_CertificateRejected);
- ServiceTracker<TrustEngine, TrustEngine> trustEngineTracker = new ServiceTracker<>(EngineActivator.getContext(), TrustEngine.class, null);
+ /**
+ * This modifies the argument collection to remove the certificates that were
+ * successfully saved. Often no certificates are saved because this tries to
+ * store in the Java runtime cacerts and those are typically read-only.
+ */
+ private IStatus persistTrustedCertificatesInTrustEngine(
+ Collection<? extends Certificate> unsavedTrustedCertificates) {
+ ServiceTracker<TrustEngine, TrustEngine> trustEngineTracker = new ServiceTracker<>(EngineActivator.getContext(),
+ TrustEngine.class, null);
trustEngineTracker.open();
Object[] trustEngines = trustEngineTracker.getServices();
try {
if (trustEngines == null)
return null;
- for (Certificate trustedCertificate : trustedCertificates) {
+ for (Iterator<? extends Certificate> it = unsavedTrustedCertificates.iterator(); it.hasNext();) {
+ Certificate trustedCertificate = it.next();
for (Object engine : trustEngines) {
TrustEngine trustEngine = (TrustEngine) engine;
if (trustEngine.isReadOnly())
continue;
try {
trustEngine.addTrustAnchor(trustedCertificate, trustedCertificate.toString());
- // this should mean we added an anchor successfully; continue to next certificate
+ // this should mean we added an anchor successfully; continue to next
+ // certificate
+ it.remove();
break;
} catch (IOException e) {
- //just return an INFO so the user can proceed with the install
- return new Status(IStatus.INFO, EngineActivator.ID, Messages.CertificateChecker_KeystoreConnectionError, e);
+ // just return an INFO so the user can proceed with the install
+ return new Status(IStatus.INFO, EngineActivator.ID,
+ Messages.CertificateChecker_KeystoreConnectionError, e);
} catch (GeneralSecurityException e) {
- return new Status(IStatus.INFO, EngineActivator.ID, Messages.CertificateChecker_CertificateError, e);
+ return new Status(IStatus.INFO, EngineActivator.ID,
+ Messages.CertificateChecker_CertificateError, e);
}
}
}
@@ -283,6 +380,43 @@ public class CertificateChecker {
return Status.OK_STATUS;
}
+ public IStatus persistTrustedCertificates(Collection<? extends Certificate> trustedCertificates) {
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ IEclipsePreferences node = profileScope.getNode(EngineActivator.ID);
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
+ CertPath certPath = certificateFactory.generateCertPath(new ArrayList<>(trustedCertificates));
+ byte[] encoded = certPath.getEncoded("PKCS7"); //$NON-NLS-1$
+ node.putByteArray(TRUSTED_CERTIFICATES_PROPERTY, encoded);
+ node.flush();
+ } catch (BackingStoreException | CertificateException ex) {
+ return new Status(IStatus.ERROR, EngineActivator.ID, ex.getMessage(), ex);
+ }
+ }
+ return Status.OK_STATUS;
+ }
+
+ public Set<? extends Certificate> getPreferenceTrustedCertificates() {
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ IEclipsePreferences node = profileScope.getNode(EngineActivator.ID);
+ try {
+ byte[] encoded = node.getByteArray(TRUSTED_CERTIFICATES_PROPERTY, null);
+ if (encoded != null) {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
+ CertPath certPath = certificateFactory.generateCertPath(new ByteArrayInputStream(encoded), "PKCS7"); //$NON-NLS-1$
+ return new LinkedHashSet<>(certPath.getCertificates());
+ }
+ } catch (CertificateException ex) {
+ DebugHelper.debug(DEBUG_PREFIX, ex.getMessage());
+ }
+ }
+ return Set.of();
+ }
+
/**
* Return the policy on unsigned content.
*/
@@ -294,37 +428,87 @@ public class CertificateChecker {
}
+ public void setProfile(IProfile profile) {
+ this.profile = profile;
+ }
+
public void add(Map<IArtifactDescriptor, File> toAdd) {
artifacts.putAll(toAdd);
}
- public PGPPublicKeyStore buildPGPTrustore() {
+ public Map<PGPPublicKey, Set<Bundle>> getContributedTrustedKeys() {
+ // Build the map based on fingerprints to properly avoid duplicates as we
+ // accumulate the full set of keys.
+ Map<ByteBuffer, Set<Bundle>> keys = new LinkedHashMap<>();
+
+ // Load from the extension registry.
+ for (IConfigurationElement extension : RegistryFactory.getRegistry()
+ .getConfigurationElementsFor(EngineActivator.ID, "pgp")) { //$NON-NLS-1$
+ if ("trustedKeys".equals(extension.getName())) { //$NON-NLS-1$
+ String pathInBundle = extension.getAttribute("path"); //$NON-NLS-1$
+ if (pathInBundle != null) {
+ String name = extension.getContributor().getName();
+ Stream.of(EngineActivator.getContext().getBundles())
+ .filter(bundle -> bundle.getSymbolicName().equals(name)).findAny().ifPresent(bundle -> {
+ URL keyURL = bundle.getEntry(pathInBundle);
+ try (InputStream stream = keyURL.openStream()) {
+ PGPPublicKeyStore.readPublicKeys(stream).stream().map(keyService::addKey)
+ .forEach(key -> keys.computeIfAbsent(ByteBuffer.wrap(key.getFingerprint()),
+ k -> new LinkedHashSet<>()).add(bundle));
+ } catch (IOException e) {
+ DebugHelper.debug(DEBUG_PREFIX, e.getMessage());
+ }
+ });
+ }
+ }
+ }
+
+ Map<PGPPublicKey, Set<Bundle>> result = keys.entrySet().stream()
+ .collect(Collectors.toMap(entry -> keyService.getKey(entry.getKey().array()), Map.Entry::getValue));
+ return result;
+ }
+
+ public boolean isTrustAlways() {
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ return profileScope.getNode(EngineActivator.ID).getBoolean(TRUST_ALWAYS_PROPERTY, false);
+ }
+ return false;
+ }
+
+ public void setTrustAlways(boolean trustAlways) {
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ profileScope.getNode(EngineActivator.ID).putBoolean(TRUST_ALWAYS_PROPERTY, trustAlways);
+ }
+ }
+
+ public PGPPublicKeyStore getPreferenceTrustedKeys() {
PGPPublicKeyStore trustStore = new PGPPublicKeyStore();
- IProfile profile = agent.getService(IProfileRegistry.class).getProfile(IProfileRegistry.SELF);
- trustStore.addKeys(profile.getProperty(TRUSTED_KEY_STORE_PROPERTY));
- ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class), profile.getProfileId());
- trustStore.addKeys(profileScope.getNode(EngineActivator.ID).get(TRUSTED_KEY_STORE_PROPERTY, null));
- //// SECURITY ISSUE: next lines become an attack vector as we have no guarantee
- //// the metadata of those IUs is safe/were signed.
- //// https://bugs.eclipse.org/bugs/show_bug.cgi?id=576705#c4
- // profile.query(QueryUtil.ALL_UNITS, new NullProgressMonitor()).forEach(
- // iu ->
- // store.addAll(PGPSignatureVerifier.readPublicKeys(iu.getProperty(TRUSTED_KEY_STORE_PROPERTY))));
- trustStore.all().forEach(PGPSignatureVerifier.KNOWN_KEYS::addKey);
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ PGPPublicKeyStore
+ .readPublicKeys(profileScope.getNode(EngineActivator.ID).get(TRUSTED_KEY_STORE_PROPERTY, null))
+ .stream().map(keyService::addKey).forEach(trustStore::addKey);
+ }
return trustStore;
}
public IStatus persistTrustedKeys(PGPPublicKeyStore trustStore) {
- IProfile profile = agent.getService(IProfileRegistry.class).getProfile(IProfileRegistry.SELF);
- ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class), profile.getProfileId());
- IEclipsePreferences node = profileScope.getNode(EngineActivator.ID);
- try {
- node.put(TRUSTED_KEY_STORE_PROPERTY, trustStore.toArmoredString());
- node.flush();
- return Status.OK_STATUS;
- } catch (IOException | BackingStoreException ex) {
- return new Status(IStatus.ERROR, EngineActivator.ID, ex.getMessage(), ex);
+ if (profile != null) {
+ ProfileScope profileScope = new ProfileScope(agent.getService(IAgentLocation.class),
+ profile.getProfileId());
+ IEclipsePreferences node = profileScope.getNode(EngineActivator.ID);
+ try {
+ node.put(TRUSTED_KEY_STORE_PROPERTY, trustStore.toArmoredString());
+ node.flush();
+ } catch (IOException | BackingStoreException ex) {
+ return new Status(IStatus.ERROR, EngineActivator.ID, ex.getMessage(), ex);
+ }
}
+ return Status.OK_STATUS;
}
}
-
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CheckTrust.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CheckTrust.java
index e885ad1f6..5b81e7ba3 100644
--- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CheckTrust.java
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CheckTrust.java
@@ -60,6 +60,7 @@ public class CheckTrust extends InstallableUnitPhase {
// Instantiate a check trust manager
CertificateChecker certificateChecker = new CertificateChecker(agent);
certificateChecker.add(artifactRequests);
+ certificateChecker.setProfile(profile);
return certificateChecker.start();
}
diff --git a/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
index 76a2520ae..290732d27 100644
--- a/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.extensionlocation;singleton:=true
-Bundle-Version: 1.4.0.qualifier
+Bundle-Version: 1.4.100.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.extensionlocation.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
-Export-Package: org.eclipse.equinox.internal.p2.extensionlocation;x-friends:="org.eclipse.equinox.p2.reconciler.dropins,org.eclipse.equinox.p2.ui.importexport"
+Export-Package: org.eclipse.equinox.internal.p2.extensionlocation;x-friends:="org.eclipse.equinox.p2.reconciler.dropins,org.eclipse.equinox.p2.ui,org.eclipse.equinox.p2.ui.importexport"
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)",
org.eclipse.equinox.p2.metadata
Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml b/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
index 474ce108b..2cadcc0b2 100644
--- a/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.extensionlocation</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.4.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.garbagecollector/pom.xml b/bundles/org.eclipse.equinox.p2.garbagecollector/pom.xml
index 989378df4..ee0e4278b 100644
--- a/bundles/org.eclipse.equinox.p2.garbagecollector/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.garbagecollector/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.installer/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.installer/META-INF/MANIFEST.MF
index d1be7dc49..63f6c3707 100644
--- a/bundles/org.eclipse.equinox.p2.installer/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.installer/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-SymbolicName: org.eclipse.equinox.p2.installer;singleton:=true
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
-Bundle-Version: 1.3.200.qualifier
+Bundle-Version: 1.3.300.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.installer.InstallerActivator
Bundle-ActivationPolicy: lazy
Require-Bundle: org.eclipse.osgi;bundle-version="[3.7.0,4.0.0)",
diff --git a/bundles/org.eclipse.equinox.p2.installer/installer.product b/bundles/org.eclipse.equinox.p2.installer/installer.product
index 6c2bd7198..83b557986 100644
--- a/bundles/org.eclipse.equinox.p2.installer/installer.product
+++ b/bundles/org.eclipse.equinox.p2.installer/installer.product
@@ -40,7 +40,7 @@
<plugin id="org.eclipse.core.expressions"/>
<plugin id="org.eclipse.core.jobs"/>
<plugin id="org.eclipse.core.net"/>
- <plugin id="org.eclipse.core.net.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.net.linux" fragment="true"/>
<plugin id="org.eclipse.core.runtime"/>
<plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
<plugin id="org.eclipse.ecf"/>
@@ -76,7 +76,7 @@
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.security.macosx" fragment="true"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
<plugin id="org.eclipse.equinox.simpleconfigurator.manipulator"/>
diff --git a/bundles/org.eclipse.equinox.p2.installer/installer.properties b/bundles/org.eclipse.equinox.p2.installer/installer.properties
index c28de9f82..ef00a4347 100644
--- a/bundles/org.eclipse.equinox.p2.installer/installer.properties
+++ b/bundles/org.eclipse.equinox.p2.installer/installer.properties
@@ -11,8 +11,8 @@
# Contributors:
# IBM Corporation - initial API and implementation
###############################################################################
-eclipse.p2.metadata=http://download.eclipse.org/eclipse/updates/3.5
-eclipse.p2.artifacts=http://download.eclipse.org/eclipse/updates/3.5
+eclipse.p2.metadata=https://download.eclipse.org/eclipse/updates/3.5
+eclipse.p2.artifacts=https://download.eclipse.org/eclipse/updates/3.5
eclipse.p2.flavor=tooling
eclipse.p2.profileName=Eclipse SDK
eclipse.p2.launcherName=eclipse
diff --git a/bundles/org.eclipse.equinox.p2.installer/pom.xml b/bundles/org.eclipse.equinox.p2.installer/pom.xml
index 2e06dd169..27ae673d5 100644
--- a/bundles/org.eclipse.equinox.p2.installer/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.installer/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.installer</artifactId>
- <version>1.3.200-SNAPSHOT</version>
+ <version>1.3.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.jarprocessor/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.jarprocessor/META-INF/MANIFEST.MF
index 2257e8ff3..283bf2bb4 100644
--- a/bundles/org.eclipse.equinox.p2.jarprocessor/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.jarprocessor/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-SymbolicName: org.eclipse.equinox.p2.jarprocessor;singleton:=true
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
-Bundle-Version: 1.2.100.qualifier
+Bundle-Version: 1.2.300.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-11
Main-Class: org.eclipse.equinox.internal.p2.jarprocessor.Main
Export-Package: org.eclipse.equinox.internal.p2.jarprocessor;x-friends:="org.eclipse.equinox.p2.artifact.repository,org.eclipse.pde.build",
diff --git a/bundles/org.eclipse.equinox.p2.jarprocessor/forceQualifierUpdate.txt b/bundles/org.eclipse.equinox.p2.jarprocessor/forceQualifierUpdate.txt
index 88375d023..1519a409d 100644
--- a/bundles/org.eclipse.equinox.p2.jarprocessor/forceQualifierUpdate.txt
+++ b/bundles/org.eclipse.equinox.p2.jarprocessor/forceQualifierUpdate.txt
@@ -6,4 +6,6 @@ comparator errors on new infra
Bug 566668 - Comparator errors in I20200904-0210
Bug 571555 - Comparator errors in I20210226-1800
Bug 571731 - Comparator errors in I20210305-0820
-Bug 575841 - Comparator errors in I20210906-1000 \ No newline at end of file
+Bug 575841 - Comparator errors in I20210906-1000
+Bug 578351 - Lambda generation order is unstable in ecj
+Bug 579126 - 4.24 I-Build: I20220307-0340 - Comparator Errors Found \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.jarprocessor/pom.xml b/bundles/org.eclipse.equinox.p2.jarprocessor/pom.xml
index caf173f63..7064c875d 100644
--- a/bundles/org.eclipse.equinox.p2.jarprocessor/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.jarprocessor/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.jarprocessor</artifactId>
- <version>1.2.100-SNAPSHOT</version>
+ <version>1.2.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/pom.xml b/bundles/org.eclipse.equinox.p2.metadata.repository/pom.xml
index afd2687b0..4058eb8f1 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/pom.xml
@@ -14,7 +14,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.metadata/pom.xml b/bundles/org.eclipse.equinox.p2.metadata/pom.xml
index eb0923e93..bf0807827 100644
--- a/bundles/org.eclipse.equinox.p2.metadata/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.metadata/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.operations/pom.xml b/bundles/org.eclipse.equinox.p2.operations/pom.xml
index 621d99d8a..ed63d9000 100644
--- a/bundles/org.eclipse.equinox.p2.operations/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.operations/pom.xml
@@ -14,7 +14,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.publisher.eclipse/.settings/org.eclipse.jdt.ui.prefs
index 708515333..d3d075e63 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/.settings/org.eclipse.jdt.ui.prefs
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/.settings/org.eclipse.jdt.ui.prefs
@@ -23,7 +23,7 @@ sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.format_source_code_changes_only=true
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.publisher.eclipse/META-INF/MANIFEST.MF
index 049dcc704..0a8d62359 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.equinox.p2.publisher.eclipse;singleton:=true
-Bundle-Version: 1.4.1.qualifier
+Bundle-Version: 1.4.2.qualifier
Bundle-Activator: org.eclipse.pde.internal.publishing.Activator
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/pom.xml b/bundles/org.eclipse.equinox.p2.publisher.eclipse/pom.xml
index 9068e97a1..cf46b80e9 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/pom.xml
@@ -4,12 +4,12 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.publisher.eclipse</artifactId>
- <version>1.4.1-SNAPSHOT</version>
+ <version>1.4.2-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
index cbc41b8c6..d11aaa39d 100644
--- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
+++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/p2/publisher/eclipse/FeaturesAction.java
@@ -614,7 +614,14 @@ public class FeaturesAction extends AbstractPublisherAction {
// artifact per feature IU.
Collection<IArtifactKey> artifacts = featureIU.getArtifacts();
for (IArtifactKey artifactKey : artifacts) {
- File file = new File(feature.getLocation());
+ String location = feature.getLocation();
+ if (location == null) {
+ if (PublisherHelper.isArtifactPublish(publisherInfo)) {
+ throw new IllegalArgumentException(NLS.bind(Messages.exception_sourcePath, feature.getId()));
+ }
+ continue;
+ }
+ File file = new File(location);
ArtifactDescriptor ad = (ArtifactDescriptor) PublisherHelper.createArtifactDescriptor(info, artifactKey, file);
processArtifactPropertiesAdvice(featureIU, ad, publisherInfo);
ad.setProperty(IArtifactDescriptor.DOWNLOAD_CONTENTTYPE, IArtifactDescriptor.TYPE_ZIP);
diff --git a/bundles/org.eclipse.equinox.p2.publisher/.settings/.api_filters b/bundles/org.eclipse.equinox.p2.publisher/.settings/.api_filters
new file mode 100644
index 000000000..5fbae6834
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.publisher/.settings/.api_filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.equinox.p2.publisher" version="2">
+ <resource path="META-INF/MANIFEST.MF">
+ <filter id="926941240">
+ <message_arguments>
+ <message_argument value="1.7.0"/>
+ <message_argument value="1.6.200"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
index 2568eeee2..693d9e66b 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.publisher/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.equinox.p2.publisher;singleton:=true
-Bundle-Version: 1.6.200.qualifier
+Bundle-Version: 1.7.0.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.publisher.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.publisher/pom.xml b/bundles/org.eclipse.equinox.p2.publisher/pom.xml
index aa9c72cd8..b16ba1bd1 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.publisher/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.publisher</artifactId>
- <version>1.6.200-SNAPSHOT</version>
+ <version>1.7.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
index 497a8a261..5f1dc9d42 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/AbstractPublisherAction.java
@@ -504,7 +504,7 @@ public abstract class AbstractPublisherAction implements IPublisherAction {
// if all we are doing is indexing things then add the descriptor and get on
// with it
- if ((publisherInfo.getArtifactOptions() & IPublisherInfo.A_PUBLISH) == 0) {
+ if (!PublisherHelper.isArtifactPublish(publisherInfo)) {
destination.addDescriptor(descriptor, new NullProgressMonitor());
return;
}
@@ -556,7 +556,7 @@ public abstract class AbstractPublisherAction implements IPublisherAction {
return;
// if all we are doing is indexing things then add the descriptor and get on
// with it
- if ((publisherInfo.getArtifactOptions() & IPublisherInfo.A_PUBLISH) == 0) {
+ if (!PublisherHelper.isArtifactPublish(publisherInfo)) {
destination.addDescriptor(descriptor, new NullProgressMonitor());
return;
}
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/IPublisherInfo.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/IPublisherInfo.java
index 0e88610aa..33796f507 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/IPublisherInfo.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/IPublisherInfo.java
@@ -8,8 +8,8 @@
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
+ *
+ * Contributors:
* Code 9 - initial API and implementation
* IBM - ongoing development
******************************************************************************/
@@ -40,7 +40,7 @@ public interface IPublisherInfo {
public static final int A_OVERWRITE = 4;
/**
- * A bitwise flag indicating that MD5 hash should not be generated when
+ * A bitwise flag indicating that MD5 hash should not be generated when
* publishing an artifact. When this flag is not specified the MD5 hash will
* be generated by default.
*/
@@ -61,9 +61,9 @@ public interface IPublisherInfo {
public IMetadataRepository getMetadataRepository();
/**
- * Returns whether or not artifacts themselves should be published.
- * @return <code>true</code> if artifacts should be published.
- * <code>false</code> otherwise.
+ * Returns a bitflag that controls the publish operation, what is a bitwhise OR
+ * of {@link #A_INDEX},{@value #A_PUBLISH}, {@link #A_NO_MD5},
+ * {@link #A_OVERWRITE} or <code>0</code> if no flags are set.
*/
public int getArtifactOptions();
@@ -80,7 +80,7 @@ public interface IPublisherInfo {
public <T extends IPublisherAdvice> Collection<T> getAdvice(String configSpec, boolean includeDefault, String id, Version version, Class<T> type);
/**
- * Add the given advice to the set of publishing advices.
+ * Add the given advice to the set of publishing advices.
* @param advice the advice to retain
*/
public void addAdvice(IPublisherAdvice advice);
@@ -95,19 +95,19 @@ public interface IPublisherInfo {
public String[] getConfigurations();
/**
- * Returns the artifact repository given to the publisher as context for
- * the publisher actions. May be <code>null</code>. Note that multiple
+ * Returns the artifact repository given to the publisher as context for
+ * the publisher actions. May be <code>null</code>. Note that multiple
* repositories may be represented as one composite repository.
- *
+ *
* @return the context artifact repository or <code>null</code> if none.
*/
public IArtifactRepository getContextArtifactRepository();
/**
- * Returns the metadata repository given to the publisher as context for
- * the publisher actions. May be <code>null</code>. Note that multiple
+ * Returns the metadata repository given to the publisher as context for
+ * the publisher actions. May be <code>null</code>. Note that multiple
* repositories may be represented as one composite repository.
- *
+ *
* @return the context metadata repository or <code>null</code> if none.
*/
public IMetadataRepository getContextMetadataRepository();
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
index d62b50b90..f074794b7 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/spi/p2/publisher/PublisherHelper.java
@@ -112,7 +112,7 @@ public class PublisherHelper {
descriptor.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, Long.toString(pathOnDisk.length()));
descriptor.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(pathOnDisk.length()));
- boolean generateChecksums = info == null || (info.getArtifactOptions() & IPublisherInfo.A_NO_MD5) == 0;
+ boolean generateChecksums = info == null || isArtifactGenerateChecksums(info);
if (generateChecksums) {
calculateChecksums(pathOnDisk, descriptor);
}
@@ -252,4 +252,49 @@ public class PublisherHelper {
return new VersionRange(min, includeMin, max, includeMax);
}
+
+ /**
+ *
+ * @return <code>true</code> if md5 sums should be generated <code>false</code>
+ * otherwise
+ * @since 1.7.0
+ */
+ public static boolean isArtifactGenerateChecksums(IPublisherInfo publisherInfo) {
+ if ((publisherInfo.getArtifactOptions() & IPublisherInfo.A_NO_MD5) != 0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @return <code>true</code> if existing artifacts should be overwritten
+ * <code>false</code> otherwise
+ * @since 1.7.0
+ */
+ public static boolean isArtifactOverwrite(IPublisherInfo publisherInfo) {
+ return (publisherInfo.getArtifactOptions() & IPublisherInfo.A_OVERWRITE) != 0;
+ }
+
+ /**
+ *
+ * @return <code>true</code> if artifacts should published <code>false</code>
+ * otherwise
+ * @since 1.7.0
+ */
+ public static boolean isArtifactPublish(IPublisherInfo publisherInfo) {
+ int artifactOptions = publisherInfo.getArtifactOptions();
+ return artifactOptions == 0 || (artifactOptions & IPublisherInfo.A_PUBLISH) != 0;
+ }
+
+ /**
+ *
+ * @return <code>true</code> if the artifact index should be updated
+ * <code>false</code> otherwise
+ * @since 1.7.0
+ */
+ public static boolean isArtifactIndex(IPublisherInfo publisherInfo) {
+ int artifactOptions = publisherInfo.getArtifactOptions();
+ return artifactOptions == 0 || (artifactOptions & IPublisherInfo.A_INDEX) != 0;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/Bootstrap.product b/bundles/org.eclipse.equinox.p2.reconciler.dropins/Bootstrap.product
index 833e2413c..f48bab7f0 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/Bootstrap.product
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/Bootstrap.product
@@ -30,7 +30,7 @@
<plugin id="org.eclipse.core.expressions"/>
<plugin id="org.eclipse.core.jobs"/>
<plugin id="org.eclipse.core.net"/>
- <plugin id="org.eclipse.core.net.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.net.linux" fragment="true"/>
<plugin id="org.eclipse.core.runtime"/>
<plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/>
<plugin id="org.eclipse.ecf"/>
@@ -64,7 +64,7 @@
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
<plugin id="org.eclipse.equinox.simpleconfigurator.manipulator"/>
<plugin id="org.eclipse.equinox.util"/>
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.reconciler.dropins/META-INF/MANIFEST.MF
index 5131cf0e6..104fdb8d6 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.reconciler.dropins;singleton:=true
-Bundle-Version: 1.4.0.qualifier
+Bundle-Version: 1.4.100.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.reconciler.dropins.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/pom.xml b/bundles/org.eclipse.equinox.p2.reconciler.dropins/pom.xml
index bc21ce7f7..d2362a506 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.reconciler.dropins</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.4.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.repository.tools/pom.xml b/bundles/org.eclipse.equinox.p2.repository.tools/pom.xml
index 2eb240c5e..379a11b8a 100644
--- a/bundles/org.eclipse.equinox.p2.repository.tools/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.repository.tools/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.repository/.options b/bundles/org.eclipse.equinox.p2.repository/.options
new file mode 100644
index 000000000..c2d3dc538
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/.options
@@ -0,0 +1,3 @@
+org.eclipse.equinox.p2.repository/credentials/debug = false
+org.eclipse.equinox.p2.repository/transport/debug = false
+org.eclipse.equinox.p2.repository/keyservice/debug = false
diff --git a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
index ce71e8628..0f0800872 100644
--- a/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.repository/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.repository;singleton:=true
-Bundle-Version: 2.5.300.qualifier
+Bundle-Version: 2.6.0.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.repository.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -42,6 +42,16 @@ Require-Bundle: org.eclipse.equinox.common,
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-ActivationPolicy: lazy
Import-Package: javax.crypto,
+ org.bouncycastle;version="1.69.0",
+ org.bouncycastle.bcpg;version="1.69.0",
+ org.bouncycastle.gpg.keybox;version="1.69.0",
+ org.bouncycastle.gpg.keybox.jcajce;version="1.69.0",
+ org.bouncycastle.openpgp;version="1.69.0",
+ org.bouncycastle.openpgp.jcajce;version="1.69.0",
+ org.bouncycastle.openpgp.operator;version="1.69.0",
+ org.bouncycastle.openpgp.operator.bc;version="1.69.0",
+ org.bouncycastle.openpgp.operator.jcajce;version="1.69.0",
+ org.bouncycastle.util.encoders;version="1.69.0",
org.eclipse.core.runtime.jobs,
org.eclipse.core.runtime.preferences;version="3.2.0",
org.eclipse.equinox.internal.p2.core,
@@ -61,5 +71,5 @@ Import-Package: javax.crypto,
org.osgi.service.packageadmin;version="1.2.0",
org.osgi.service.prefs;version="1.0.0",
org.osgi.util.tracker;version="1.4.0"
-Service-Component: OSGI-INF/cacheManager.xml
+Service-Component: OSGI-INF/cacheManager.xml, OSGI-INF/pgpPublicKeyService.xml
Automatic-Module-Name: org.eclipse.equinox.p2.repository
diff --git a/bundles/org.eclipse.equinox.p2.repository/OSGI-INF/pgpPublicKeyService.xml b/bundles/org.eclipse.equinox.p2.repository/OSGI-INF/pgpPublicKeyService.xml
new file mode 100644
index 000000000..e303cd93e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/OSGI-INF/pgpPublicKeyService.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.equinox.p2.repository.spi.pgpPublicKeyService">
+ <implementation class="org.eclipse.equinox.internal.p2.repository.PGPKeyServiceComponent"/>
+ <service>
+ <provide interface="org.eclipse.equinox.p2.core.spi.IAgentServiceFactory"/>
+ </service>
+ <property name="p2.agent.servicename" type="String" value="org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService"/>
+</scr:component>
diff --git a/bundles/org.eclipse.equinox.p2.repository/build.properties b/bundles/org.eclipse.equinox.p2.repository/build.properties
index f3b28f666..89e396d06 100644
--- a/bundles/org.eclipse.equinox.p2.repository/build.properties
+++ b/bundles/org.eclipse.equinox.p2.repository/build.properties
@@ -17,6 +17,7 @@ bin.includes = META-INF/,\
about.html,\
plugin.properties,\
OSGI-INF/cacheManager.xml,\
- OSGI-INF/
+ OSGI-INF/,\
+ .options
src.includes = about.html
source.. = src/
diff --git a/bundles/org.eclipse.equinox.p2.repository/pom.xml b/bundles/org.eclipse.equinox.p2.repository/pom.xml
index f80aa9c5c..7b16ab7c0 100644
--- a/bundles/org.eclipse.equinox.p2.repository/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.repository/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.repository</artifactId>
- <version>2.5.300-SNAPSHOT</version>
+ <version>2.6.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/PGPKeyServiceComponent.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/PGPKeyServiceComponent.java
new file mode 100644
index 000000000..dfb73bc90
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/PGPKeyServiceComponent.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.repository;
+
+import org.eclipse.equinox.internal.provisional.p2.repository.DefaultPGPPublicKeyService;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.spi.IAgentServiceFactory;
+
+public class PGPKeyServiceComponent implements IAgentServiceFactory {
+ @Override
+ public Object createService(IProvisioningAgent agent) {
+ return new DefaultPGPPublicKeyService(agent);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/DebugHelper.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/DebugHelper.java
index bb422888a..e4955cefe 100644
--- a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/DebugHelper.java
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/p2/repository/helpers/DebugHelper.java
@@ -25,15 +25,18 @@ public class DebugHelper {
public static final boolean DEBUG_REPOSITORY_CREDENTIALS;
public static final boolean DEBUG_REPOSITORY_TRANSPORT;
+ public static final boolean DEBUG_KEY_SERVICE;
static {
DebugOptions options = ServiceHelper.getService(Activator.getContext(), DebugOptions.class);
if (options != null) {
DEBUG_REPOSITORY_CREDENTIALS = options.getBooleanOption(Activator.ID + "/credentials/debug", false); //$NON-NLS-1$
DEBUG_REPOSITORY_TRANSPORT = options.getBooleanOption(Activator.ID + "/transport/debug", false); //$NON-NLS-1$
+ DEBUG_KEY_SERVICE = options.getBooleanOption(Activator.ID + "/keyservice/debug", false); //$NON-NLS-1$
} else {
DEBUG_REPOSITORY_CREDENTIALS = false;
DEBUG_REPOSITORY_TRANSPORT = false;
+ DEBUG_KEY_SERVICE = false;
}
}
@@ -50,7 +53,7 @@ public class DebugHelper {
System.out.println(buffer.toString());
}
- public static void debug(String name, String message, Object[] keyValueArray) {
+ public static void debug(String name, String message, Object... keyValueArray) {
if (keyValueArray == null || keyValueArray.length == 0)
debug(name, message);
else {
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/provisional/p2/repository/DefaultPGPPublicKeyService.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/provisional/p2/repository/DefaultPGPPublicKeyService.java
new file mode 100644
index 000000000..3aa501986
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/internal/provisional/p2/repository/DefaultPGPPublicKeyService.java
@@ -0,0 +1,869 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.internal.provisional.p2.repository;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileTime;
+import java.util.*;
+import java.util.function.*;
+import org.bouncycastle.bcpg.ArmoredInputStream;
+import org.bouncycastle.bcpg.ArmoredOutputStream;
+import org.bouncycastle.gpg.keybox.*;
+import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder;
+import org.bouncycastle.openpgp.*;
+import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
+import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
+import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.repository.Transport;
+import org.eclipse.equinox.internal.p2.repository.helpers.DebugHelper;
+import org.eclipse.equinox.p2.core.IAgentLocation;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+
+/**
+ * @since 2.6
+ */
+public class DefaultPGPPublicKeyService extends PGPPublicKeyService {
+
+ /**
+ * Enable debug tracing either via debug options or via a system property.
+ */
+ private static final boolean DEBUG_KEY_SERVICE = DebugHelper.DEBUG_KEY_SERVICE
+ || Boolean.TRUE.toString().equalsIgnoreCase(System.getProperty("p2.keyserver.debug")); //$NON-NLS-1$
+
+ /**
+ * The system property used to initialized the {@link #keyServer}.
+ */
+ private static final String KEY_SERVERS_PROPERTY = "p2.keyservers"; //$NON-NLS-1$
+
+ /**
+ * The system property used to determine where to look for the GPG pubring.
+ *
+ * @see #getGPPDirectory()
+ */
+ private static final String GPG_HOME_PROPERTY = "p2.gpg.home"; //$NON-NLS-1$
+
+ /**
+ * The system property used to determine whether to enable GPG pubring lookup.
+ *
+ * @see #gpg
+ * @see #setGPG(boolean)
+ */
+ private static final String GPG_PROPERTY = "p2.gpg"; //$NON-NLS-1$
+
+ /**
+ * The number of elapsed milliseconds after which keys cached from a key server
+ * are considered stale such that they will be re-fetched if possible.
+ */
+ private static final long STALE_AFTER_MILLIS = Long.getLong("p2.keyserver.cache.stale", 24) * 1000 * 60 * 60; //$NON-NLS-1$
+
+ /**
+ * Reuse p2's transport layer for fetching keys from the key server.
+ */
+ private final Transport transport;
+
+ /**
+ * Keys {@link #addKey(PGPPublicKey) added} to this key service are cached via
+ * this map.
+ */
+ private final Map<Long, LocalKeyCache> localKeys = new LinkedHashMap<>();
+
+ /**
+ * A folder with locally cached keys, indexed on {@link PGPPublicKey#getKeyID()
+ * key ID}.
+ */
+ private final Path keyCache;
+
+ /**
+ * The current key servers.
+ */
+ private final Map<String, PGPKeyServer> keyServers = new LinkedHashMap<>();
+
+ /**
+ * Whether to load from GPG's pubring.
+ */
+ private boolean gpg;
+
+ /**
+ * Creates an instance associated with the given agent.
+ *
+ * @param agent the agent for which a key service is provided.
+ */
+ public DefaultPGPPublicKeyService(IProvisioningAgent agent) {
+ IAgentLocation agentLocation = agent.getService(IAgentLocation.class);
+ URI dataArea = agentLocation.getDataArea(org.eclipse.equinox.internal.p2.repository.Activator.ID);
+ keyCache = Paths.get(dataArea).resolve("pgp"); //$NON-NLS-1$
+ try {
+ Files.createDirectories(keyCache);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ if (DEBUG_KEY_SERVICE) {
+ DebugHelper.debug("KeyServer", "Cache", "location", keyCache); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ String keyServersProperty = System.getProperty(KEY_SERVERS_PROPERTY, ""); //$NON-NLS-1$
+ if (!keyServersProperty.isBlank()) {
+ Set<String> keyServersSet = new LinkedHashSet<>();
+ for (String keyServer : keyServersProperty.split("[,; \t]+")) { //$NON-NLS-1$
+ if (!keyServer.isEmpty()) {
+ keyServersSet.add(keyServer);
+ }
+ }
+
+ setKeyServers(keyServersSet);
+ }
+
+ setGPG(Boolean.TRUE.toString().equalsIgnoreCase(System.getProperty(GPG_PROPERTY, Boolean.TRUE.toString()))
+ || !System.getProperty(GPG_HOME_PROPERTY, "").isBlank()); //$NON-NLS-1$
+
+ transport = agent.getService(Transport.class);
+ }
+
+ public Set<String> getKeyServers() {
+ return Collections.unmodifiableSet(keyServers.keySet());
+ }
+
+ public void setKeyServers(Set<String> keyServers) {
+ Map<String, PGPKeyServer> newKeyServers = new LinkedHashMap<>();
+ for (String keyServer : keyServers) {
+ PGPKeyServer pgpKeyServer = this.keyServers.get(keyServer);
+ if (pgpKeyServer == null) {
+ pgpKeyServer = new PGPKeyServer(keyServer, this.keyCache) {
+ @Override
+ protected boolean isStale(Path path) {
+ return DefaultPGPPublicKeyService.this.isStale(path);
+ }
+
+ @Override
+ protected IStatus download(URI uri, OutputStream receiver, IProgressMonitor monitor) {
+ return DefaultPGPPublicKeyService.this.download(uri, receiver, monitor);
+ }
+
+ @Override
+ protected void log(Throwable throwable) {
+ DefaultPGPPublicKeyService.this.log(throwable);
+ }
+ };
+ }
+ newKeyServers.put(keyServer, pgpKeyServer);
+ }
+
+ this.keyServers.clear();
+ this.keyServers.putAll(newKeyServers);
+ }
+
+ @Override
+ public PGPPublicKey getKey(String fingerprint) {
+ int length = fingerprint.length();
+ if (length >= 16) {
+ long keyID = Long.parseUnsignedLong(fingerprint.substring(length - 16, length), 16);
+ Collection<PGPPublicKey> keys = getKeys(keyID);
+ for (PGPPublicKey key : keys) {
+ if (toHexFingerprint(key).equalsIgnoreCase(fingerprint)) {
+ return key;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<PGPPublicKey> getKeys(long keyID) {
+ List<PGPPublicKey> keys = new ArrayList<>();
+ for (PGPKeyServer keyServer : keyServers.values()) {
+ keys.addAll(keyServer.getKeys(keyID));
+ }
+
+ keys.addAll(getLocalKeyCache(keyID).get());
+
+ keys.addAll(getDefaultKeys(keyID));
+
+ return reconcileKeys(keys);
+ }
+
+ public boolean isGGP() {
+ return gpg;
+ }
+
+ public void setGPG(boolean gpg) {
+ this.gpg = gpg;
+ }
+
+ protected List<PGPPublicKey> getDefaultKeys(long keyID) {
+ return gpg ? getGPGPubringKeys(keyID) : Collections.emptyList();
+ }
+
+ protected List<PGPPublicKey> reconcileKeys(List<PGPPublicKey> keys) {
+ if (keys.size() <= 1) {
+ return new ArrayList<>(keys);
+ }
+
+ Map<ByteBuffer, PGPPublicKey> encodings = new LinkedHashMap<>();
+ Map<ByteBuffer, PGPPublicKey> fingerprints = new LinkedHashMap<>();
+ for (PGPPublicKey key : keys) {
+ try {
+ ByteBuffer encoding = ByteBuffer.wrap(key.getEncoded());
+ PGPPublicKey existingKey = encodings.put(encoding, key);
+ if (existingKey == null) {
+ ByteBuffer fingerprint = ByteBuffer.wrap(key.getFingerprint());
+ PGPPublicKey otherKey = fingerprints.put(fingerprint, key);
+ if (otherKey != null) {
+ fingerprints.put(fingerprint, choose(otherKey, key));
+ }
+ }
+ } catch (IOException e) {
+ log(e);
+ }
+ }
+
+ return new ArrayList<>(fingerprints.values());
+ }
+
+ /**
+ * While {@link #reconcileKeys(List) reconciling}, when two keys have the same
+ * fingerprint, this method must be chosen in favor of the other to be retained
+ * in the result.
+ *
+ * @param key1 the first key from which to choose.
+ * @param key2 the second key from which to choose.
+ * @return the key with the newest or most complete details.
+ */
+ protected PGPPublicKey choose(PGPPublicKey key1, PGPPublicKey key2) {
+ // Favor the one with the newest information.
+ long signatureTime1 = getNewestSignature(key1);
+ long signatureTime2 = getNewestSignature(key2);
+ if (signatureTime1 > signatureTime2) {
+ return key1;
+ } else if (signatureTime1 < signatureTime2) {
+ return key2;
+ }
+
+ // Favor the one with the most information.
+ int signatureCount1 = getSignatureCount(key1);
+ int signatureCount2 = getSignatureCount(key2);
+ if (signatureCount1 > signatureCount2) {
+ return key1;
+ } else if (signatureCount1 < signatureCount2) {
+ return key2;
+ }
+
+ return key1;
+ }
+
+ protected static int getSignatureCount(PGPPublicKey key) {
+ int result = 0;
+ for (Iterator<PGPSignature> signatures = key.getSignatures(); signatures.hasNext(); signatures.next()) {
+ ++result;
+ }
+ for (Iterator<PGPSignature> signatures = key.getKeySignatures(); signatures.hasNext(); signatures.next()) {
+ ++result;
+ }
+ return result;
+ }
+
+ protected static long getNewestSignature(PGPPublicKey key) {
+ long result = 0;
+ for (Iterator<PGPSignature> signatures = key.getSignatures(); signatures.hasNext();) {
+ PGPSignature signature = signatures.next();
+ long time = signature.getCreationTime().getTime();
+ result = Math.max(result, time);
+ }
+ for (Iterator<PGPSignature> signatures = key.getKeySignatures(); signatures.hasNext();) {
+ PGPSignature signature = signatures.next();
+ long time = signature.getCreationTime().getTime();
+ result = Math.max(result, time);
+ }
+
+ return result;
+ }
+
+ @Override
+ public PGPPublicKey addKey(PGPPublicKey key) {
+ long keyID = key.getKeyID();
+ LocalKeyCache localKeyCache = getLocalKeyCache(keyID);
+ localKeyCache.add(key);
+
+ Collection<PGPPublicKey> keys = getKeys(keyID);
+ byte[] fingerprint = key.getFingerprint();
+ for (PGPPublicKey otherKey : keys) {
+ if (Arrays.equals(otherKey.getFingerprint(), fingerprint)) {
+ return otherKey;
+ }
+ }
+
+ // We should never get this far.
+ return key;
+ }
+
+ protected boolean isStale(Path path) {
+ try {
+ FileTime lastModifiedTime = Files.getLastModifiedTime(path);
+ long lastModified = lastModifiedTime.toMillis();
+ long currentTime = System.currentTimeMillis();
+ return currentTime - lastModified > STALE_AFTER_MILLIS;
+ } catch (IOException e) {
+ return true;
+ }
+ }
+
+ @Override
+ public Set<PGPPublicKey> getVerifiedCertifications(PGPPublicKey key) {
+ Set<PGPPublicKey> certifications = new LinkedHashSet<>();
+ LOOP: for (Iterator<PGPSignature> signatures = key.getSignatures(); signatures.hasNext();) {
+ PGPSignature signature = signatures.next();
+ long signingKeyID = signature.getKeyID();
+ for (PGPPublicKey signingKey : getKeys(signingKeyID)) {
+ switch (signature.getSignatureType()) {
+ case PGPSignature.SUBKEY_BINDING:
+ case PGPSignature.PRIMARYKEY_BINDING: {
+ try {
+ signature.init(new BcPGPContentVerifierBuilderProvider(), signingKey);
+ if (signature.verifyCertification(signingKey, key)
+ && isCreatedBeforeRevocation(signature, signingKey)) {
+ certifications.add(signingKey);
+ continue LOOP;
+ }
+ } catch (PGPException e) {
+ //$FALL-THROUGH$
+ }
+ break;
+ }
+ case PGPSignature.DEFAULT_CERTIFICATION:
+ case PGPSignature.NO_CERTIFICATION:
+ case PGPSignature.CASUAL_CERTIFICATION:
+ case PGPSignature.POSITIVE_CERTIFICATION: {
+ for (Iterator<String> userIDs = key.getUserIDs(); userIDs.hasNext();) {
+ String userID = userIDs.next();
+ try {
+ signature.init(new BcPGPContentVerifierBuilderProvider(), signingKey);
+ if (signature.verifyCertification(userID, key)
+ && isCreatedBeforeRevocation(signature, signingKey)) {
+ certifications.add(signingKey);
+ continue LOOP;
+ }
+ } catch (PGPException e) {
+ //$FALL-THROUGH$
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ return certifications;
+ }
+
+ @Override
+ public Date getVerifiedRevocationDate(PGPPublicKey key) {
+ for (Iterator<PGPSignature> signatures = key.getSignatures(); signatures.hasNext();) {
+ PGPSignature signature = signatures.next();
+ long signingKeyID = signature.getKeyID();
+ for (PGPPublicKey signingKey : getKeys(signingKeyID)) {
+ switch (signature.getSignatureType()) {
+ case PGPSignature.KEY_REVOCATION:
+ case PGPSignature.CERTIFICATION_REVOCATION: {
+ try {
+ signature.init(new BcPGPContentVerifierBuilderProvider(), signingKey);
+ if (signature.verifyCertification(key)) {
+ return signature.getCreationTime();
+ }
+ } catch (PGPException e) {
+ //$FALL-THROUGH$
+ }
+ break;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private LocalKeyCache getLocalKeyCache(long keyID) {
+ LocalKeyCache localKeyCache = localKeys.get(keyID);
+ if (localKeyCache == null) {
+ String hexKeyID = toHex(keyID);
+ Path cache = keyCache.resolve(hexKeyID + ".asc"); //$NON-NLS-1$
+ localKeyCache = new LocalKeyCache(cache) {
+ @Override
+ protected List<PGPPublicKey> reconcileKeys(List<PGPPublicKey> keys) {
+ return DefaultPGPPublicKeyService.this.reconcileKeys(keys);
+ }
+
+ @Override
+ protected void log(Throwable throwable) {
+ DefaultPGPPublicKeyService.this.log(throwable);
+ }
+ };
+ localKeys.put(keyID, localKeyCache);
+ }
+ return localKeyCache;
+ }
+
+ protected Collection<PGPPublicKey> fetchKeys(URI uri, Path cache) throws IOException {
+ try {
+ ByteArrayOutputStream reciever = new ByteArrayOutputStream();
+ IStatus download = download(uri, reciever, new NullProgressMonitor());
+ if (!download.isOK()) {
+ Throwable exception = download.getException();
+ if (exception != null) {
+ throw new IOException(download.getMessage(), exception);
+ }
+ throw new IOException(download.getMessage());
+ }
+ List<PGPPublicKey> result = new ArrayList<>();
+ byte[] bytes = reciever.toByteArray();
+ try (InputStream input = new ArmoredInputStream(new ByteArrayInputStream(bytes))) {
+ result.addAll(loadKeys(input));
+ }
+
+ try (OutputStream out = newAtomicOutputStream(cache)) {
+ out.write(bytes);
+ }
+
+ return result;
+ } catch (IOException ex) {
+ if (Files.isRegularFile(cache)) {
+ try (InputStream input = new ArmoredInputStream(new BufferedInputStream(Files.newInputStream(cache)))) {
+ return loadKeys(input);
+ } catch (IOException ex1) {
+ try {
+ // Assume the cache is corrupt so delete it.
+ Files.delete(cache);
+ } catch (IOException ex2) {
+ log(ex2);
+ }
+ // Rethrow original network failure exception
+ throw new IOException("Error while processing " + uri + " as well while processing the cache " //$NON-NLS-1$ //$NON-NLS-2$
+ + cache + ": " + ex1.getMessage(), ex); //$NON-NLS-1$
+ }
+ }
+ throw new IOException("Error while processing " + uri, ex); //$NON-NLS-1$
+ }
+ }
+
+ protected IStatus download(URI uri, OutputStream receiver, IProgressMonitor monitor) {
+ return transport.download(uri, receiver, monitor);
+ }
+
+ protected void log(Throwable throwable) {
+ if (DEBUG_KEY_SERVICE) {
+ LogHelper.log(new Status(IStatus.ERROR, org.eclipse.equinox.internal.p2.repository.Activator.ID,
+ throwable.getMessage(), throwable));
+ }
+ }
+
+ protected static OutputStream newAtomicOutputStream(Path cache) throws IOException {
+ Path temp = Files.createTempFile(cache.getParent(), "out", ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$
+ return new BufferedOutputStream(Files.newOutputStream(temp)) {
+ @Override
+ public void close() throws IOException {
+ super.close();
+ Files.move(temp, cache, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
+ }
+ };
+ }
+
+ protected static List<PGPPublicKey> loadKeys(InputStream input) throws IOException {
+ try {
+ List<PGPPublicKey> result = new ArrayList<>();
+ for (Object o : new JcaPGPObjectFactory(input)) {
+ if (o instanceof PGPPublicKeyRingCollection) {
+ collectKeys((PGPPublicKeyRingCollection) o, result::add);
+ } else if (o instanceof PGPPublicKeyRing) {
+ collectKeys((PGPPublicKeyRing) o, result::add);
+ } else if (o instanceof PGPPublicKey) {
+ result.add((PGPPublicKey) o);
+ }
+ }
+ return result;
+ } catch (RuntimeException ex) {
+ throw new IOException(ex);
+ }
+ }
+
+ private static void collectKeys(PGPPublicKeyRingCollection pgpPublicKeyRingCollection,
+ Consumer<PGPPublicKey> collector) {
+ pgpPublicKeyRingCollection.forEach(keyring -> collectKeys(keyring, collector));
+ }
+
+ private static void collectKeys(PGPPublicKeyRing pgpPublicKeyRing, Consumer<PGPPublicKey> collector) {
+ pgpPublicKeyRing.getPublicKeys().forEachRemaining(collector::accept);
+ }
+
+ private static abstract class LocalKeyCache {
+ private Path cache;
+ private FileTime lastModifiedTime;
+ private List<PGPPublicKey> keys;
+
+ public LocalKeyCache(Path cache) {
+ this.cache = cache;
+ }
+
+ protected abstract void log(Throwable throwable);
+
+ protected abstract List<PGPPublicKey> reconcileKeys(List<PGPPublicKey> keysToReconcile);
+
+ public List<PGPPublicKey> get() {
+ if (keys != null) {
+ try {
+ FileTime newLastModifiedTime = Files.getLastModifiedTime(cache);
+ if (lastModifiedTime == null || lastModifiedTime.compareTo(newLastModifiedTime) < 0) {
+ lastModifiedTime = newLastModifiedTime;
+ } else {
+ return keys;
+ }
+ } catch (Exception e) {
+ //$FALL-THROUGH$
+ }
+ }
+
+ if (!Files.isRegularFile(cache)) {
+ return List.of();
+ }
+
+ try (InputStream input = new ArmoredInputStream(new BufferedInputStream(Files.newInputStream(cache)))) {
+ keys = loadKeys(input);
+ return keys;
+ } catch (IOException ex) {
+ log(ex);
+ try {
+ // Assume the cache is corrupt so delete it.
+ Files.delete(cache);
+ } catch (IOException ex2) {
+ log(ex2);
+ }
+ return List.of();
+ }
+ }
+
+ public void add(PGPPublicKey key) {
+ List<PGPPublicKey> oldKeys = get();
+ List<PGPPublicKey> newKeys = new ArrayList<>(oldKeys);
+ newKeys.add(key);
+ newKeys = reconcileKeys(newKeys);
+ if (!oldKeys.equals(newKeys)) {
+ try (OutputStream underlyingStream = newAtomicOutputStream(cache);
+ OutputStream output = new ArmoredOutputStream(underlyingStream)) {
+ for (PGPPublicKey newKey : newKeys) {
+ newKey.encode(output);
+ }
+ } catch (IOException e) {
+ log(e);
+ return;
+ }
+ keys = newKeys;
+ }
+ }
+ }
+
+ private static abstract class PGPKeyServer {
+ private final Map<Long, List<PGPPublicKey>> keyIDMap = new LinkedHashMap<>();
+
+ private final String keyServer;
+
+ private final Path keyCache;
+
+ public PGPKeyServer(String keyServer, Path baseCache) {
+ this.keyServer = keyServer;
+ keyCache = baseCache.resolve(keyServer.replace(':', '_'));
+ if (!Files.isDirectory(this.keyCache)) {
+ try {
+ Files.createDirectory(keyCache);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ protected abstract boolean isStale(Path path);
+
+ protected abstract IStatus download(URI uri, OutputStream receiver, IProgressMonitor monitor);
+
+ protected abstract void log(Throwable throwable);
+
+ public List<PGPPublicKey> getKeys(long keyID) {
+ List<PGPPublicKey> keys = keyIDMap.get(keyID);
+ String hexKeyID = toHex(keyID);
+ Path cache = keyCache.resolve(hexKeyID + ".asc"); //$NON-NLS-1$
+ boolean needsRemoteFetch = !Files.isRegularFile(cache) || isStale(cache);
+ if (keys == null || needsRemoteFetch) {
+ try {
+ Iterable<PGPPublicKey> fetchedKeys;
+ if (needsRemoteFetch) {
+ String link = "https://" + keyServer + "/pks/lookup?op=get&search=0x" + hexKeyID; //$NON-NLS-1$ //$NON-NLS-2$
+ if (DEBUG_KEY_SERVICE) {
+ DebugHelper.debug("KeyServer", "Searching", "uri", link); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ URI uri = new URI(link);
+ fetchedKeys = fetchKeys(uri, cache);
+ } else {
+ try (InputStream input = new ArmoredInputStream(
+ new BufferedInputStream(Files.newInputStream(cache)))) {
+ fetchedKeys = loadKeys(input);
+ }
+ }
+
+ List<PGPPublicKey> newKeys = new ArrayList<>();
+ for (PGPPublicKey fetchedKey : fetchedKeys) {
+ long fetchedKeyID = fetchedKey.getKeyID();
+ if (fetchedKeyID == keyID) {
+ newKeys.add(fetchedKey);
+ }
+ }
+
+ keyIDMap.put(keyID, newKeys);
+ keys = newKeys;
+ } catch (URISyntaxException | IOException e) {
+ log(e);
+ if (keys == null || keys.isEmpty()) {
+ List<PGPPublicKey> newKeys = List.of();
+ keyIDMap.put(keyID, newKeys);
+ keys = newKeys;
+ }
+ }
+ }
+
+ return Collections.unmodifiableList(keys);
+ }
+
+ protected Collection<PGPPublicKey> fetchKeys(URI uri, Path cache) throws IOException {
+ try {
+ ByteArrayOutputStream reciever = new ByteArrayOutputStream();
+ IStatus download = download(uri, reciever, new NullProgressMonitor());
+ if (!download.isOK()) {
+ // If the file is not found, save an empty file to prevent repeated attempts to
+ // download from this URI.
+ Throwable exception = download.getException();
+ if (exception instanceof FileNotFoundException) {
+ log(exception);
+ } else {
+ if (exception != null) {
+ throw new IOException(download.getMessage(), exception);
+ }
+ throw new IOException(download.getMessage());
+ }
+ }
+ List<PGPPublicKey> result;
+ byte[] bytes = reciever.toByteArray();
+ try {
+ try (InputStream input = new ArmoredInputStream(new ByteArrayInputStream(bytes))) {
+ result = loadKeys(input);
+ }
+ } catch (IOException ex) {
+ log(ex);
+ // If the bytes can't be processed cache an empty file to prevent repeated
+ // attempts.
+ bytes = new byte[0];
+ result = List.of();
+ }
+
+ try (OutputStream out = newAtomicOutputStream(cache)) {
+ out.write(bytes);
+ }
+
+ return result;
+ } catch (IOException ex) {
+ // If the key server fails, load the cache if it exists.
+ if (Files.isRegularFile(cache)) {
+ try (InputStream input = new ArmoredInputStream(
+ new BufferedInputStream(Files.newInputStream(cache)))) {
+ return loadKeys(input);
+ } catch (IOException ex1) {
+ try {
+ // Assume the cache is corrupt so delete it.
+ Files.delete(cache);
+ } catch (IOException ex2) {
+ log(ex2);
+ }
+ // Rethrow original network failure exception with additional details
+ throw new IOException("Error while processing " + uri + " as well while processing the cache " //$NON-NLS-1$ //$NON-NLS-2$
+ + cache + ": " + ex1.getMessage(), ex); //$NON-NLS-1$
+ }
+ }
+ throw new IOException("Error while processing " + uri, ex); //$NON-NLS-1$
+ }
+ }
+
+ }
+
+ private static List<PGPPublicKey> getGPGPubringKeys(long keyID) {
+ return GPGPubringCache.getKeys(keyID);
+ }
+
+ private static class GPGPubringCache {
+ private static final Supplier<PGPPublicKeyRingCollection> GPG_PUBRING = getGPGPubring();
+ private static volatile PGPPublicKeyRingCollection cachePubring;
+ private static volatile Map<Long, List<PGPPublicKey>> cache;
+
+ public static List<PGPPublicKey> getKeys(long keyID) {
+ PGPPublicKeyRingCollection pubring = GPG_PUBRING.get();
+ if (pubring != cachePubring) {
+ Map<Long, List<PGPPublicKey>> newCache = new LinkedHashMap<>();
+ for (Iterator<PGPPublicKeyRing> keyRings = pubring.getKeyRings(); keyRings.hasNext();) {
+ for (PGPPublicKey key : keyRings.next()) {
+ long keyID2 = key.getKeyID();
+ List<PGPPublicKey> keys = newCache.computeIfAbsent(keyID2, it -> new ArrayList<>());
+ keys.add(key);
+ }
+ }
+ cache = newCache;
+ cachePubring = pubring;
+ }
+
+ List<PGPPublicKey> result = cache.get(keyID);
+ return result == null ? List.of() : result;
+ }
+ }
+
+ private static abstract class GPGPubringSupplier implements Supplier<PGPPublicKeyRingCollection> {
+
+ private final Path pubring;
+
+ private PGPPublicKeyRingCollection keyRingCollection;
+
+ private FileTime lastModifiedTime;
+
+ public GPGPubringSupplier(Path pubring) {
+ this.pubring = pubring;
+ try {
+ keyRingCollection = new PGPPublicKeyRingCollection(Collections.emptyList());
+ } catch (IOException | PGPException e) {
+ // Cannot happen for an empty collection.
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public PGPPublicKeyRingCollection get() {
+ try {
+ FileTime newLastModifiedTime = Files.getLastModifiedTime(pubring);
+ if (lastModifiedTime == null || lastModifiedTime.compareTo(newLastModifiedTime) < 0) {
+ lastModifiedTime = newLastModifiedTime;
+ keyRingCollection = buildPubring();
+ }
+ } catch (Exception e) {
+ //$FALL-THROUGH$
+ }
+ return keyRingCollection;
+ }
+
+ protected abstract PGPPublicKeyRingCollection buildPubring() throws Exception;
+ }
+
+ private static Supplier<PGPPublicKeyRingCollection> getGPGPubring() {
+ Path gpgDirectory = getGPPDirectory();
+ Path pubringGpg = gpgDirectory.resolve("pubring.gpg"); //$NON-NLS-1$
+ Path pubringKbx = gpgDirectory.resolve("pubring.kbx"); //$NON-NLS-1$
+
+ if (Files.isRegularFile(pubringGpg)) {
+ return new GPGPubringSupplier(pubringGpg) {
+ @Override
+ protected PGPPublicKeyRingCollection buildPubring() throws Exception {
+ try (InputStream input = new BufferedInputStream(Files.newInputStream(pubringGpg))) {
+ PGPPublicKeyRingCollection keyRingCollection = new PGPPublicKeyRingCollection(input,
+ new JcaKeyFingerprintCalculator());
+ return keyRingCollection;
+ }
+ }
+ };
+ } else if (Files.isRegularFile(pubringKbx)) {
+ return new GPGPubringSupplier(pubringKbx) {
+ @Override
+ protected PGPPublicKeyRingCollection buildPubring() throws Exception {
+ try (InputStream input = new BufferedInputStream(Files.newInputStream(pubringKbx))) {
+ KeyBox keyBox = new JcaKeyBoxBuilder().build(input);
+ List<PGPPublicKeyRing> pgpPublicKeyRings = new ArrayList<>();
+ for (KeyBlob keyBlob : keyBox.getKeyBlobs()) {
+ switch (keyBlob.getType()) {
+ case OPEN_PGP_BLOB: {
+ PGPPublicKeyRing pgpPublicKeyRing = ((PublicKeyRingBlob) keyBlob).getPGPPublicKeyRing();
+ pgpPublicKeyRings.add(pgpPublicKeyRing);
+ }
+ default: {
+ //$FALL-THROUGH$
+ }
+ }
+ }
+ PGPPublicKeyRingCollection keyRingCollection = new PGPPublicKeyRingCollection(
+ pgpPublicKeyRings);
+ return keyRingCollection;
+ }
+ }
+ };
+ } else {
+ PGPPublicKeyRingCollection empty;
+ try {
+ empty = new PGPPublicKeyRingCollection(Collections.emptyList());
+ } catch (IOException | PGPException e) {
+ // Cannot happen for an empty collection.
+ throw new RuntimeException(e);
+ }
+ return () -> empty;
+ }
+ }
+
+ @SuppressWarnings("nls")
+ private static Path getGPPDirectory() {
+ // Handle ~ as might be used on macos and linux.
+ Function<String, Path> resolveTilde = s -> {
+ if (s.startsWith("~/") || s.startsWith("~" + File.separatorChar)) {
+ return new File(System.getProperty("user.home"), s.substring(2)).getAbsoluteFile().toPath();
+ }
+ return Paths.get(s);
+ };
+
+ // Allow the user to specify the GPG home used by p2 specifically.
+ Path path = checkDirectory(System.getProperty(GPG_HOME_PROPERTY), resolveTilde);
+ if (path != null) {
+ return path;
+ }
+
+ path = checkDirectory(System.getenv("GNUPGHOME"), resolveTilde);
+ if (path != null) {
+ return path;
+ }
+
+ if ("win32".equals(System.getProperty("osgi.os"))) {
+ // On Windows prefer %APPDATA%\gnupg if it exists, even if Cygwin is used.
+ path = checkDirectory(System.getenv("APPDATA"), //$NON-NLS-1$
+ s -> Paths.get(s).resolve("gnupg")); //$NON-NLS-1$
+ if (path != null) {
+ return path;
+ }
+ }
+ // All systems, including Cygwin and even Windows if %APPDATA%\gnupg doesn't
+ // exist.
+ return resolveTilde.apply("~/.gnupg"); //$NON-NLS-1$
+ }
+
+ private static Path checkDirectory(String dir, Function<String, Path> toPath) {
+ if (dir != null && !dir.isBlank()) {
+ try {
+ Path directory = toPath.apply(dir);
+ if (Files.isDirectory(directory)) {
+ return directory;
+ }
+ } catch (RuntimeException e) {
+ //$FALL-THROUGH$
+ }
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/IArtifactUIServices.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/IArtifactUIServices.java
new file mode 100644
index 000000000..b5cc328f5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/artifact/spi/IArtifactUIServices.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.artifact.spi;
+
+import java.io.File;
+import java.security.cert.Certificate;
+import java.util.*;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.eclipse.equinox.p2.core.UIServices;
+import org.eclipse.equinox.p2.core.UIServices.TrustInfo;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+
+/**
+ * An interface optionally implemented by {@link UIServices} to provide richer
+ * information for the users. In particular, the users often wish to know which
+ * artifacts are signed by which certificates or which keys when they are
+ * {@link UIServices#getTrustInfo(Certificate[][], Collection, String[])
+ * prompted} whether to trust such certificates or keys.
+ *
+ * @since 2.6
+ *
+ * @see UIServices#getTrustInfo(Certificate[][], Collection, String[])
+ */
+public interface IArtifactUIServices {
+
+ /**
+ * Opens a UI prompt to capture information about trusted content.
+ *
+ * @param untrustedCertificateChains a map from untrusted certificate chains to
+ * the set of keys of the artifacts signed by
+ * that chain.
+ * @param untrustedPGPKeys a map of untrusted PGP public keys to the
+ * set of keys of the artifacts signed by that
+ * key.
+ * @param unsignedArtifacts a set of keys of the artifacts that are not
+ * signed.
+ * @param artifactFiles a map from artifact keys to the file
+ * associated with that artifact key.
+ *
+ * @return the TrustInfo that describes the user's choices for trusting
+ * certificates, keys, and unsigned content.
+ *
+ * @see #getTrustInfo(UIServices, Map, Map, Set, Map)
+ * @see UIServices
+ */
+ TrustInfo getTrustInfo( //
+ Map<List<Certificate>, Set<IArtifactKey>> untrustedCertificateChains, //
+ Map<PGPPublicKey, Set<IArtifactKey>> untrustedPGPKeys, //
+ Set<IArtifactKey> unsignedArtifacts, //
+ Map<IArtifactKey, File> artifactFiles);
+
+ /**
+ * Opens a UI prompt to capture information about trusted content. This
+ * implementation is useful for delegating to an old-style
+ * {@link UIServices#getTrustInfo(Certificate[][], Collection, String[])
+ * UIServices implementation} that does not support the IArtifactUIServices
+ * interface.
+ *
+ * @param uiServices the delegate UI services.
+ * @param untrustedCertificateChains a map from untrusted certificate chains to
+ * the set of keys of the artifacts signed by
+ * that chain.
+ * @param untrustedPGPKeys a map of untrusted PGP public keys to the
+ * set of keys of the artifacts signed by that
+ * key.
+ * @param unsignedArtifacts a set of keys of the artifacts that are not
+ * signed.
+ * @param artifactFiles a map from artifact keys to the file
+ * associated with that artifact key.
+ *
+ * @return the TrustInfo that describes the user's choices for trusting
+ * certificates, keys, and unsigned content.
+ *
+ * @see #getTrustInfo(Map, Map, Set, Map)
+ * @see UIServices#getTrustInfo(Certificate[][], Collection, String[])
+ */
+ static TrustInfo getTrustInfo(UIServices uiServices, //
+ Map<List<Certificate>, Set<IArtifactKey>> untrustedCertificateChains, //
+ Map<PGPPublicKey, Set<IArtifactKey>> untrustedPGPKeys, //
+ Set<IArtifactKey> unsignedArtifacts, //
+ Map<IArtifactKey, File> artifactFiles) {
+ Certificate[][] unTrustedCertificateChainsArray = untrustedCertificateChains.keySet().stream()
+ .map(c -> c.toArray(Certificate[]::new)).toArray(Certificate[][]::new);
+ String[] details = unsignedArtifacts.isEmpty() ? null
+ : unsignedArtifacts.stream().map(artifactFiles::get).map(Objects::toString).toArray(String[]::new);
+ return uiServices.getTrustInfo(unTrustedCertificateChainsArray, untrustedPGPKeys.keySet(), details);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/PGPPublicKeyService.java b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/PGPPublicKeyService.java
new file mode 100644
index 000000000..6fbdff286
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.repository/src/org/eclipse/equinox/p2/repository/spi/PGPPublicKeyService.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.p2.repository.spi;
+
+import java.util.*;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.util.encoders.Hex;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.spi.IAgentServiceFactory;
+
+/**
+ * A service for managing and searching {@link PGPPublicKey keys}.
+ * Implementations may make use of a
+ * <a href="https://datatracker.ietf.org/doc/html/draft-shaw-openpgp-hkp-00">key
+ * server</a> to fetch up-to-date information about keys. Implementations should
+ * generally provide support for caching and efficient lookup of keys,
+ * especially lookup based on {@link PGPPublicKey#getKeyID() key ID} because
+ * signatures generally use {@link PGPSignature#getKeyID() key IDs} and this is
+ * the primary use case.
+ *
+ * <p>
+ * Implementors of this service are responsible for registering the
+ * implementation with the {@link IProvisioningAgent provisioning agent} either
+ * {@link IProvisioningAgent#registerService(String, Object) explicitly} or via
+ * an {@link IAgentServiceFactory agent service factory}.
+ * </p>
+ *
+ * @see PGPPublicKey#getKeyID()
+ * @see PGPSignature#getKeyID()
+ * @see IAgentServiceFactory
+ * @see IProvisioningAgent#registerService(String, Object)
+ *
+ * @since 2.6
+ */
+public abstract class PGPPublicKeyService {
+ /**
+ * The name used for obtaining a reference to the key service.
+ *
+ * @see IProvisioningAgent#getService(Class)
+ * @see IProvisioningAgent#getService(String)
+ */
+ public static final String SERVICE_NAME = PGPPublicKeyService.class.getName();
+
+ /**
+ * Returns the key associated with the given
+ * {@link PGPPublicKey#getFingerprint() fingerprint}.
+ *
+ * @param fingerprint the fingerprint for which to search.
+ * @return the key with the matching fingerprint.
+ *
+ * @see PGPPublicKey#getFingerprint()
+ */
+ public PGPPublicKey getKey(byte[] fingerprint) {
+ return getKey(toHex(fingerprint));
+ }
+
+ /**
+ * Returns the key associated with the given
+ * {@link PGPPublicKey#getFingerprint() fingerprint} represented as a
+ * {@link #toHex(byte[]) hexadecimal} string value.
+ *
+ * @param fingerprint the fingerprint for which to search.
+ * @return the key with the matching fingerprint.
+ *
+ * @see PGPPublicKey#getFingerprint()
+ * @see #toHex(byte[])
+ */
+ public abstract PGPPublicKey getKey(String fingerprint);
+
+ /**
+ * Returns the keys associated with the given {@link PGPPublicKey#getKeyID() key
+ * ID}. In general, key ID collisions are possible so implementations must be
+ * tolerant of that.
+ *
+ * @param keyID the key ID for which to search.
+ * @return the keys with the matching key IDs.
+ *
+ * @see PGPPublicKey#getKeyID()
+ * @see PGPSignature#getKeyID()
+ */
+ public abstract Collection<PGPPublicKey> getKeys(long keyID);
+
+ /**
+ * Adds the given key to this key service. An implementations may fetch more
+ * up-to-date information about this key from a key server and may return a
+ * different key than the one passed in here. In general an implementation may
+ * also return an existing key, with the same fingerprint, already known to the
+ * key service.
+ *
+ * @param key the key to add.
+ * @return the normalized key available in this key service.
+ */
+ public abstract PGPPublicKey addKey(PGPPublicKey key);
+
+ /**
+ * Returns the set of keys that have been verified to have signed the given key.
+ * These are the links in the web of trust.
+ *
+ * @param key the key for which to find keys that have signed it.
+ * @return the set of keys that have been verified to have signed the given key.
+ *
+ * @see PGPSignature#verifyCertification(String, PGPPublicKey)
+ * @see PGPSignature#verifyCertification(PGPPublicKey, PGPPublicKey)
+ */
+ public abstract Set<PGPPublicKey> getVerifiedCertifications(PGPPublicKey key);
+
+ /**
+ * If this key has a revocation signature that is verified to have been signed
+ * by the public key of that revocation signature, this returns the
+ * {@link PGPSignature#getCreationTime() creation time} of that signature,
+ * otherwise it returns <code>null</code>.
+ *
+ * @param key the key to test for revocation.
+ * @return when this key was verifiably revoked, or <code>null</code> if it is
+ * not revoked.
+ *
+ * @see PGPSignature#getKeyID()
+ * @see PGPPublicKey#hasRevocation()
+ * @see PGPSignature#getCreationTime()
+ * @see PGPSignature#KEY_REVOCATION
+ * @see PGPSignature#SUBKEY_REVOCATION
+ */
+ public abstract Date getVerifiedRevocationDate(PGPPublicKey key);
+
+ /**
+ * Returns whether the signature's {@link PGPSignature creation time} is before
+ * the key's {@link #getVerifiedRevocationDate(PGPPublicKey) verified revocation
+ * date}, if that key has one.
+ *
+ * @param signature the signature to test.
+ * @param key the corresponding key of this signature against which to
+ * test.
+ * @return <code>true</code> if the signature was created before the key was
+ * revoked or if the key is not revoked, <code>false</code> otherwise.
+ *
+ * @throws IllegalArgumentException if the signature's
+ * {@link PGPSignature#getKeyID() key} is not
+ * the same as the key's
+ * {@link PGPPublicKey#getKeyID() key ID}
+ */
+ public boolean isCreatedBeforeRevocation(PGPSignature signature, PGPPublicKey key) {
+ if (signature.getKeyID() != key.getKeyID()) {
+ throw new IllegalArgumentException("The signature's key ID must be the same as the key's key ID"); //$NON-NLS-1$
+ }
+ Date verifiedRevocationDate = getVerifiedRevocationDate(key);
+ if (verifiedRevocationDate != null) {
+ long signatureCreationTime = signature.getCreationTime().getTime();
+ if (signatureCreationTime >= verifiedRevocationDate.getTime()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the hexadecimal representation of the key's
+ * {@link PGPPublicKey#getFingerprint() fingerprint}.
+ *
+ * @param key the key for which to get the hexadecimal fingerprint.
+ *
+ * @return the hexadecimal representation of the key's fingerprint.
+ */
+ public static String toHexFingerprint(PGPPublicKey key) {
+ return Hex.toHexString(key.getFingerprint());
+ }
+
+ /**
+ * Returns the hexadecimal representation of the given bytes.
+ *
+ * @param bytes the bytes to convert to a hexadecimal representation.
+ * @return the hexadecimal representation of the given bytes.
+ */
+ public static String toHex(byte[] bytes) {
+ return Hex.toHexString(bytes);
+ }
+
+ /**
+ * Returns the hexadecimal representation of the given long value, typically a
+ * key ID, padded with leading zeros to a length of 16.
+ *
+ * @param keyID the long value, typically a key ID, to convert to a hexadecimal
+ * representation.
+ * @return the hexadecimal representation of the given long value, padded with
+ * leading zeros.
+ */
+ public static String toHex(long keyID) {
+ return String.format("%1$016x", keyID); //$NON-NLS-1$
+ }
+
+ /**
+ * If the signature's {@link PGPSignature#getCreationTime() creation time} is
+ * before the key's {@link PGPPublicKey#getCreationTime() creation time}, this
+ * returns a negative value equal to the number of milliseconds that the
+ * signature was created before the key was created. If the key has a
+ * {@link PGPPublicKey#getValidSeconds() validity period}, i.e., if the key
+ * expires, and the signature's creation time is after the key's expiration,
+ * returns a positive value equal to the number of milliseconds that the
+ * signature was created after the key's expiration. Otherwise, the signature
+ * was created during the period of time that the key was valid and this returns
+ * <code>0</code>.
+ *
+ * @param signature the signature to test.
+ * @param key the corresponding key of this signature against which to
+ * test.
+ * @return a negative value representing the number of milliseconds the
+ * signature was created before the key was created, a positive value
+ * representing the number of milliseconds the signature as created
+ * after the key expired, or <code>0</code> if the signature was created
+ * during the valid period of the key.
+ * @throws IllegalArgumentException if the signature's
+ * {@link PGPSignature#getKeyID() key} is not
+ * the same as the key's
+ * {@link PGPPublicKey#getKeyID() key ID}
+ */
+ public static long compareSignatureTimeToKeyValidityTime(PGPSignature signature, PGPPublicKey key) {
+ if (signature.getKeyID() != key.getKeyID()) {
+ throw new IllegalArgumentException("The signature's key ID must be the same as the key's key ID"); //$NON-NLS-1$
+ }
+ long keyCreationTime = key.getCreationTime().getTime();
+ long signatureCreationTime = signature.getCreationTime().getTime();
+ long delta = signatureCreationTime - keyCreationTime;
+ if (delta < 0) {
+ return delta;
+ }
+ long validSeconds = key.getValidSeconds();
+ if (validSeconds != 0) {
+ delta = signatureCreationTime - (keyCreationTime + validSeconds * 1000);
+ if (delta > 0) {
+ return delta;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.sar/pom.xml b/bundles/org.eclipse.equinox.p2.sar/pom.xml
index 2a1c6de4c..fb9f99428 100644
--- a/bundles/org.eclipse.equinox.p2.sar/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.sar/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF
index 6ccf36ca3..361f71e5e 100644
--- a/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.equinox.p2.tests.discovery;singleton:=true
-Bundle-Version: 1.3.100.qualifier
+Bundle-Version: 1.3.200.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Export-Package: org.eclipse.equinox.p2.discovery.tests;x-internal:=true,
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml
index 968754bef..f6f6a95f0 100644
--- a/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml
@@ -86,7 +86,7 @@
style="push">
<parameter
name="org.eclipse.equinox.p2.ui.discovery.commands.DirectoryParameter"
- value="http://www.eclipse.org/mylyn/discovery/directory-3.3.xml">
+ value="https://www.eclipse.org/mylyn/discovery/directory-3.3.xml">
</parameter>
<parameter
name="org.eclipse.equinox.p2.ui.discovery.commands.TagsParameter"
@@ -99,7 +99,7 @@
style="push">
<parameter
name="org.eclipse.equinox.p2.ui.discovery.commands.RepositoryParameter"
- value="http://download.eclipse.org/tools/mylyn/update/e3.4">
+ value="https://download.eclipse.org/tools/mylyn/update/e3.4">
</parameter>
</command>
</menuContribution>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/pom.xml b/bundles/org.eclipse.equinox.p2.tests.discovery/pom.xml
index 1a7e81a20..ce3ff89b1 100644
--- a/bundles/org.eclipse.equinox.p2.tests.discovery/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/pom.xml
@@ -4,12 +4,12 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.tests.discovery</artifactId>
- <version>1.3.100-SNAPSHOT</version>
+ <version>1.3.200-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/bundles/org.eclipse.equinox.p2.tests.optimizers/pom.xml b/bundles/org.eclipse.equinox.p2.tests.optimizers/pom.xml
index 3e89aab0c..089a4d389 100644
--- a/bundles/org.eclipse.equinox.p2.tests.optimizers/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.optimizers/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.tests.reconciler.product/pom.xml b/bundles/org.eclipse.equinox.p2.tests.reconciler.product/pom.xml
index 95344861e..13eefc82a 100644
--- a/bundles/org.eclipse.equinox.p2.tests.reconciler.product/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.reconciler.product/pom.xml
@@ -11,7 +11,7 @@
<parent>
<groupId>org.eclipse</groupId>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
diff --git a/bundles/org.eclipse.equinox.p2.tests.reconciler.product/reconciler.product b/bundles/org.eclipse.equinox.p2.tests.reconciler.product/reconciler.product
index 6cd3000e1..0532b3ab5 100644
--- a/bundles/org.eclipse.equinox.p2.tests.reconciler.product/reconciler.product
+++ b/bundles/org.eclipse.equinox.p2.tests.reconciler.product/reconciler.product
@@ -38,8 +38,8 @@
<plugin id="org.apache.commons.jxpath"/>
<plugin id="org.apache.commons.logging"/>
<plugin id="org.apache.felix.scr"/>
- <plugin id="org.apache.httpcomponents.httpclient"/>
- <plugin id="org.apache.httpcomponents.httpcore"/>
+ <plugin id="org.apache.httpcomponents.client5.httpclient5"/>
+ <plugin id="org.apache.httpcomponents.core5.httpcore5"/>
<plugin id="org.apache.xmlgraphics"/>
<plugin id="org.eclipse.core.commands"/>
<plugin id="org.eclipse.core.contenttype"/>
@@ -49,7 +49,7 @@
<plugin id="org.eclipse.core.expressions"/>
<plugin id="org.eclipse.core.jobs"/>
<plugin id="org.eclipse.core.net"/>
- <plugin id="org.eclipse.core.net.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.net.linux" fragment="true"/>
<plugin id="org.eclipse.core.runtime"/>
<plugin id="org.eclipse.e4.core.commands"/>
<plugin id="org.eclipse.e4.core.contexts"/>
@@ -78,7 +78,7 @@
<plugin id="org.eclipse.ecf.filetransfer"/>
<plugin id="org.eclipse.ecf.identity"/>
<plugin id="org.eclipse.ecf.provider.filetransfer"/>
- <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient45"/>
+ <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient5"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.source"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.ssl" fragment="true"/>
<plugin id="org.eclipse.ecf.ssl" fragment="true"/>
@@ -120,7 +120,7 @@
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.security.ui"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
<plugin id="org.eclipse.equinox.simpleconfigurator.manipulator"/>
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF
index 37792cc02..58c4adbf1 100644
--- a/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.tests.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.tests.ui
-Bundle-Version: 1.3.300.qualifier
+Bundle-Version: 1.3.400.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.100",
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml b/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml
index 2f8b7876a..f941878fb 100644
--- a/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.ui/pom.xml
@@ -15,13 +15,13 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.tests.ui</artifactId>
- <version>1.3.300-SNAPSHOT</version>
+ <version>1.3.400-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/actions/ElementUtilsTest.java b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/actions/ElementUtilsTest.java
index d0125ad1e..a4cfbd144 100644
--- a/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/actions/ElementUtilsTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests.ui/src/org/eclipse/equinox/p2/tests/ui/actions/ElementUtilsTest.java
@@ -58,15 +58,15 @@ public class ElementUtilsTest extends ProfileModificationActionTest {
public void testUpdateUsingElements() throws URISyntaxException {
// Two visible repos, one is added, the other is not
- URI known1 = new URI("http://example.com/known1");
- URI known2 = new URI("http://example.com/known2");
+ URI known1 = new URI("https://example.com/known1");
+ URI known2 = new URI("https://example.com/known2");
IMetadataRepositoryManager manager = getMetadataRepositoryManager();
manager.addRepository(known1);
// Add system repos that should not be known or affected by ElementUtils
// One is an enabled system repo, one is disabled system repo
- URI uri = new URI("http://example.com/1");
- URI uri2 = new URI("http://example.com/2");
+ URI uri = new URI("https://example.com/1");
+ URI uri2 = new URI("https://example.com/2");
manager.addRepository(uri);
manager.setRepositoryProperty(uri, IRepository.PROP_SYSTEM, Boolean.toString(true));
manager.addRepository(uri2);
@@ -82,7 +82,7 @@ public class ElementUtilsTest extends ProfileModificationActionTest {
MetadataRepositoryElement[] elements = children.toArray(new MetadataRepositoryElement[children.size()]);
// Add a visible repo not known by the elements
- URI uri3 = new URI("http://example.com/3");
+ URI uri3 = new URI("https://example.com/3");
manager.addRepository(uri3);
// Now update the repo using the elements.
diff --git a/bundles/org.eclipse.equinox.p2.tests.verifier/pom.xml b/bundles/org.eclipse.equinox.p2.tests.verifier/pom.xml
index 909390b0d..08bb6782c 100644
--- a/bundles/org.eclipse.equinox.p2.tests.verifier/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests.verifier/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
index 7859591e4..73c3d22e7 100644
--- a/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.tests;singleton:=true
-Bundle-Version: 1.8.600.qualifier
+Bundle-Version: 1.8.700.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.equinox.p2.tests.TestActivator
Bundle-Vendor: %providerName
@@ -45,7 +45,7 @@ Require-Bundle: org.eclipse.equinox.frameworkadmin,
org.eclipse.ecf.filetransfer;bundle-version="4.0.0",
org.eclipse.ecf.identity;bundle-version="3.1.0",
org.eclipse.ecf.provider.filetransfer;bundle-version="3.1.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45,
+ org.eclipse.ecf.provider.filetransfer.httpclient5,
org.eclipse.equinox.p2.reconciler.dropins;bundle-version="1.1.0",
org.eclipse.ant.core;bundle-version="3.2.200",
org.apache.ant;bundle-version="1.7.1",
@@ -114,6 +114,5 @@ Import-Package: org.eclipse.ant.core,
org.eclipse.osgi.util;version="1.1.0",
org.osgi.framework;version="1.3.0",
org.osgi.service.packageadmin;version="1.2.0",
- org.osgi.util.tracker;version="1.3.0",
- org.easymock;version="4.0.0"
+ org.osgi.util.tracker;version="1.3.0"
Automatic-Module-Name: org.eclipse.equinox.p2.tests
diff --git a/bundles/org.eclipse.equinox.p2.tests/plugin.xml b/bundles/org.eclipse.equinox.p2.tests/plugin.xml
index 841b529ea..857699598 100644
--- a/bundles/org.eclipse.equinox.p2.tests/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/plugin.xml
@@ -153,4 +153,10 @@
suffix="@testArtifactRepositoryRegistry">
</filter>
</extension>
+ <extension
+ point="org.eclipse.equinox.p2.engine.pgp">
+ <trustedKeys
+ path="testData/pgp/signer2-publickey.asc">
+ </trustedKeys>
+ </extension>
</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.tests/pom.xml b/bundles/org.eclipse.equinox.p2.tests/pom.xml
index f0006e807..894085114 100644
--- a/bundles/org.eclipse.equinox.p2.tests/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/pom.xml
@@ -10,13 +10,13 @@
<parent>
<groupId>org.eclipse</groupId>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.tests</artifactId>
- <version>1.8.600-SNAPSHOT</version>
+ <version>1.8.700-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
index dcc84bbfb..ab74b9572 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AbstractProvisioningTest.java
@@ -739,7 +739,7 @@ public abstract class AbstractProvisioningTest extends TestCase {
}
}
- public static void writeBuffer(File outputFile, StringBuffer buffer) throws IOException {
+ public static void writeBuffer(File outputFile, StringBuilder buffer) throws IOException {
outputFile.getParentFile().mkdirs();
try (FileOutputStream stream = new FileOutputStream(outputFile)) {
stream.write(buffer.toString().getBytes());
@@ -1367,7 +1367,7 @@ public abstract class AbstractProvisioningTest extends TestCase {
IInstallableUnit sourceIU = it.next();
IQueryResult destinationCollector = destination.query(QueryUtil.createIUQuery(sourceIU), null);
assertEquals(message, 1, queryResultSize(destinationCollector));
- assertTrue(message, sourceIU.equals(destinationCollector.iterator().next()));
+ assertEquals(message, sourceIU, destinationCollector.iterator().next());
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/TestData.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/TestData.java
index c423c5dd5..d2a8bc870 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/TestData.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/TestData.java
@@ -135,15 +135,16 @@ public class TestData {
* @throws IOException
*/
public static void assertEquals(ZipInputStream expected, ZipInputStream actual) throws IOException {
- Map<String, Object[]> jar1 = getEntries(expected);
- Map<String, Object[]> jar2 = getEntries(actual);
- for (String name : jar1.keySet()) {
- Object[] file1 = jar1.get(name);
- Object[] file2 = jar2.remove(name);
- Assert.assertNotNull(file2);
-
- ZipEntry entry1 = (ZipEntry) file1[0];
- ZipEntry entry2 = (ZipEntry) file2[0];
+ Map<String, Object[]> expectedEntries = getEntries(expected);
+ Map<String, Object[]> actualEntries = getEntries(actual);
+ for (String name : expectedEntries.keySet()) {
+ Object[] expectedFiles = expectedEntries.get(name);
+ Object[] actualFiles = actualEntries.remove(name);
+ Assert.assertNotNull(name + " entry is missing in actual zip stream (actual=" + actualEntries.keySet()
+ + ", expected=" + expectedEntries.keySet() + ")", actualFiles);
+
+ ZipEntry entry1 = (ZipEntry) expectedFiles[0];
+ ZipEntry entry2 = (ZipEntry) actualFiles[0];
// compare the entries
Assert.assertEquals(entry1.getName(), entry2.getName());
Assert.assertEquals(entry1.getSize(), entry2.getSize());
@@ -154,11 +155,11 @@ public class TestData {
Assert.assertEquals(entry1.getMethod(), entry2.getMethod());
// check the content of the entries
- Assert.assertArrayEquals((byte[]) file1[1], (byte[]) file2[1]);
+ Assert.assertArrayEquals((byte[]) expectedFiles[1], (byte[]) actualFiles[1]);
}
// ensure that we have consumed all of the entries in the second JAR
- Assert.assertEquals(0, jar2.size());
+ Assert.assertEquals(0, actualEntries.size());
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/PGPSignatureVerifierTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/PGPSignatureVerifierTest.java
index 36b50a545..dd3356767 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/PGPSignatureVerifierTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/processors/PGPSignatureVerifierTest.java
@@ -13,31 +13,57 @@ package org.eclipse.equinox.p2.tests.artifact.processors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Files;
+import java.util.Set;
import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.equinox.internal.p2.artifact.processors.pgp.Messages;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.provisional.p2.repository.DefaultPGPPublicKeyService;
+import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.IProcessingStepDescriptor;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.spi.ProcessingStepDescriptor;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.equinox.p2.tests.TestAgentProvider;
import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
public class PGPSignatureVerifierTest {
+ @Rule
+ public TestAgentProvider agentProvider = new TestAgentProvider();
+
+ @Before
+ public void initialize() {
+ try {
+ PGPPublicKeyService keyService = agentProvider.getService(PGPPublicKeyService.class);
+ if (keyService instanceof DefaultPGPPublicKeyService) {
+ DefaultPGPPublicKeyService defaultPGPPublicKeyService = (DefaultPGPPublicKeyService) keyService;
+ defaultPGPPublicKeyService.setKeyServers(Set.of());
+ defaultPGPPublicKeyService.setGPG(false);
+ }
+ } catch (ProvisionException e) {
+ //$FALL-THROUGH$
+ }
+ }
+
// @formatter:off
/*
- * About test keys:
- * * Install the public&private keys locally
- * * then generate signatures with eg `gpg -u signer2@fakeuser.eclipse.org -a --output signed_by_signer_2 --detach-sig testArtifact`
+ * About test keys: * Install the public&private keys locally * then generate
+ * signatures with eg `gpg -u signer2@fakeuser.eclipse.org -a --output
+ * signed_by_signer_2 --detach-sig testArtifact`
*/
// @formatter:on
@@ -50,6 +76,23 @@ public class PGPSignatureVerifierTest {
return res;
}
+ private static class ArtifactOutputStream extends ByteArrayOutputStream implements IAdaptable {
+ IArtifactDescriptor descriptor = new ArtifactDescriptor(
+ new ArtifactKey("whatever", "whatever", Version.parseVersion("1.0.0")));
+
+ public IArtifactDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ if (adapter.isInstance(descriptor)) {
+ return adapter.cast(descriptor);
+ }
+ return null;
+ }
+ }
+
private String read(String resource) throws IOException, URISyntaxException {
return Files.readString(new File(FileLocator.toFileURL(getClass().getResource(resource)).toURI()).toPath());
}
@@ -58,8 +101,11 @@ public class PGPSignatureVerifierTest {
public void testOK() throws Exception {
IProcessingStepDescriptor processingStepDescriptor = new ProcessingStepDescriptor(null, null, false);
IArtifactDescriptor artifact = createArtifact("signed_by_signer_1", "public_signer1.pgp");
+ @SuppressWarnings("resource")
PGPSignatureVerifier verifier = new PGPSignatureVerifier();
- verifier.initialize(null, processingStepDescriptor, artifact);
+ verifier.initialize(agentProvider.getAgent(), processingStepDescriptor, artifact);
+ ArtifactOutputStream artifactOutputStream = new ArtifactOutputStream();
+ verifier.link(artifactOutputStream, new NullProgressMonitor());
Assert.assertTrue(verifier.getStatus().toString(), verifier.getStatus().isOK());
try (InputStream bytes = getClass().getResourceAsStream("testArtifact")) {
bytes.transferTo(verifier);
@@ -67,6 +113,12 @@ public class PGPSignatureVerifierTest {
Assert.assertTrue(verifier.getStatus().isOK());
verifier.close();
Assert.assertTrue(verifier.getStatus().isOK());
+
+ IArtifactDescriptor descriptor = artifactOutputStream.getDescriptor();
+ Assert.assertNotNull("Signatures should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME));
+ Assert.assertNotNull("Keys should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
}
@Test
@@ -74,10 +126,22 @@ public class PGPSignatureVerifierTest {
IProcessingStepDescriptor processingStepDescriptor = new ProcessingStepDescriptor(null, null, false);
IArtifactDescriptor artifact = createArtifact("signed_by_signer_1", "public_signer2.pgp");
try (PGPSignatureVerifier verifier = new PGPSignatureVerifier()) {
- verifier.initialize(null, processingStepDescriptor, artifact);
- IStatus status = verifier.getStatus();
- assertEquals(IStatus.ERROR, status.getSeverity());
- assertTrue(status.getMessage().contains("Public key not found for"));
+ verifier.initialize(agentProvider.getAgent(), processingStepDescriptor, artifact);
+ ArtifactOutputStream artifactOutputStream = new ArtifactOutputStream();
+ verifier.link(artifactOutputStream, new NullProgressMonitor());
+ Assert.assertTrue(verifier.getStatus().toString(), verifier.getStatus().isOK());
+ try (InputStream bytes = getClass().getResourceAsStream("testArtifact")) {
+ bytes.transferTo(verifier);
+ }
+ Assert.assertTrue(verifier.getStatus().isOK());
+ verifier.close();
+ Assert.assertTrue(verifier.getStatus().isOK());
+
+ IArtifactDescriptor descriptor = artifactOutputStream.getDescriptor();
+ Assert.assertNull("No signatures should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME));
+ Assert.assertNull("No keys should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
}
}
@@ -86,7 +150,7 @@ public class PGPSignatureVerifierTest {
IProcessingStepDescriptor processingStepDescriptor = new ProcessingStepDescriptor(null, null, false);
IArtifactDescriptor artifact = createArtifact("signed_by_signer_1_tampered", "public_signer1.pgp");
try (PGPSignatureVerifier verifier = new PGPSignatureVerifier()) {
- verifier.initialize(null, processingStepDescriptor, artifact);
+ verifier.initialize(agentProvider.getAgent(), processingStepDescriptor, artifact);
// signature has random modification, making it invalid by itself
Assert.assertFalse(verifier.getStatus().isOK());
}
@@ -96,8 +160,9 @@ public class PGPSignatureVerifierTest {
public void testSignatureForAnotherArtifact() throws Exception {
IProcessingStepDescriptor processingStepDescriptor = new ProcessingStepDescriptor(null, null, false);
IArtifactDescriptor artifact = createArtifact("signed_by_signer_1_otherArtifact", "public_signer1.pgp");
+ @SuppressWarnings("resource")
PGPSignatureVerifier verifier = new PGPSignatureVerifier();
- verifier.initialize(null, processingStepDescriptor, artifact);
+ verifier.initialize(agentProvider.getAgent(), processingStepDescriptor, artifact);
Assert.assertTrue(verifier.getStatus().isOK());
try (InputStream bytes = getClass().getResourceAsStream("testArtifact")) {
bytes.transferTo(verifier);
@@ -106,6 +171,6 @@ public class PGPSignatureVerifierTest {
verifier.close();
IStatus status = verifier.getStatus();
assertEquals(IStatus.ERROR, status.getSeverity());
- assertTrue(status.getMessage().contains(Messages.Error_SignatureAndFileDontMatch));
+ assertTrue(status.getMessage().matches(".*signature.*invalid.*"));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/PGPVerifierTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/PGPVerifierTest.java
index c010af306..0d4525b23 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/PGPVerifierTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/PGPVerifierTest.java
@@ -10,15 +10,26 @@
*******************************************************************************/
package org.eclipse.equinox.p2.tests.artifact.repository;
+import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.stream.Stream;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
import org.eclipse.equinox.internal.p2.artifact.repository.MirrorRequest;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.provisional.p2.repository.DefaultPGPPublicKeyService;
+import org.eclipse.equinox.p2.core.IAgentLocation;
import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -30,7 +41,6 @@ public class PGPVerifierTest extends AbstractProvisioningTest {
@Before
public void setUp() throws Exception {
super.setUp();
- PGPSignatureVerifier.KNOWN_KEYS.clear();
}
private void loadPGPTestRepo(String repoName) throws Exception {
@@ -42,29 +52,75 @@ public class PGPVerifierTest extends AbstractProvisioningTest {
@Test
public void testAllGood() throws Exception {
- IStatus mirrorStatus = performMirrorFrom("repoPGPOK");
+ MirrorRequest mirrorRequest = performMirrorFrom("repoPGPOK");
+ IStatus mirrorStatus = mirrorRequest.getResult();
assertOK(mirrorStatus);
+
+ IArtifactDescriptor[] artifactDescriptors = targetRepo.getArtifactDescriptors(mirrorRequest.getArtifactKey());
+ Assert.assertEquals(1, artifactDescriptors.length);
+ IArtifactDescriptor descriptor = artifactDescriptors[0];
+ Assert.assertNotNull("Signatures should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME));
+ Assert.assertNotNull("Keys should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
}
@Test
public void testAllGoodWithEncodedProperties() throws Exception {
- IStatus mirrorStatus = performMirrorFrom("repoPGPOK_encoded");
+ MirrorRequest mirrorRequest = performMirrorFrom("repoPGPOK_encoded");
+ IStatus mirrorStatus = mirrorRequest.getResult();
assertOK(mirrorStatus);
+
+ IArtifactDescriptor[] artifactDescriptors = targetRepo.getArtifactDescriptors(mirrorRequest.getArtifactKey());
+ Assert.assertEquals(1, artifactDescriptors.length);
+ IArtifactDescriptor descriptor = artifactDescriptors[0];
+ Assert.assertNotNull("Signatures should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME));
+ Assert.assertNotNull("Keys should be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
}
- private IStatus performMirrorFrom(String repoName) throws Exception {
+ private MirrorRequest performMirrorFrom(String repoName) throws Exception {
+ // Clear the remembered keys/cache of the agent.
+ IAgentLocation agentLocation = getAgent().getService(IAgentLocation.class);
+ Path repositoryCache = Paths
+ .get(agentLocation.getDataArea(org.eclipse.equinox.internal.p2.repository.Activator.ID));
+ if (Files.isDirectory(repositoryCache)) {
+ try (Stream<Path> walk = Files.walk(repositoryCache)) {
+ walk.sorted(Comparator.reverseOrder()).forEach(path -> {
+ try {
+ Files.delete(path);
+ } catch (IOException e) {
+ // Ignore
+ }
+ });
+ }
+ }
+ DefaultPGPPublicKeyService keyService = new DefaultPGPPublicKeyService(getAgent());
+ keyService.setGPG(false);
+ keyService.setKeyServers(Set.of());
+
+ getAgent().registerService(PGPPublicKeyService.SERVICE_NAME, keyService);
loadPGPTestRepo(repoName);
ArtifactKey key = new ArtifactKey("osgi.bundle", "blah", Version.create("1.0.0.123456"));
MirrorRequest mirrorRequest = new MirrorRequest(key, targetRepo, NO_PROPERTIES, NO_PROPERTIES, getTransport());
mirrorRequest.perform(sourceRepo, getMonitor());
- return mirrorRequest.getResult();
+ return mirrorRequest;
}
@Test
public void testMissingPublicKey() throws Exception {
- IStatus mirrorStatus = performMirrorFrom("repoMissingPublicKey");
- assertNotOK(mirrorStatus);
- assertTrue(mirrorStatus.toString().contains("Public key not found"));
+ MirrorRequest mirrorRequest = performMirrorFrom("repoMissingPublicKey");
+ IStatus mirrorStatus = mirrorRequest.getResult();
+ assertOK(mirrorStatus);
+
+ IArtifactDescriptor[] artifactDescriptors = targetRepo.getArtifactDescriptors(mirrorRequest.getArtifactKey());
+ Assert.assertEquals(1, artifactDescriptors.length);
+ IArtifactDescriptor descriptor = artifactDescriptors[0];
+ Assert.assertNull("Signatures should not be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME));
+ Assert.assertNull("Keys should not be present",
+ descriptor.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME));
}
@Override
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/TransferTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/TransferTest.java
index 718db58cc..dd7b38315 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/TransferTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/TransferTest.java
@@ -57,7 +57,9 @@ public class TransferTest extends AbstractProvisioningTest {
try {
fos.close();
if (f != null) {
- String[] ecfPlugins = new String[] {"org.eclipse.ecf", "org.eclipse.ecf.identity", "org.eclipse.ecf.filetransfer", "org.eclipse.ecf.provider.filetransfer", "org.eclipse.ecf.provider.filetransfer.httpclient45"};
+ String[] ecfPlugins = new String[] { "org.eclipse.ecf", "org.eclipse.ecf.identity",
+ "org.eclipse.ecf.filetransfer", "org.eclipse.ecf.provider.filetransfer",
+ "org.eclipse.ecf.provider.filetransfer.httpclient5" };
StringBuilder buffer = new StringBuilder();
for (String ecfPlugin : ecfPlugins) {
Bundle bundle = Platform.getBundle(ecfPlugin);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/director/DirectorApplicationTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/director/DirectorApplicationTest.java
index 973a234ff..9ac6d4b8a 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/director/DirectorApplicationTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/director/DirectorApplicationTest.java
@@ -838,4 +838,24 @@ public class DirectorApplicationTest extends AbstractProvisioningTest {
return avoidTrustPromptService.getTrustInfo(untrustedChain, null);
}
+ public void testPGPSignedArtifact() throws Exception {
+ File srcRepo = getTestData(null, "/testData/pgp/repoPGPOK");
+
+ IArtifactRepositoryManager artifactManager = getAgent().getService(IArtifactRepositoryManager.class);
+ IMetadataRepositoryManager metadataManager = getAgent().getService(IMetadataRepositoryManager.class);
+ assertNotNull(artifactManager);
+ assertNotNull(metadataManager);
+
+ File destinationRepo = new File(getTempFolder(), "DirectorApp Destination");
+ String[] args = getSingleRepoArgs(null, srcRepo, srcRepo, destinationRepo, "blah");
+
+ destinationRepo.mkdirs();
+
+ StringBuffer buffer = runDirectorApp(null, args);
+ assertFalse(buffer.toString(), buffer.toString().contains("failed"));
+
+ artifactManager.removeRepository(srcRepo.toURI());
+ metadataManager.removeRepository(srcRepo.toURI());
+ delete(destinationRepo);
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/CertificateCheckerTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/CertificateCheckerTest.java
index 5f4049a5a..ba56cc6ea 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/CertificateCheckerTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/engine/CertificateCheckerTest.java
@@ -16,8 +16,12 @@ package org.eclipse.equinox.p2.tests.engine;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.security.cert.Certificate;
+import java.util.Comparator;
import java.util.Map;
+import java.util.Set;
+import java.util.stream.Stream;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
import org.eclipse.equinox.internal.p2.core.AgentLocation;
@@ -25,12 +29,14 @@ import org.eclipse.equinox.internal.p2.core.ProvisioningAgent;
import org.eclipse.equinox.internal.p2.engine.EngineActivator;
import org.eclipse.equinox.internal.p2.engine.phases.CertificateChecker;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.internal.provisional.p2.repository.DefaultPGPPublicKeyService;
import org.eclipse.equinox.p2.core.IAgentLocation;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.core.UIServices;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
import org.eclipse.equinox.p2.tests.TestActivator;
import org.eclipse.equinox.p2.tests.TestData;
@@ -39,7 +45,7 @@ import org.eclipse.equinox.p2.tests.TestData;
* Tests for {@link CertificateChecker}.
*/
public class CertificateCheckerTest extends AbstractProvisioningTest {
- private static final String PGP_PUBLIC_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "\n"
+ private static final String PGP_SIGNER1_PUBLIC_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "\n"
+ "mQGNBGB1bugBDADQ5l7YnS9hNFRkBKSrvVNHt/TxeHaNNIHkdTC56I1QdThsOt4Y\n"
+ "oQRI27AEOaY1GFEi6+QqwxALcMMMSTgkCRs2NFGqlWMVzNYE7bJMWChVa7uQ/9CG\n"
+ "1HRbXwVwQx3hFgU4kmw1Kl/IH4LX76d9gAMyFANPjYZJSjbAv54wOlKruDRgpQFF\n"
@@ -78,7 +84,7 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
+ "cKLSMOR+Tji6n7FjOcVl6VoDKTjdxj9OgAlbZ7W9jEArrUjDdCk/m4jq9h9phpli\n"
+ "BHoul/nauwtlUnQes1V+39Rk9l7gddKWg3dlwg6CjB5MkmcaeyxgANcyKgrunpg=\n" + "=JYpC\n"
+ "-----END PGP PUBLIC KEY BLOCK-----\n";
- private static final String PGP_SIGNATURE = "-----BEGIN PGP SIGNATURE-----\n" + "\n"
+ private static final String PGP_SIGNER1_SIGNATURE = "-----BEGIN PGP SIGNATURE-----\n" + "\n"
+ "iQHRBAABCAA7FiEE6ZbGcKp/ZUCb9dtWE5442Q3tEfAFAmB4Bf8dHHNpZ25lcjFA\n"
+ "ZmFrZXVzZXIuZWNsaXBzZS5vcmcACgkQE5442Q3tEfBPuAwAhE4zA7BswKFhEtzm\n"
+ "DS3EbyRr/U13sV01YxqGtxYDCfrOt8TGVPXJSvo0AVP4vLFc5b+0jtVFoarFJNBu\n"
@@ -88,8 +94,48 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
+ "2XpuKxPXGavKfpSvssVQIZ6aWi5W6wp5lZAQQddZvYAv3Gi5CZZcUT7ayFJYdD23\n"
+ "p9jz76G7MXm0f0uNT9B57T72QryokUIEIJYsCb6lNjWUQB4cd0+JesM7sHwweOQ3\n"
+ "7iTFc+WgVJkP0e695mm1tcvtQHUPbIItYJUsndyLgGInzglxN8+F4U4k8uapydI9\n"
- + "RmV2NVAifYp8z95Am5AnlG8lqjwrWk5bMbJH82QsQESrNT/h\n" + "=8Vrn\n"
- + "-----END PGP SIGNATURE-----\n";
+ + "RmV2NVAifYp8z95Am5AnlG8lqjwrWk5bMbJH82QsQESrNT/h\n" + "=8Vrn\n" + "-----END PGP SIGNATURE-----\n";
+
+ private static final String PGP_SIGNER2_PUBLIC_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n" + "\r\n"
+ + "mQINBGHUyxYBEADATeNx4XA4H2fP9mD5xwlIyh7qvHLezgXpqCwNS9ATqBwnfrCV\r\n"
+ + "06a+pfSLsLoXrP/sdaB5WhijfuxTis18RMfoDVwGMRqyD2GiBCl2vwJDg3BUwHnc\r\n"
+ + "H7W6XkWKO7dkPmF+TUbD3cTWZ7cvrPmMjinmXaq8htuktGuE2VEGZRnuG1m+ChDM\r\n"
+ + "PnSb1ioFS2+MJv13P2fagVk2qC95DkPJGpMk3CY3ghLDEaY/KaJl+8axAlUUUk9N\r\n"
+ + "d3k/KVxxf5k3g26EVQkWWgH2mmolptGO101xW64iked97Cy4NK2yafOF/wmpsavx\r\n"
+ + "PGpOewnDgAJBBPkum6mPH0vcOZgxmLyh4uqfPfr3IaBQlbJLN2dXaDsV83j5t1wZ\r\n"
+ + "2qxOPcWBfORm6W7dC0TQgCXbEG0geMBpJtvnMX83Q2ORqDpjbHRJsV2k+8NxaXON\r\n"
+ + "pYXGr+Lj/9n0xfNEDXhCdGab0XP2tVZ5jfr2OQ5dAomEaPqK5Kq7akoWMddpDLNC\r\n"
+ + "G4IvH8G0cxwruJk00uwd6Nd2NVqVMRYCsBbA89VanUnutLUIpVnnOAetlX9blXHO\r\n"
+ + "JtmiCPGgHyp+iYGhKYVzfuZQyFhonbi0AhidJDvbHsoLT3p4Mcog1B9y6MODBE7R\r\n"
+ + "jwrU+qMqYsYeFhGYKbYyXv9TfEyUvtCQ/GnTtRJAQyicFdOdbK37WecS6QARAQAB\r\n"
+ + "tDdFY2xpcHNlIHAyIHRlc3QgU2lnbmVyIDIgPHNpZ25lcjJAZmFrZXVzZXIuZWNs\r\n"
+ + "aXBzZS5vcmc+iQJYBBMBCABCFiEEzZ1aK4a8T+GDlFHh4vaU9BsKs3AFAmHUyxYC\r\n"
+ + "GwMFCQPCZwAFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJEOL2lPQbCrNw\r\n"
+ + "wH4QAIiCaw1mREgt4ldz7hQvmGxdMuQwVKZPzbOIAlYbZBo0q9SmeMf/CBCO90hg\r\n"
+ + "LFmJmsZV4KUU5NKI7UwkDVrpUCl00Ok6+gtiUTId2tRcwXI+25I478VX27j6OkQj\r\n"
+ + "7Xr6giv8cn8nstt5CF6xxeqrxvpmnZC0u30jE6CL6SdXSd0vViFDPQj3KgGJCRc9\r\n"
+ + "St+LHB3XJTsadihzQnscqI4E2i5Z3Uj1GogqxtR59M1NAXubl5dySM0qHhwn8O+6\r\n"
+ + "lcgCCeuyMLLde1M1v8w07jdRUM+IFqHrRnE89EPH3MQeZbQ3UfFXK2r7wx2BJCqL\r\n"
+ + "Irtn68kz834ByKchGR6DqaAw0q+iF2QkgzYxpwai41BgmtUCYnj+HxQNIF4KTzDe\r\n"
+ + "nd8mDAPWttGCoVuV2Tyu9peYOaqyAZ2PZwUEH5MqihPCbenU17RLXzRu/IT/SH47\r\n"
+ + "NGrN3yKGgLZr2EVWPWFibpoxP4G4NUCHsY75uiL2EWPVSjK/+OOeHIE5k3U3lYwB\r\n"
+ + "7clhBwMkIhQHJ+a0SHRkKixkwrQDw4veKY4LaD0NCBLHFoV5L9orH1ToGM729kr/\r\n"
+ + "+4I1VQFkL3KvfLjmRbTUgwHeqEquQ96JtqowbNwlpujfHXQKDNsuiKGP5OazXll5\r\n"
+ + "sH2CR7e4ePqhhzxjLvi9e/79Khq+08eqllS3rs06EXEAJYTo\r\n" + "=807V\r\n"
+ + "-----END PGP PUBLIC KEY BLOCK-----\r\n" + "";
+ private static final String PGP_SIGNER2_SIGNATURE = "-----BEGIN PGP SIGNATURE-----\n" + "\n"
+ + "iQIzBAABCAAdFiEEzZ1aK4a8T+GDlFHh4vaU9BsKs3AFAmHUy4UACgkQ4vaU9BsK\n"
+ + "s3DjuhAAvlCtqhK/7/aAG0/cXtlpu0fPC176OmEmBGTjCsrGdWwuRHsqXbLnMBVZ\n"
+ + "0D1m38MDvuYZfJuP7arw7USKp+Jy54Bv/YwvHLl74YTx1BN9hAN9QvyLxLZOjdm1\n"
+ + "/ipiWUuUgGa/brxEZNQqSR0w17TqXkIJHeFFS3T/rNH/Ckom5vQhAEm9HwJYeGdt\n"
+ + "tJ5BUl7BS1rrEOs+xmzqLu6AaERREc5gGRniJe7aP2Ke+/wL6oOLG3v/6vsJSM2e\n"
+ + "t+Olo4Ugc6JbdNrwvTO8kkTxsi0gp2CPhKl3RZVnbGoe4tXHawmk2V3eVTa0w6iP\n"
+ + "ARPJ/xH2dDsRi4Kz3OkcyQOI24jGmaqpUrx3+f2BnEbcVs4cHIJc+O2gh1WUz6uY\n"
+ + "Zw7qtK0W3H+E7RuJLCScgasPZZPBzyA6B3o2J3bfXnG5r41aJEuiq3otgllrBakG\n"
+ + "u7fX00h8lylgRrlCb4mquZxxRsrl+ac6U5eYdDMkK5VNkXgrus8FedIh3vmqI7RR\n"
+ + "ou9GEjho4kebt1Y1yTAQnxWBtTUG2hFt6VirKydI7+ZcCZmbD9lrZT6xVQOCkyUQ\n"
+ + "Cwy7vNPWkpMBBRVLoaThD2+7znDpb6wNYf9mDCcCK8tyuVCDSYEFX6jlqv1yfpNl\n"
+ + "QlYE1biLAHl09NH397Ta/9cWdfu68I7Mv4Ev2zu45OGa83h820M=\n" + "=9Ha/\n" + "-----END PGP SIGNATURE-----\n";
class CertificateTestService extends UIServices {
public boolean unsignedReturnValue = true;
@@ -117,14 +163,22 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
CertificateTestService serviceUI;
File unsigned;
private ProvisioningAgent testAgent;
+ private Path agentLocation;
@Override
protected void setUp() throws Exception {
serviceUI = new CertificateTestService();
testAgent = new ProvisioningAgent();
testAgent.registerService(UIServices.SERVICE_NAME, serviceUI);
+ agentLocation = Files.createTempDirectory("certificateTest");
+ testAgent.setLocation(agentLocation.toUri());
testAgent.setBundleContext(TestActivator.getContext());
checker = new CertificateChecker(testAgent);
+ PGPPublicKeyService keyService = testAgent.getService(PGPPublicKeyService.class);
+ if (keyService instanceof DefaultPGPPublicKeyService) {
+ ((DefaultPGPPublicKeyService) keyService).setKeyServers(Set.of());
+ }
+
try {
unsigned = TestData.getFile("CertificateChecker", "unsigned.jar");
} catch (IOException e) {
@@ -134,12 +188,26 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
assertTrue("1.0", unsigned.exists());
}
+ @Override
+ protected void tearDown() throws Exception {
+ try (Stream<Path> walk = Files.walk(agentLocation)) {
+ walk.sorted(Comparator.reverseOrder()).forEach(path -> {
+ try {
+ Files.delete(path);
+ } catch (IOException e) {
+ // Ignore
+ }
+ });
+ }
+ }
+
/**
- * Tests that installing unsigned content is not allowed when the policy says it must fail.
+ * Tests that installing unsigned content is not allowed when the policy says it
+ * must fail.
*/
public void testPolicyAllow() {
try {
- //if the service is consulted it will say no
+ // if the service is consulted it will say no
serviceUI.unsignedReturnValue = false;
System.getProperties().setProperty(EngineActivator.PROP_UNSIGNED_POLICY, EngineActivator.UNSIGNED_ALLOW);
checker.add(Map.of(new ArtifactDescriptor(new ArtifactKey("what", "ever", Version.create("1"))), unsigned));
@@ -151,7 +219,8 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
}
/**
- * Tests that installing unsigned content is not allowed when the policy says it must fail.
+ * Tests that installing unsigned content is not allowed when the policy says it
+ * must fail.
*/
public void testPolicyFail() {
try {
@@ -166,7 +235,8 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
}
/**
- * Tests that installing unsigned content with the "prompt" policy and the prompt succeeds.
+ * Tests that installing unsigned content with the "prompt" policy and the
+ * prompt succeeds.
*/
public void testPolicyPromptSuccess() {
try {
@@ -194,7 +264,8 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
}
/**
- * Tests that installing unsigned content with the "prompt" policy and the prompt says no.
+ * Tests that installing unsigned content with the "prompt" policy and the
+ * prompt says no.
*/
public void testPolicyPromptCancel() {
try {
@@ -210,16 +281,17 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
}
/**
- * Tests that trust checks that occur in a headless environment are properly treated
- * as permissive, but not persistent, the same way as it would be if the service registration
- * were not there.
+ * Tests that trust checks that occur in a headless environment are properly
+ * treated as permissive, but not persistent, the same way as it would be if the
+ * service registration were not there.
*/
public void testBug291049() {
try {
// Intentionally replace our service with a null service
testAgent.registerService(UIServices.SERVICE_NAME, null);
checker.add(Map.of(new ArtifactDescriptor(new ArtifactKey("what", "ever", Version.create("1"))), unsigned));
- // TODO need to add some untrusted files here, too. To prove that we treated them as trusted temporarily
+ // TODO need to add some untrusted files here, too. To prove that we treated
+ // them as trusted temporarily
System.getProperties().setProperty(EngineActivator.PROP_UNSIGNED_POLICY, EngineActivator.UNSIGNED_PROMPT);
IStatus result = checker.start();
assertTrue("1.0", result.isOK());
@@ -241,10 +313,9 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
unsigned = TestData.getFile("pgp/repoPGPOK/plugins", "blah_1.0.0.123456.jar");
ArtifactDescriptor artifactDescriptor = new ArtifactDescriptor(
new ArtifactKey("what", "ever", Version.create("1")));
- artifactDescriptor.addProperties(
- Map.of(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME, PGP_SIGNATURE, //
- PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME,
- PGP_PUBLIC_KEY));
+ artifactDescriptor
+ .addProperties(Map.of(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME, PGP_SIGNER1_SIGNATURE, //
+ PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME, PGP_SIGNER1_PUBLIC_KEY));
checker.add(Map.of(artifactDescriptor, unsigned));
System.getProperties().setProperty(EngineActivator.PROP_UNSIGNED_POLICY, EngineActivator.UNSIGNED_PROMPT);
IStatus result = checker.start();
@@ -255,22 +326,14 @@ public class CertificateCheckerTest extends AbstractProvisioningTest {
}
}
- public void testPGPSignedArtifactTrustedKeyInProfile() throws ProvisionException, IOException {
+ public void testPGPSignedArtifactTrustedKeyInProvideCapability() throws IOException {
try {
- // create a test profile
- testAgent.registerService("FORCED_SELF", IProfileRegistry.SELF);
- testAgent.registerService(IAgentLocation.SERVICE_NAME, new AgentLocation(
- Files.createTempDirectory(
- CertificateCheckerTest.class.getName() + "testPGPSignedArtifactTrustedKey-profile")
- .toUri()));
- testAgent.getService(IProfileRegistry.class).addProfile(IProfileRegistry.SELF,
- Map.of(CertificateChecker.TRUSTED_KEY_STORE_PROPERTY, PGP_PUBLIC_KEY));
-
unsigned = TestData.getFile("pgp/repoPGPOK/plugins", "blah_1.0.0.123456.jar");
ArtifactDescriptor artifactDescriptor = new ArtifactDescriptor(
new ArtifactKey("what", "ever", Version.create("1")));
- artifactDescriptor.addProperties(
- Map.of(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME, PGP_SIGNATURE));
+ artifactDescriptor
+ .addProperties(Map.of(PGPSignatureVerifier.PGP_SIGNATURES_PROPERTY_NAME, PGP_SIGNER2_SIGNATURE,
+ PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME, PGP_SIGNER2_PUBLIC_KEY));
checker.add(Map.of(artifactDescriptor, unsigned));
System.getProperties().setProperty(EngineActivator.PROP_UNSIGNED_POLICY, EngineActivator.UNSIGNED_PROMPT);
IStatus result = checker.start();
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/GeneratorTests.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/GeneratorTests.java
index 4cd3e61c3..e09e8bc4d 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/GeneratorTests.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/generator/GeneratorTests.java
@@ -27,7 +27,9 @@ import org.eclipse.equinox.p2.publisher.eclipse.FeaturesAndBundlesPublisherAppli
import org.eclipse.equinox.p2.publisher.eclipse.InstallPublisherApplication;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
-import org.eclipse.equinox.p2.tests.*;
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+import org.eclipse.equinox.p2.tests.StringBufferStream;
+import org.eclipse.equinox.p2.tests.TestActivator;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -90,7 +92,7 @@ public class GeneratorTests extends AbstractProvisioningTest {
for (int i = 0; i < limit; i++) {
BundleContext context = TestActivator.getContext();
Bundle bundle = context.getBundle(i);
- File bundleFile = FileLocator.getBundleFile(bundle);
+ File bundleFile = FileLocator.getBundleFileLocation(bundle).get();
if (!bundleFile.isFile()) {
//only jars please
++limit;
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/MetadataRepositoryManagerTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/MetadataRepositoryManagerTest.java
index 22f8f9150..6ac039147 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/MetadataRepositoryManagerTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/metadata/repository/MetadataRepositoryManagerTest.java
@@ -387,17 +387,14 @@ public class MetadataRepositoryManagerTest extends AbstractProvisioningTest {
IAgentLocation agentLocation = ServiceHelper.getService(TestActivator.getContext(), IAgentLocation.class);
URI dataArea = agentLocation.getDataArea("org.eclipse.equinox.p2.repository/cache/");
File dataAreaFile = URIUtil.toFile(dataArea);
- File cacheFileXML = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".xml");
- File cacheFileJAR = new File(dataAreaFile, "content" + repoLocation.hashCode() + ".jar");
- File cacheFile;
+ File cacheFile = new File(dataAreaFile,
+ Integer.toString(URIUtil.append(repoLocation, "content.xml.xz").hashCode())); // as implemented in
+ // XZedSimpleMetadataRepository
+ // and CacheManager
// load a remote repository and check that a local cache was created
manager.loadRepository(repoLocation, null);
- assertTrue("Cache file was not created.", cacheFileXML.exists() || cacheFileJAR.exists());
- if (cacheFileXML.exists())
- cacheFile = cacheFileXML;
- else
- cacheFile = cacheFileJAR;
+ assertTrue("Cache file was not created.", cacheFile.exists());
// modify the last modified date to be older than the remote file
cacheFile.setLastModified(0);
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/MetadataMirrorApplicationTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/MetadataMirrorApplicationTest.java
index 004b5db20..94bdec524 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/MetadataMirrorApplicationTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/MetadataMirrorApplicationTest.java
@@ -14,7 +14,9 @@
package org.eclipse.equinox.p2.tests.mirror;
import java.io.File;
-import java.net.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository;
@@ -516,7 +518,7 @@ public class MetadataMirrorApplicationTest extends AbstractProvisioningTest {
public void testMetadataMirrorToInvalid() {
URI invalidDestRepository;
try {
- invalidDestRepository = new URI("http://eclipse.org/equinox/foobar/abcdefg");
+ invalidDestRepository = new URI("https://eclipse.org/equinox/foobar/abcdefg");
basicRunMirrorApplication("14.1", sourceRepoLocation.toURL(), invalidDestRepository.toURL(), true);
//we expect an illegal state exception to be thrown and should never get here
fail("14.0 IllegalStateExpection not thrown");
@@ -535,7 +537,7 @@ public class MetadataMirrorApplicationTest extends AbstractProvisioningTest {
delete(invalidRepository);
try {
- URI invalidDestRepository = new URI("http://eclipse.org/equinox/foobar/abcdefg");
+ URI invalidDestRepository = new URI("https://eclipse.org/equinox/foobar/abcdefg");
basicRunMirrorApplication("15.1", invalidRepository.toURL(), invalidDestRepository.toURL(), true);
//we expect a provisioning exception to be thrown and should never get here
fail("15.0 ProvisionExpection not thrown");
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java
index 173bb4ca0..4d8c2ac71 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/mirror/NewMirrorApplicationMetadataTest.java
@@ -14,8 +14,12 @@
package org.eclipse.equinox.p2.tests.mirror;
import java.io.File;
-import java.net.*;
-import java.util.*;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository;
import org.eclipse.equinox.internal.simpleconfigurator.utils.URIUtil;
import org.eclipse.equinox.p2.core.ProvisionException;
@@ -551,7 +555,7 @@ public class NewMirrorApplicationMetadataTest extends AbstractProvisioningTest {
public void testMetadataMirrorToInvalid() {
URI invalidDestRepository = null;
try {
- invalidDestRepository = new URI("http://eclipse.org/equinox/foobar/abcdefg");
+ invalidDestRepository = new URI("https://eclipse.org/equinox/foobar/abcdefg");
basicRunMirrorApplication("14.1", sourceRepoLocation.toURL(), invalidDestRepository.toURL(), true);
//we expect an illegal state exception to be thrown and should never get here
fail("14.0 IllegalStateExpection not thrown");
@@ -574,7 +578,7 @@ public class NewMirrorApplicationMetadataTest extends AbstractProvisioningTest {
delete(invalidRepository);
try {
- URI invalidDestRepository = new URI("http://eclipse.org/equinox/foobar/abcdefg");
+ URI invalidDestRepository = new URI("https://eclipse.org/equinox/foobar/abcdefg");
basicRunMirrorApplication("15.1", invalidRepository.toURL(), invalidDestRepository.toURL(), true);
//we expect a provisioning exception to be thrown and should never get here
fail("15.0 ProvisionExpection not thrown");
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
index bb92cf4ef..d6085fd8a 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ANYConfigCUsActionTest.java
@@ -14,13 +14,17 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.expect;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.matches;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.easymock.EasyMock;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.publisher.eclipse.DataLoader;
@@ -212,7 +216,8 @@ public class ANYConfigCUsActionTest extends ActionTest {
fail("Unable to create product file advice", e); //$NON-NLS-1$
}
- expect(publisherInfo.getAdvice(EasyMock.matches(configSpec), EasyMock.eq(false), (String) EasyMock.anyObject(), (Version) EasyMock.anyObject(), EasyMock.eq(IExecutableAdvice.class))).andReturn(launchingList).anyTimes();
+ when(publisherInfo.getAdvice(matches(configSpec), eq(false), anyString(), any(Version.class),
+ eq(IExecutableAdvice.class))).thenReturn(launchingList);
//configure IConfigAdvice
ConfigData configData = loader.getConfigData();
@@ -220,14 +225,15 @@ public class ANYConfigCUsActionTest extends ActionTest {
ArrayList<IConfigAdvice> configList = new ArrayList<>();
configList.add(configAdvice);
configList.add(productAdvice);
- expect(publisherInfo.getAdvice(EasyMock.matches(configSpec), EasyMock.eq(false), (String) EasyMock.anyObject(), (Version) EasyMock.anyObject(), EasyMock.eq(IConfigAdvice.class))).andReturn(configList).anyTimes();
+ when(publisherInfo.getAdvice(matches(configSpec), eq(false), anyString(), any(Version.class),
+ eq(IConfigAdvice.class))).thenReturn(configList);
//setup metadata repository
IInstallableUnit[] ius = {mockIU("foo", null), mockIU("bar", null)}; //$NON-NLS-1$ //$NON-NLS-2$
metadataRepo = new TestMetadataRepository(getAgent(), ius);
- expect(publisherInfo.getMetadataRepository()).andReturn(metadataRepo).anyTimes();
- expect(publisherInfo.getContextMetadataRepository()).andReturn(null).anyTimes();
+ when(publisherInfo.getMetadataRepository()).thenReturn(metadataRepo);
+ when(publisherInfo.getContextMetadataRepository()).thenReturn(null);
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AccumulateConfigDataActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AccumulateConfigDataActionTest.java
index 480303b82..ffe6009d5 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AccumulateConfigDataActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AccumulateConfigDataActionTest.java
@@ -15,21 +15,25 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
+import static org.mockito.Mockito.verify;
+
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Map;
-import org.easymock.Capture;
-import org.easymock.EasyMock;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.provisional.frameworkadmin.ConfigData;
+import org.eclipse.equinox.p2.publisher.IPublisherAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.AccumulateConfigDataAction;
import org.eclipse.equinox.p2.publisher.eclipse.ConfigAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.LaunchingAdvice;
import org.eclipse.equinox.p2.tests.TestActivator;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
public class AccumulateConfigDataActionTest extends ActionTest {
@@ -43,13 +47,11 @@ public class AccumulateConfigDataActionTest extends ActionTest {
private static String launcherName = "launcherName"; //$NON-NLS-1$
private static String launcherVersion = "0.0.0"; //$NON-NLS-1$
- Capture<ConfigAdvice> configAdviceCapture;
- Capture<LaunchingAdvice> launchingAdviceCapture;
+ ArgumentCaptor<IPublisherAdvice> capture;
@Override
public void setUp() throws Exception {
- configAdviceCapture = Capture.newInstance();
- launchingAdviceCapture = Capture.newInstance();
+ capture = ArgumentCaptor.forClass(IPublisherAdvice.class);
setupPublisherInfo();
setupPublisherResult();
testAction = new AccumulateConfigDataAction(publisherInfo, configSpec, configLocation, executableLocation);
@@ -57,13 +59,15 @@ public class AccumulateConfigDataActionTest extends ActionTest {
public void testAccumulateConfigDataAction() throws Exception {
testAction.perform(publisherInfo, publisherResult, new NullProgressMonitor());
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(capture.capture());
verifyConfigAdvice();
verifyLaunchAdvice();
debug("Completed AccumulateConfigDataActionTest."); //$NON-NLS-1$
}
private void verifyLaunchAdvice() throws URISyntaxException {
- LaunchingAdvice captured = launchingAdviceCapture.getValue();
+ LaunchingAdvice captured = (LaunchingAdvice) capture.getAllValues().stream()
+ .filter(LaunchingAdvice.class::isInstance).collect(Collectors.toList()).get(0);
String[] programArgs = captured.getProgramArguments();
assertTrue(programArgs.length == 4);
assertTrue(programArgs[0].equalsIgnoreCase("-startup")); //$NON-NLS-1$
@@ -81,7 +85,8 @@ public class AccumulateConfigDataActionTest extends ActionTest {
}
private void verifyConfigAdvice() throws Exception {
- ConfigAdvice captured = configAdviceCapture.getValue();
+ ConfigAdvice captured = (ConfigAdvice) capture.getAllValues().stream().filter(ConfigAdvice.class::isInstance)
+ .collect(Collectors.toList()).get(0);
Map<String, String> prop = captured.getProperties();
assertTrue(prop.get("eclipse.buildId").equalsIgnoreCase("TEST-ID")); //$NON-NLS-1$ //$NON-NLS-2$
assertTrue(prop.get("eclipse.p2.profile").equalsIgnoreCase("PlatformProfile")); //$NON-NLS-1$//$NON-NLS-2$
@@ -109,8 +114,5 @@ public class AccumulateConfigDataActionTest extends ActionTest {
ConfigAdvice configAdvice = new ConfigAdvice(configData, configSpec);
ArrayList<ConfigAdvice> configList = new ArrayList<>();
configList.add(configAdvice);
-
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(ConfigAdvice.class), EasyMock.capture(configAdviceCapture)));
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(LaunchingAdvice.class), EasyMock.capture(launchingAdviceCapture)));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
index 1741c7878..25290d337 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ActionTest.java
@@ -14,10 +14,9 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -118,9 +117,9 @@ public abstract class ActionTest extends AbstractProvisioningTest {
for (IRequirement act : actual) {
if (expected.getMatches().equals(act.getMatches())) {
String descr = "IRequirement " + expected.getMatches();
- Assert.assertEquals("Min of " + descr, expected.getMin(), act.getMin());
- Assert.assertEquals("Max of " + descr, expected.getMax(), act.getMax());
- Assert.assertEquals("Greedy of " + descr, expected.isGreedy(), act.isGreedy());
+ assertEquals("Min of " + descr, expected.getMin(), act.getMin());
+ assertEquals("Max of " + descr, expected.getMax(), act.getMax());
+ assertEquals("Greedy of " + descr, expected.isGreedy(), act.isGreedy());
return;
}
}
@@ -128,13 +127,12 @@ public abstract class ActionTest extends AbstractProvisioningTest {
}
protected IInstallableUnit mockIU(String id, Version version) {
- IInstallableUnit result = createMock(IInstallableUnit.class);
- expect(result.getId()).andReturn(id).anyTimes();
+ IInstallableUnit result = mock(IInstallableUnit.class);
+ when(result.getId()).thenReturn(id);
if (version == null)
version = Version.emptyVersion;
- expect(result.getVersion()).andReturn(version).anyTimes();
- expect(result.getFilter()).andReturn(null).anyTimes();
- replay(result);
+ when(result.getVersion()).thenReturn(version);
+ when(result.getFilter()).thenReturn(null);
return result;
}
@@ -170,31 +168,20 @@ public abstract class ActionTest extends AbstractProvisioningTest {
* Call this method to setup Publisher Info, not <code>insertPublisherInfoBehavior</code>
*/
public void setupPublisherInfo() {
- publisherInfo = createPublisherInfoMock();
+ publisherInfo = mock(IPublisherInfo.class);
String[] config = getArrayFromString(configSpec, COMMA_SEPARATOR);
- expect(publisherInfo.getConfigurations()).andReturn(config).anyTimes();
+ when(publisherInfo.getConfigurations()).thenReturn(config);
insertPublisherInfoBehavior();
- replay(publisherInfo);
- }
-
- /**
- * Creates the mock object for the IPublisherInfo. Subclasses
- * can override to create a nice or strict mock instead.
- * @return The publisher info mock
- * @see org.easymock.EasyMock#createNiceMock(Class)
- * @see org.easymock.EasyMock#createStrictMock(Class)
- */
- protected IPublisherInfo createPublisherInfoMock() {
- return createMock(IPublisherInfo.class);
}
/**
* Do not call this method, it is called by <code>setupPublisherInfo</code>.
*/
protected void insertPublisherInfoBehavior() {
- expect(publisherInfo.getMetadataRepository()).andReturn(createTestMetdataRepository(new IInstallableUnit[0])).anyTimes();
- expect(publisherInfo.getContextMetadataRepository()).andReturn(createTestMetdataRepository(new IInstallableUnit[0])).anyTimes();
+ when(publisherInfo.getMetadataRepository()).thenReturn(createTestMetdataRepository(new IInstallableUnit[0]));
+ when(publisherInfo.getContextMetadataRepository())
+ .thenReturn(createTestMetdataRepository(new IInstallableUnit[0]));
}
public void cleanup() {
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AdviceMatcher.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AdviceMatcher.java
deleted file mode 100644
index f23e1f53b..000000000
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/AdviceMatcher.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.p2.tests.publisher.actions;
-
-import org.easymock.EasyMock;
-import org.easymock.IArgumentMatcher;
-import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.publisher.IPublisherAdvice;
-
-/**
- * A matcher that matches advice applicable to a given id and version.
- */
-public class AdviceMatcher implements IArgumentMatcher {
- private final Version version;
- private final String id;
- private static Class<?> clazz;
-
- public static IPublisherAdvice adviceMatches(String id, Version version, Class<?> clazz) {
- AdviceMatcher.clazz = clazz;
- EasyMock.reportMatcher(new AdviceMatcher(id, version));
- return null;
- }
-
- public AdviceMatcher(String id, Version version) {
- this.id = id;
- this.version = version;
- }
-
- @Override
- public void appendTo(StringBuffer buf) {
- buf.append("AdviceMatcher[" + id + ',' + version + ']');
- }
-
- @Override
- public boolean matches(Object arg) {
- if (!(arg instanceof IPublisherAdvice))
- return false;
- if (!(clazz.isAssignableFrom(arg.getClass())))
- return false;
- IPublisherAdvice advice = (IPublisherAdvice) arg;
- return advice.isApplicable("", false, id, version);
- }
-}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
index 72bde8105..fd95c834b 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/BundlesActionTest.java
@@ -16,15 +16,16 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.and;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.errorStatus;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.statusWithMessageWhich;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.BufferedInputStream;
import java.io.File;
@@ -39,9 +40,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipInputStream;
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.easymock.EasyMock;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
@@ -60,6 +58,7 @@ import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
+import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.publisher.AbstractPublisherApplication;
import org.eclipse.equinox.p2.publisher.AdviceFileAdvice;
import org.eclipse.equinox.p2.publisher.IPublisherInfo;
@@ -80,6 +79,8 @@ import org.eclipse.equinox.p2.tests.TestActivator;
import org.eclipse.equinox.p2.tests.TestData;
import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
public class BundlesActionTest extends ActionTest {
private static final String OSGI = PublisherHelper.OSGI_BUNDLE_CLASSIFIER;
@@ -143,39 +144,27 @@ public class BundlesActionTest extends ActionTest {
private static final VersionRange TEST1_IU_D_VERSION_RANGE = VersionRange.create("1.3.0");//$NON-NLS-1$
protected TestArtifactRepository artifactRepository = new TestArtifactRepository(getAgent());
-
- private Capture<ITouchpointAdvice> tpAdvice1, tpAdvice2;
- private Capture<IUpdateDescriptorAdvice> udAdvice3;
- private Capture<ICapabilityAdvice> capAdvice5;
-
- @Override
- public void setupPublisherInfo() {
- tpAdvice1 = Capture.newInstance(CaptureType.ALL);
- tpAdvice2 = Capture.newInstance(CaptureType.ALL);
-
- udAdvice3 = Capture.newInstance(CaptureType.ALL);
- capAdvice5 = Capture.newInstance(CaptureType.ALL);
-
- super.setupPublisherInfo();
- }
+ private ArgumentCaptor<AdviceFileAdvice> updateDescriptorCapture;
public void testAll() throws Exception {
File[] files = TEST_BASE.listFiles();
- testAction = new BundlesAction(files);
+ testAction = Mockito.spy(new BundlesAction(files));
setupPublisherResult();
setupPublisherInfo();
artifactRepository.setProperty(AbstractPublisherApplication.PUBLISH_PACK_FILES_AS_SIBLINGS, "true");//$NON-NLS-1$
+ updateDescriptorCapture = ArgumentCaptor.forClass(AdviceFileAdvice.class);
+ IStatus status = testAction.perform(publisherInfo, publisherResult, new NullProgressMonitor());
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(updateDescriptorCapture.capture());
+ assertEquals(Status.OK_STATUS, status);
- assertEquals(Status.OK_STATUS, testAction.perform(publisherInfo, publisherResult, new NullProgressMonitor()));
verifyBundlesAction();
cleanup();
- debug("Completed BundlesActionTest.");//$NON-NLS-1$
}
public void testTranslationFragment() {
File foo_fragment = new File(TestActivator.getTestDataFolder(), "FragmentPublisherTest/foo.fragment");//$NON-NLS-1$
File foo = new File(TestActivator.getTestDataFolder(), "FragmentPublisherTest/foo");//$NON-NLS-1$
- BundlesAction bundlesAction = new BundlesAction(new File[] {foo_fragment});
+ BundlesAction bundlesAction = new BundlesAction(new File[] { foo_fragment });
PublisherInfo info = new PublisherInfo();
PublisherResult results = new PublisherResult();
@@ -185,7 +174,7 @@ public class BundlesActionTest extends ActionTest {
info = new PublisherInfo();
results = new PublisherResult();
- bundlesAction = new BundlesAction(new File[] {foo});
+ bundlesAction = new BundlesAction(new File[] { foo });
bundlesAction.perform(info, results, new NullProgressMonitor());
ius = results.getIUs(null, null);
assertEquals(1, ius.size());
@@ -197,7 +186,7 @@ public class BundlesActionTest extends ActionTest {
utils.setTranslationSource(queryableArray);
assertEquals("English Foo", utils.getIUProperty(iu, IInstallableUnit.PROP_NAME));
- bundlesAction = new BundlesAction(new File[] {foo_fragment});
+ bundlesAction = new BundlesAction(new File[] { foo_fragment });
bundlesAction.perform(info, results, new NullProgressMonitor());
ius = results.getIUs(null, null);
assertEquals(3, ius.size());
@@ -238,7 +227,8 @@ public class BundlesActionTest extends ActionTest {
canonicalIdx = 0;
}
- try (ZipInputStream actual = artifactRepository.getZipInputStream(descriptors[canonicalIdx]); ZipInputStream expected = new ZipInputStream(new FileInputStream(TEST_FILE2))) {
+ try (ZipInputStream actual = artifactRepository.getZipInputStream(descriptors[canonicalIdx]);
+ ZipInputStream expected = new ZipInputStream(new FileInputStream(TEST_FILE2))) {
TestData.assertEquals(expected, actual);
}
@@ -248,12 +238,14 @@ public class BundlesActionTest extends ActionTest {
IArtifactKey key1 = ArtifactKey.parse("osgi.bundle,test1,0.1.0");//$NON-NLS-1$
ZipInputStream zis = artifactRepository.getZipInputStream(key1);
- Map<String, Object[]> fileMap = getFileMap(new HashMap<>(), new File[] {TEST_FILE1}, new Path(TEST_FILE1.getAbsolutePath()));
+ Map<String, Object[]> fileMap = getFileMap(new HashMap<>(), new File[] { TEST_FILE1 },
+ new Path(TEST_FILE1.getAbsolutePath()));
TestData.assertContains(fileMap, zis, true);
}
private void verifyBundle1() {
- List<IInstallableUnit> ius = new ArrayList<>(publisherResult.getIUs(TEST1_PROVBUNDLE_NAME, IPublisherResult.ROOT));
+ List<IInstallableUnit> ius = new ArrayList<>(
+ publisherResult.getIUs(TEST1_PROVBUNDLE_NAME, IPublisherResult.ROOT));
assertEquals(1, ius.size());
IInstallableUnit bundle1IU = ius.get(0);
@@ -272,25 +264,28 @@ public class BundlesActionTest extends ActionTest {
verifyProvidedCapability(providedCapabilities, OSGI_IDENTITY, TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION);
verifyProvidedCapability(providedCapabilities, OSGI, TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION);
verifyProvidedCapability(providedCapabilities, TEST1_PROV_Z_NAMESPACE, TEST1_PROVZ_NAME, TEST2_PROVZ_VERSION);
- verifyProvidedCapability(providedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "source", Version.create("1.0.0"));//$NON-NLS-1$//$NON-NLS-2$
+ verifyProvidedCapability(providedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "source", //$NON-NLS-1$
+ Version.create("1.0.0"));//$NON-NLS-1$
assertEquals(5, providedCapabilities.size());
- Collection<ITouchpointData> data = bundle1IU.getTouchpointData();
+ List<AdviceFileAdvice> tData = updateDescriptorCapture.getAllValues();
boolean found = false;
- for (ITouchpointData td : data) {
- ITouchpointInstruction configure = td.getInstruction("configure");
- if (configure == null)
- continue;
- String body = configure.getBody();
- if (body != null && body.indexOf("download.eclipse.org/releases/ganymede") > 0) {
- found = true;
+ for (AdviceFileAdvice iTouchpointAdvice : tData) {
+ ITouchpointInstruction configure = iTouchpointAdvice.getTouchpointData(NO_TP_DATA)
+ .getInstruction("configure");
+ if (configure != null) {
+ String body = configure.getBody();
+ if (body != null && body.indexOf("download.eclipse.org/releases/ganymede") > 0) {
+ found = true;
+ }
}
}
assertTrue(found);
}
private void verifyBundle2() {
- List<IInstallableUnit> ius = new ArrayList<>(publisherResult.getIUs(TEST2_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
+ List<IInstallableUnit> ius = new ArrayList<>(
+ publisherResult.getIUs(TEST2_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
assertEquals(1, ius.size());
IInstallableUnit bundleIu = ius.get(0);
@@ -307,14 +302,16 @@ public class BundlesActionTest extends ActionTest {
// check provided capabilities
Collection<IProvidedCapability> providedCapabilities = bundleIu.getProvidedCapabilities();
- verifyProvidedCapability(providedCapabilities, PROVBUNDLE_NAMESPACE, TEST2_PROV_BUNDLE_NAME, PROVBUNDLE2_VERSION);
+ verifyProvidedCapability(providedCapabilities, PROVBUNDLE_NAMESPACE, TEST2_PROV_BUNDLE_NAME,
+ PROVBUNDLE2_VERSION);
verifyProvidedCapability(providedCapabilities, OSGI, TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION);
verifyProvidedCapability(providedCapabilities, OSGI_IDENTITY, TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION);
verifyProvidedCapability(providedCapabilities, TEST2_PROV_Z_NAMESPACE, TEST2_PROV_Z_NAME, TEST2_PROVZ_VERSION);
verifyProvidedCapability(providedCapabilities, TEST2_PROV_Y_NAMESPACE, TEST2_PROV_Y_NAME, TEST2_PROVY_VERSION);
verifyProvidedCapability(providedCapabilities, TEST2_PROV_X_NAMESPACE, TEST2_PROV_X_NAME, TEST2_PROVX_VERSION);
- verifyProvidedCapability(providedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "bundle", Version.create("1.0.0"));//$NON-NLS-1$//$NON-NLS-2$
- assertEquals(7, providedCapabilities.size()); /*number of tested elements*/
+ verifyProvidedCapability(providedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "bundle", //$NON-NLS-1$
+ Version.create("1.0.0"));//$NON-NLS-1$
+ assertEquals(7, providedCapabilities.size()); /* number of tested elements */
// check %bundle name is correct
Map<String, String> prop = bundleIu.getProperties();
@@ -336,27 +333,41 @@ public class BundlesActionTest extends ActionTest {
}
private void verifyBundle3() {
- // also a regression test for bug 393051: manifest headers use uncommon (but valid) capitalization
- ArrayList<IInstallableUnit> ius = new ArrayList<>(publisherResult.getIUs(TEST3_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
+ // also a regression test for bug 393051: manifest headers use uncommon (but
+ // valid) capitalization
+ ArrayList<IInstallableUnit> ius = new ArrayList<>(
+ publisherResult.getIUs(TEST3_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
assertEquals(1, ius.size());
-
- IInstallableUnit bundleIu = ius.get(0);
-
- IUpdateDescriptor updateDescriptor = bundleIu.getUpdateDescriptor();
- String name = RequiredCapability.extractName(updateDescriptor.getIUsBeingUpdated().iterator().next());
+ IUpdateDescriptor updateDescriptor = null;
+ boolean found = false;
+ for (AdviceFileAdvice advice : updateDescriptorCapture.getAllValues()) {
+ IUpdateDescriptor descriptor = advice.getUpdateDescriptor(new InstallableUnitDescription());
+ if (descriptor != null) {
+ Collection<IMatchExpression<IInstallableUnit>> iUsBeingUpdated = descriptor.getIUsBeingUpdated();
+ if (iUsBeingUpdated != null) {
+ String name = RequiredCapability.extractName(descriptor.getIUsBeingUpdated().iterator().next());
+ if (TEST3_PROV_BUNDLE_NAME.equals(name)) {
+ updateDescriptor = descriptor;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ assertTrue(found);
VersionRange range = RequiredCapability.extractRange(updateDescriptor.getIUsBeingUpdated().iterator().next());
String description = updateDescriptor.getDescription();
int severity = updateDescriptor.getSeverity();
VersionRange expectedRange = new VersionRange("(0.0.1," + BUNDLE3_VERSION + "]");
- assertEquals(TEST3_PROV_BUNDLE_NAME, name);
assertEquals(expectedRange, range);
assertEquals("Some description about this update", description.trim());
assertEquals(8, severity);
}
private void verifyBundle4() {
- ArrayList<IInstallableUnit> ius = new ArrayList<>(publisherResult.getIUs(TEST4_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
+ ArrayList<IInstallableUnit> ius = new ArrayList<>(
+ publisherResult.getIUs(TEST4_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
assertEquals(1, ius.size());
IInstallableUnit bundleIu = ius.get(0);
@@ -365,23 +376,29 @@ public class BundlesActionTest extends ActionTest {
// check required capabilities
Collection<IRequirement> requirements = bundleIu.getRequirements();
- verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, false);
- verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, true);
+ verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, null, 0,
+ 1, false);
+ verifyRequirement(requirements, JAVA_PACKAGE, TEST4_REQ_PACKAGE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, null, 0,
+ 1, true);
verifyRequirement(requirements, OSGI, TEST4_REQ_BUNDLE_OPTIONAL_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, false);
verifyRequirement(requirements, OSGI, TEST4_REQ_BUNDLE_OPTGREEDY_NAME, DEFAULT_VERSION_RANGE, null, 0, 1, true);
assertEquals(4, requirements.size());
}
private void verifyBundle5() {
- ArrayList<IInstallableUnit> ius = new ArrayList<>(publisherResult.getIUs(TEST5_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
+ ArrayList<IInstallableUnit> ius = new ArrayList<>(
+ publisherResult.getIUs(TEST5_PROV_BUNDLE_NAME, IPublisherResult.ROOT));
assertEquals(1, ius.size());
IInstallableUnit bundle5IU = ius.get(0);
-
+ for (AdviceFileAdvice adv : updateDescriptorCapture.getAllValues()) {
+ IRequirement[] reqs = adv.getRequiredCapabilities(new InstallableUnitDescription());
+ if (reqs != null) {
+ verifyRequirement(List.of(reqs), "bar", "foo", VersionRange.emptyRange, null, 6, 7, true);
+ }
+ }
Collection<IRequirement> requirements = bundle5IU.getRequirements();
verifyRequirement(requirements, OSGI_EE, TEST5_REQ_EE, null, 1, 1, true);
- verifyRequirement(requirements, "bar", "foo", VersionRange.emptyRange, null, 6, 7, true);
- assertEquals(2, requirements.size());
}
@Override
@@ -395,7 +412,8 @@ public class BundlesActionTest extends ActionTest {
@Override
protected void insertPublisherInfoBehavior() {
- //super sets publisherInfo.getMetadataRepository and publisherInfo.getContextMetadataRepository
+ // super sets publisherInfo.getMetadataRepository and
+ // publisherInfo.getContextMetadataRepository
super.insertPublisherInfoBehavior();
Map<String, String> sarProperties = new HashMap<>();
sarProperties.put("key1", "value1");//$NON-NLS-1$//$NON-NLS-2$
@@ -405,23 +423,21 @@ public class BundlesActionTest extends ActionTest {
sdkProperties.put("key1", "value1");//$NON-NLS-1$//$NON-NLS-2$
sdkProperties.put("key2", "value2");//$NON-NLS-1$//$NON-NLS-2$
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH).anyTimes();
- expect(publisherInfo.getAdvice(null, false, null, null, ICapabilityAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getArtifactOptions())
+ .thenReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH);
+ when(publisherInfo.getAdvice(null, false, null, null, ICapabilityAdvice.class)).thenReturn(new ArrayList<>());
expectOtherAdviceQueries(TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION);
expectPropertyAdviceQuery(TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION, sarProperties);
expectUpdateDescriptorAdviceQuery(TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION, null);
- expectTouchpointAdviceQuery(TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION, tpAdvice1.getValues());
expectOtherAdviceQueries(TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION);
expectPropertyAdviceQuery(TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION, sdkProperties);
expectUpdateDescriptorAdviceQuery(TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION, null);
- expectTouchpointAdviceQuery(TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION, tpAdvice2.getValues());
expectOtherAdviceQueries(TEST3_PROV_BUNDLE_NAME, BUNDLE3_VERSION);
expectPropertyAdviceQuery(TEST3_PROV_BUNDLE_NAME, BUNDLE3_VERSION, sarProperties);
- expectUpdateDescriptorAdviceQuery(TEST3_PROV_BUNDLE_NAME, BUNDLE3_VERSION, udAdvice3.getValues());
expectTouchpointAdviceQuery(TEST3_PROV_BUNDLE_NAME, BUNDLE3_VERSION, null);
expectOtherAdviceQueries(TEST4_PROV_BUNDLE_NAME, BUNDLE4_VERSION);
@@ -429,49 +445,43 @@ public class BundlesActionTest extends ActionTest {
expectUpdateDescriptorAdviceQuery(TEST4_PROV_BUNDLE_NAME, BUNDLE4_VERSION, null);
expectTouchpointAdviceQuery(TEST4_PROV_BUNDLE_NAME, BUNDLE4_VERSION, null);
- expectCapabilityAdviceQuery(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, capAdvice5.getValues());
+// expectCapabilityAdviceQuery(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, capAdvice5.getValues());
expectOtherAdviceQueries(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION);
expectPropertyAdviceQuery(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, sarProperties);
expectUpdateDescriptorAdviceQuery(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, null);
expectTouchpointAdviceQuery(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, null);
- //capture any touchpoint advice, and return the captured advice when the action asks for it
- publisherInfo.addAdvice(and(AdviceMatcher.adviceMatches(TEST1_PROVBUNDLE_NAME, BUNDLE1_VERSION, ITouchpointAdvice.class), capture(tpAdvice1)));
- EasyMock.expectLastCall().anyTimes();
-
- publisherInfo.addAdvice(and(AdviceMatcher.adviceMatches(TEST2_PROV_BUNDLE_NAME, BUNDLE2_VERSION, ITouchpointAdvice.class), capture(tpAdvice2)));
- EasyMock.expectLastCall().anyTimes();
-
- publisherInfo.addAdvice(and(AdviceMatcher.adviceMatches(TEST3_PROV_BUNDLE_NAME, BUNDLE3_VERSION, AdviceFileAdvice.class), capture(udAdvice3)));
-
- publisherInfo.addAdvice(and(AdviceMatcher.adviceMatches(TEST5_PROV_BUNDLE_NAME, BUNDLE5_VERSION, AdviceFileAdvice.class), capture(capAdvice5)));
- EasyMock.expectLastCall().anyTimes();
}
private void expectOtherAdviceQueries(String bundleName, Version bundleVersion) {
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ICapabilityAdvice.class))
- .andReturn(Collections.emptyList());
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IAdditionalInstallableUnitAdvice.class))
- .andReturn(Collections.emptyList());
- expect(publisherInfo.getAdvice(null, true, bundleName, bundleVersion, IBundleShapeAdvice.class)).andReturn(null);
+ when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ICapabilityAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IAdditionalInstallableUnitAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, true, bundleName, bundleVersion, IBundleShapeAdvice.class)).thenReturn(null);
}
- private void expectCapabilityAdviceQuery(String bundleName, Version bundleVersion, Collection<ICapabilityAdvice> answer) {
- if (answer == null)
- answer = Collections.emptyList();
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ICapabilityAdvice.class)).andReturn(answer);
- }
+// private void expectCapabilityAdviceQuery(String bundleName, Version bundleVersion,
+// Collection<ICapabilityAdvice> answer) {
+// if (answer == null)
+// answer = Collections.emptyList();
+// when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ICapabilityAdvice.class))
+// .thenReturn(answer);
+// }
- private void expectUpdateDescriptorAdviceQuery(String bundleName, Version bundleVersion, Collection<IUpdateDescriptorAdvice> answer) {
+ private void expectUpdateDescriptorAdviceQuery(String bundleName, Version bundleVersion,
+ Collection<IUpdateDescriptorAdvice> answer) {
if (answer == null)
answer = Collections.emptyList();
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IUpdateDescriptorAdvice.class)).andReturn(answer);
+ when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IUpdateDescriptorAdvice.class))
+ .thenReturn(answer);
}
- private void expectTouchpointAdviceQuery(String bundleName, Version bundleVersion, Collection<ITouchpointAdvice> answer) {
+ private void expectTouchpointAdviceQuery(String bundleName, Version bundleVersion, List<ITouchpointAdvice> answer) {
if (answer == null)
answer = Collections.emptyList();
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ITouchpointAdvice.class)).andReturn(answer).anyTimes();
+ when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, ITouchpointAdvice.class))
+ .thenReturn(answer);
}
private void expectPropertyAdviceQuery(String bundleName, Version bundleVersion, Map<String, String> answer) {
@@ -480,20 +490,22 @@ public class BundlesActionTest extends ActionTest {
propertyAdvices = Collections.singletonList(createPropertyAdvice(answer));
else
propertyAdvices = Collections.emptyList();
- expect(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IPropertyAdvice.class)).andReturn(propertyAdvices).times(2);
+ when(publisherInfo.getAdvice(null, false, bundleName, bundleVersion, IPropertyAdvice.class))
+ .thenReturn(propertyAdvices);
}
private IPropertyAdvice createPropertyAdvice(Map<String, String> properties) {
- IPropertyAdvice mockAdvice = EasyMock.createMock(IPropertyAdvice.class);
- expect(mockAdvice.getInstallableUnitProperties((InstallableUnitDescription) EasyMock.anyObject())).andReturn(null).anyTimes();
- expect(mockAdvice.getArtifactProperties((IInstallableUnit) EasyMock.anyObject(), (IArtifactDescriptor) EasyMock.anyObject())).andReturn(properties).anyTimes();
- EasyMock.replay(mockAdvice);
+ IPropertyAdvice mockAdvice = mock(IPropertyAdvice.class);
+ when(mockAdvice.getInstallableUnitProperties(any(InstallableUnitDescription.class))).thenReturn(null);
+ when(mockAdvice.getArtifactProperties(any(IInstallableUnit.class), any(IArtifactDescriptor.class)))
+ .thenReturn(properties);
return mockAdvice;
}
public void testDynamicImport() throws Exception {
File testData = getTestData("dymamicImport", "testData/dynamicImport");
- IInstallableUnit iu = BundlesAction.createBundleIU(BundlesAction.createBundleDescription(testData), null, new PublisherInfo());
+ IInstallableUnit iu = BundlesAction.createBundleIU(BundlesAction.createBundleDescription(testData), null,
+ new PublisherInfo());
Collection<IRequirement> requirements = iu.getRequirements();
verifyRequirement(requirements, OSGI_EE, TESTDYN_REQ_EE, null, 1, 1, true);
@@ -510,11 +522,13 @@ public class BundlesActionTest extends ActionTest {
// overall status shall be error...
assertThat(status, errorStatus());
List<IStatus> childStatuses = Arrays.asList(status.getChildren());
- assertThat(childStatuses, hasItem(statusWithMessageWhich(containsString("The manifest line \"foo\" is invalid; it has no colon ':' character after the header key."))));
+ assertThat(childStatuses, hasItem(statusWithMessageWhich(containsString(
+ "The manifest line \"foo\" is invalid; it has no colon ':' character after the header key."))));
assertThat(childStatuses.size(), is(1));
// ... but the valid bundle must still be published
- Collection<IInstallableUnit> ius = publisherResult.getIUs("org.eclipse.p2.test.validManifest", IPublisherResult.ROOT);
+ Collection<IInstallableUnit> ius = publisherResult.getIUs("org.eclipse.p2.test.validManifest",
+ IPublisherResult.ROOT);
assertThat(ius.size(), is(1));
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/CaptureList.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/CaptureList.java
deleted file mode 100644
index e317d621c..000000000
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/CaptureList.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008, 2017 IBM Corporation and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.equinox.p2.tests.publisher.actions;
-
-import java.util.AbstractList;
-import org.easymock.Capture;
-
-/**
- * An object that adapts an EasyMock Capture to a List.
- */
-public class CaptureList<E> extends AbstractList<E> {
- private Capture<E> capture;
-
- public CaptureList(Capture<E> capture) {
- this.capture = capture;
- }
-
- @Override
- public E get(int arg0) {
- return capture.getValue();
- }
-
- @Override
- public int size() {
- return capture.hasCaptured() ? 1 : 0;
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
index 24b6997bb..99afa871c 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ConfigCUsActionTest.java
@@ -15,13 +15,17 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.expect;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.matches;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.easymock.EasyMock;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.publisher.eclipse.DataLoader;
@@ -147,7 +151,8 @@ public class ConfigCUsActionTest extends ActionTest {
ConfigAdvice configAdvice = new ConfigAdvice(configData, configSpec);
ArrayList<IConfigAdvice> configList = new ArrayList<>();
configList.add(configAdvice);
- expect(publisherInfo.getAdvice(EasyMock.matches(configSpec), EasyMock.eq(false), (String) EasyMock.anyObject(), (Version) EasyMock.anyObject(), EasyMock.eq(IConfigAdvice.class))).andReturn(configList).anyTimes();
+ when(publisherInfo.getAdvice(matches(configSpec), eq(false), anyString(), any(Version.class),
+ eq(IConfigAdvice.class))).thenReturn(configList);
//configure IExecutableAdvice
LauncherData launcherData = loader.getLauncherData();
@@ -164,14 +169,15 @@ public class ConfigCUsActionTest extends ActionTest {
// TODO Auto-generated catch block
}
- expect(publisherInfo.getAdvice(EasyMock.matches(configSpec), EasyMock.eq(false), (String) EasyMock.anyObject(), (Version) EasyMock.anyObject(), EasyMock.eq(IExecutableAdvice.class))).andReturn(launchingList).anyTimes();
+ when(publisherInfo.getAdvice(matches(configSpec), eq(false), anyString(), any(Version.class),
+ eq(IExecutableAdvice.class))).thenReturn(launchingList);
//setup metadata repository
IInstallableUnit[] ius = {mockIU("foo", null), mockIU("bar", null)}; //$NON-NLS-1$ //$NON-NLS-2$
metadataRepo = new TestMetadataRepository(getAgent(), ius);
- expect(publisherInfo.getMetadataRepository()).andReturn(metadataRepo).anyTimes();
- expect(publisherInfo.getContextMetadataRepository()).andReturn(null).anyTimes();
+ when(publisherInfo.getMetadataRepository()).thenReturn(metadataRepo);
+ when(publisherInfo.getContextMetadataRepository()).thenReturn(null);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
index 41bf705a0..532bab05e 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxExecutableActionTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2017 Code 9 and others.
+ * Copyright (c) 2008, 2021 Code 9 and others.
*
* This
* program and the accompanying materials are made available under the terms of
@@ -15,9 +15,11 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
@@ -30,6 +32,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
@@ -62,10 +65,9 @@ public class EquinoxExecutableActionTest extends ActionTest {
private static final File LINUX_EXEC = new File(TestActivator.getTestDataFolder(), "EquinoxExecutableActionTest/linux/"); //$NON-NLS-1$
private static final File WIN_EXEC = new File(TestActivator.getTestDataFolder(), "EquinoxExecutableActionTest/win/"); //$NON-NLS-1$
private final String EXECUTABLE_NAME = "LauncherName"; //$NON-NLS-1$
- private Collection<IBrandingAdvice> brandingAdvice = new LinkedList<>();
private String macConfigCocoa = "cocoa.macosx.x86"; //$NON-NLS-1$
- private String winConfig = "win32.win32.x86"; //$NON-NLS-1$
- private String linuxConfig = "linux.gtk.x86"; //$NON-NLS-1$
+ private String winConfig = "win32.win32.x86_64"; //$NON-NLS-1$
+ private String linuxConfig = "linux.gtk.x86_64"; //$NON-NLS-1$
private ExecutablesDescriptor executablesDescriptor;
private IArtifactRepository artifactRepository;
private Version version = Version.create("1.2.3"); //$NON-NLS-1$
@@ -76,9 +78,6 @@ public class EquinoxExecutableActionTest extends ActionTest {
public void setUp() throws Exception {
setupPublisherInfo();
setupPublisherResult();
- }
-
- private void setupArtifactRepository() {
artifactRepository = new TestArtifactRepository(getAgent());
}
@@ -118,7 +117,10 @@ public class EquinoxExecutableActionTest extends ActionTest {
private void testExecutableAction(String idBase, final String osArg, String config, File exec, File icon) {
id = idBase;
- setupBrandingAdvice(osArg, configSpec, exec, icon);
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getArtifactOptions()).thenReturn(IPublisherInfo.A_PUBLISH);
+ when(publisherInfo.getAdvice(anyString(), anyBoolean(), nullable(String.class), nullable(Version.class),
+ eq(IBrandingAdvice.class))).then(invocation -> setupBrandingAdvice(osArg, icon));
executablesDescriptor = ExecutablesDescriptor.createDescriptor(osArg, "eclipse", exec);
testAction = new EquinoxExecutableAction(executablesDescriptor, config, idBase, version, flavorArg);
testAction.perform(publisherInfo, publisherResult, new NullProgressMonitor());
@@ -128,10 +130,10 @@ public class EquinoxExecutableActionTest extends ActionTest {
private void verifyResults(String idBase, String confSpec) {
ArrayList<IInstallableUnit> iuList = new ArrayList<>(publisherResult.getIUs(null, IPublisherResult.ROOT));
+ assertEquals(3, iuList.size());
verifyEclipseIU(iuList, idBase, confSpec);
verifyCU(iuList, idBase, confSpec);
verifyExecIU(iuList, idBase, confSpec);
- assertTrue(iuList.size() == 3);
}
private void verifyCU(ArrayList<IInstallableUnit> iuList, String idBase, String confSpec) {
@@ -162,16 +164,16 @@ public class EquinoxExecutableActionTest extends ActionTest {
private void verifyEclipseIU(ArrayList<IInstallableUnit> iuList, String idBase, String confSpec) {
for (IInstallableUnit possibleEclipse : iuList) {
if (possibleEclipse.getId().equals((idBase + ".executable." + confSpec + "." + EXECUTABLE_NAME))) { //$NON-NLS-1$//$NON-NLS-2$
- assertTrue(possibleEclipse.getVersion().equals(version));
+ assertEquals(version, possibleEclipse.getVersion());
Collection<IProvidedCapability> providedCapability = possibleEclipse.getProvidedCapabilities();
verifyProvidedCapability(providedCapability, IInstallableUnit.NAMESPACE_IU_ID, idBase + ".executable." + confSpec + "." + EXECUTABLE_NAME, version); //$NON-NLS-1$ //$NON-NLS-2$
- assertTrue(providedCapability.size() == 1);
+ assertEquals(1, providedCapability.size());
Collection<IRequirement> req = possibleEclipse.getRequirements();
- assertTrue(req.size() == 0);
+ assertEquals(0, req.size());
return;//pass
}
}
- fail();
+ fail("No executable installable unit.");
}
private void verifyExecIU(ArrayList<IInstallableUnit> iuList, String idBase, String confSpec) {
@@ -274,15 +276,8 @@ public class EquinoxExecutableActionTest extends ActionTest {
}
}
- @Override
- protected void insertPublisherInfoBehavior() {
- setupArtifactRepository();
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_PUBLISH).anyTimes();
- expect(publisherInfo.getAdvice((String) anyObject(), anyBoolean(), (String) anyObject(), (Version) anyObject(), (Class<IBrandingAdvice>) anyObject())).andReturn(brandingAdvice);
- }
-
- private void setupBrandingAdvice(final String osArg, final String config, final File exec, final File icon) {
+ private List<IBrandingAdvice> setupBrandingAdvice(final String osArg, final File icon) {
+ List<IBrandingAdvice> brandingAdvice = new LinkedList<>();
brandingAdvice.add(new IBrandingAdvice() {
@Override
public boolean isApplicable(String configSpec, boolean includeDefault, String id, Version version) {
@@ -304,5 +299,6 @@ public class EquinoxExecutableActionTest extends ActionTest {
return EXECUTABLE_NAME;
}
});
+ return brandingAdvice;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
index 95442d175..ff0b846fb 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/EquinoxLauncherCUActionTest.java
@@ -15,9 +15,8 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collection;
@@ -56,13 +55,12 @@ public class EquinoxLauncherCUActionTest extends ActionTest {
}
protected IInstallableUnit mockIU(String id, Version version, boolean fragment) {
- IInstallableUnit result = createMock(IInstallableUnit.class);
- expect(result.getId()).andReturn(id).anyTimes();
+ IInstallableUnit result = mock(IInstallableUnit.class);
+ when(result.getId()).thenReturn(id);
if (version == null)
version = Version.emptyVersion;
- expect(result.getVersion()).andReturn(version).anyTimes();
- expect(result.getFilter()).andReturn(null).anyTimes();
- replay(result);
+ when(result.getVersion()).thenReturn(version);
+ when(result.getFilter()).thenReturn(null);
return result;
}
@@ -108,7 +106,10 @@ public class EquinoxLauncherCUActionTest extends ActionTest {
ArrayList<IVersionAdvice> versionList = new ArrayList<>();
versionList.add(versionAdvice);
- expect(publisherInfo.getAdvice(null, true, EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER, null, IVersionAdvice.class)).andReturn(versionList);
- expect(publisherInfo.getAdvice(configSpec, true, EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER + "." + configSpec, null, IVersionAdvice.class)).andReturn(versionList); //$NON-NLS-1$
+ when(publisherInfo.getAdvice(null, true, EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER, null,
+ IVersionAdvice.class)).thenReturn(versionList);
+ when(publisherInfo.getAdvice(configSpec, true,
+ EquinoxLauncherCUAction.ORG_ECLIPSE_EQUINOX_LAUNCHER + "." + configSpec, null, IVersionAdvice.class)) //$NON-NLS-1$
+ .thenReturn(versionList);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
index bae3a460e..279660892 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/FeaturesActionTest.java
@@ -15,10 +15,10 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.and;
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.isA;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
@@ -26,10 +26,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
-import org.easymock.Capture;
-import org.easymock.EasyMock;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
@@ -62,6 +61,8 @@ import org.eclipse.equinox.p2.tests.TestData;
import org.eclipse.equinox.p2.tests.TestMetadataRepository;
import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
public class FeaturesActionTest extends ActionTest {
@@ -75,12 +76,12 @@ public class FeaturesActionTest extends ActionTest {
private Version barVersion = Version.create("1.1.1"); //$NON-NLS-1$
private String BAR = "bar"; //$NON-NLS-1$
private String FOO = "foo"; //$NON-NLS-1$
- private Capture<ITouchpointAdvice> tpAdvice;
+ private ArgumentCaptor<ITouchpointAdvice> capture = ArgumentCaptor.forClass(ITouchpointAdvice.class);
@Override
public void setUp() throws Exception {
- testAction = new FeaturesAction(new File[] {root});
- tpAdvice = Capture.newInstance();
+ super.setUp();
+ testAction = Mockito.spy(new FeaturesAction(new File[] { root }));
setupPublisherInfo();
setupPublisherResult();
}
@@ -90,37 +91,41 @@ public class FeaturesActionTest extends ActionTest {
*/
public void testSimple() throws Exception {
testAction.perform(publisherInfo, publisherResult, new NullProgressMonitor());
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(capture.capture());
verifyRepositoryContents();
debug("Completed FeaturesAction."); //$NON-NLS-1$
}
public void testFeaturePatch() throws Exception {
File testFolder = getTestFolder("FeaturesAction.testFilters");
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
buffer.append(" <requires> \n");
- buffer.append(" <import feature=\"org.foo\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" patch=\"true\"/> \n");
+ buffer.append(
+ " <import feature=\"org.foo\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" patch=\"true\"/> \n");
buffer.append(" </requires> \n");
buffer.append("</feature> \n");
File featureXML = new File(testFolder, "feature.xml");
writeBuffer(featureXML, buffer);
publisherInfo = new PublisherInfo();
- FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ FeaturesAction action = new FeaturesAction(new File[] { testFolder });
action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
- IInstallableUnitPatch iu = (IInstallableUnitPatch) publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
+ IInstallableUnitPatch iu = (IInstallableUnitPatch) publisherResult.getIU("test.feature.feature.group",
+ Version.parseVersion("1.0.0"), null);
IRequirement[][] applicabilityScope = iu.getApplicabilityScope();
assertEquals(1, applicabilityScope.length);
IRequiredCapability require = (IRequiredCapability) applicabilityScope[0][0];
- IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
+ IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID,
+ "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
verifyRequirement(Collections.singleton(expected), require);
}
public void testMatchRange() throws Exception {
File testFolder = getTestFolder("FeaturesAction.testFilters");
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
buffer.append(" <requires> \n");
buffer.append(" <import plugin=\"org.plug\" version=\"[1.0.0,2.0.0)\" match=\"versionRange\" /> \n");
@@ -131,7 +136,7 @@ public class FeaturesActionTest extends ActionTest {
writeBuffer(featureXML, buffer);
publisherInfo = new PublisherInfo();
- FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ FeaturesAction action = new FeaturesAction(new File[] { testFolder });
action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
IInstallableUnit iu = publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
@@ -141,10 +146,12 @@ public class FeaturesActionTest extends ActionTest {
String requireName = ((IRequiredCapability) require).getName();
if (requireName.equals("org.foo.feature.group")) {
- IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
+ IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID,
+ "org.foo.feature.group", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
verifyRequirement(Collections.singleton(expected), require);
} else if (requireName.equals("org.plug")) {
- IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug", VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
+ IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug",
+ VersionRange.create("[1.0.0, 2.0.0)"), null, false, false, true);
verifyRequirement(Collections.singleton(expected), require);
}
}
@@ -152,7 +159,7 @@ public class FeaturesActionTest extends ActionTest {
public void testMatchGreaterOrEqual() throws Exception {
File testFolder = getTestFolder("FeaturesAction.testFilters");
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
buffer.append(" <requires> \n");
buffer.append(" <import plugin=\"org.plug\" version=\"1.0.0\" match=\"greaterOrEqual\" /> \n");
@@ -163,7 +170,7 @@ public class FeaturesActionTest extends ActionTest {
writeBuffer(featureXML, buffer);
publisherInfo = new PublisherInfo();
- FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ FeaturesAction action = new FeaturesAction(new File[] { testFolder });
action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
IInstallableUnit iu = publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
@@ -173,10 +180,12 @@ public class FeaturesActionTest extends ActionTest {
String requireName = ((IRequiredCapability) require).getName();
if (requireName.equals("org.foo.feature.group")) {
- IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.foo.feature.group", VersionRange.create("1.0.0"), null, false, false, true);
+ IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID,
+ "org.foo.feature.group", VersionRange.create("1.0.0"), null, false, false, true);
verifyRequirement(Collections.singleton(expected), require);
} else if (requireName.equals("org.plug")) {
- IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug", VersionRange.create("1.0.0"), null, false, false, true);
+ IRequirement expected = MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, "org.plug",
+ VersionRange.create("1.0.0"), null, false, false, true);
verifyRequirement(Collections.singleton(expected), require);
}
}
@@ -184,7 +193,7 @@ public class FeaturesActionTest extends ActionTest {
public void testFilters() throws Exception {
File testFolder = getTestFolder("FeaturesAction.testFilters");
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("<feature id=\"test.feature\" version=\"1.0.0\" > \n");
buffer.append(" <includes id=\"org.foo\" version=\"1.0.0\" filter=\"(osgi.os=win32)\"/> \n");
buffer.append(" <plugin id=\"org.plug\" version=\"1.0.0\" filter=\"(my.prop=foo)\" os=\"win32\" /> \n");
@@ -197,7 +206,7 @@ public class FeaturesActionTest extends ActionTest {
writeBuffer(featureXML, buffer);
publisherInfo = new PublisherInfo();
- FeaturesAction action = new FeaturesAction(new File[] {testFolder});
+ FeaturesAction action = new FeaturesAction(new File[] { testFolder });
action.perform(publisherInfo, publisherResult, new NullProgressMonitor());
IInstallableUnit iu = publisherResult.getIU("test.feature.feature.group", Version.parseVersion("1.0.0"), null);
@@ -207,7 +216,8 @@ public class FeaturesActionTest extends ActionTest {
if (((IRequiredCapability) require).getName().equals("org.foo.feature.group")) {
assertEquals(ExpressionUtil.parseLDAP("(osgi.os=win32)"), require.getFilter().getParameters()[0]);
} else if (((IRequiredCapability) require).getName().equals("org.plug")) {
- assertEquals(ExpressionUtil.parseLDAP("(&(my.prop=foo)(osgi.os=win32))"), require.getFilter().getParameters()[0]);
+ assertEquals(ExpressionUtil.parseLDAP("(&(my.prop=foo)(osgi.os=win32))"),
+ require.getFilter().getParameters()[0]);
} else if (((IRequiredCapability) require).getName().equals("org.plug2")) {
assertEquals(ExpressionUtil.parseLDAP("(my.prop=foo)"), require.getFilter().getParameters()[0]);
} else if (((IRequiredCapability) require).getName().equals("org.foo2.feature.group")) {
@@ -222,151 +232,173 @@ public class FeaturesActionTest extends ActionTest {
}
private void verifyMetadata() {
- //{foo.feature.jar=[foo.feature.jar 1.0.0], bar.feature.jar=[bar.feature.jar 1.1.1], foo.feature.group=[foo.feature.group 1.0.0], bar.feature.group=[bar.feature.group 1.1.1]}
- ArrayList<IInstallableUnit> fooIUs = new ArrayList<>(publisherResult.getIUs("foo.feature.jar", IPublisherResult.NON_ROOT)); //$NON-NLS-1$
- assertTrue(fooIUs.size() == 1);
+ // {foo.feature.jar=[foo.feature.jar 1.0.0], bar.feature.jar=[bar.feature.jar
+ // 1.1.1], foo.feature.group=[foo.feature.group 1.0.0],
+ // bar.feature.group=[bar.feature.group 1.1.1]}
+ ArrayList<IInstallableUnit> fooIUs = new ArrayList<>(
+ publisherResult.getIUs("foo.feature.jar", IPublisherResult.NON_ROOT)); //$NON-NLS-1$
+ assertEquals(1, fooIUs.size());
IInstallableUnit foo = fooIUs.get(0);
assertTrue(foo.getId().equalsIgnoreCase("foo.feature.jar")); //$NON-NLS-1$
- assertTrue(foo.getVersion().equals(fooVersion));
+ assertEquals(fooVersion, foo.getVersion());
assertEquals("Foo Feature", foo.getProperty(IInstallableUnit.PROP_NAME));
assertEquals("Foo Description", foo.getProperty(IInstallableUnit.PROP_DESCRIPTION));
assertEquals("Foo License", foo.getLicenses().iterator().next().getBody());
assertEquals("Foo Copyright", foo.getCopyright().getBody());
- assertTrue(foo.getProperty("key1").equals("value1")); //$NON-NLS-1$ //$NON-NLS-2$
- assertTrue(foo.getProperty("key2").equals("value2")); //$NON-NLS-1$//$NON-NLS-2$
- assertTrue(foo.getArtifacts().iterator().next().equals(FOO_KEY));
- assertEquals(foo.getFilter().getParameters()[0], ExpressionUtil.parseLDAP("(org.eclipse.update.install.features=true)")); //$NON-NLS-1$
+ assertEquals("value1", foo.getProperty("key1")); //$NON-NLS-1$ //$NON-NLS-2$
+ assertEquals("value2", foo.getProperty("key2")); //$NON-NLS-1$//$NON-NLS-2$
+ assertEquals(FOO_KEY, foo.getArtifacts().iterator().next());
+ assertEquals(foo.getFilter().getParameters()[0],
+ ExpressionUtil.parseLDAP("(org.eclipse.update.install.features=true)")); //$NON-NLS-1$
- //check touchpointType
+ // check touchpointType
assertTrue(foo.getTouchpointType().getId().equalsIgnoreCase("org.eclipse.equinox.p2.osgi")); //$NON-NLS-1$
- assertTrue(foo.getTouchpointType().getVersion().equals(fooVersion));
+ assertEquals(fooVersion, foo.getTouchpointType().getVersion());
- //zipped=true
+ // zipped=true
Collection<ITouchpointData> tpData = foo.getTouchpointData();
String fooValue = tpData.iterator().next().getInstructions().get("zipped").getBody(); //$NON-NLS-1$
assertTrue(fooValue.equalsIgnoreCase("true")); //$NON-NLS-1$
Collection<IRequirement> fooRequiredCapabilities = foo.getRequirements();
- assertTrue(fooRequiredCapabilities.size() == 0);
+ assertTrue(fooRequiredCapabilities.isEmpty());
Collection<IProvidedCapability> fooProvidedCapabilities = foo.getProvidedCapabilities();
- verifyProvidedCapability(fooProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "foo.feature.jar", fooVersion); //$NON-NLS-1$
- verifyProvidedCapability(fooProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
+ verifyProvidedCapability(fooProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "foo.feature.jar", //$NON-NLS-1$
+ fooVersion);
+ verifyProvidedCapability(fooProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", //$NON-NLS-1$
+ fooVersion);
verifyProvidedCapability(fooProvidedCapabilities, "org.eclipse.update.feature", FOO, fooVersion); //$NON-NLS-1$
- assertTrue(fooProvidedCapabilities.size() == 3);
+ assertEquals(3, fooProvidedCapabilities.size());
- //feature group IU for foo
+ // feature group IU for foo
fooIUs = new ArrayList<>(publisherResult.getIUs("foo.feature.group", IPublisherResult.ROOT)); //$NON-NLS-1$
- assertTrue(fooIUs.size() == 1);
+ assertEquals(1, fooIUs.size());
IInstallableUnit fooGroup = fooIUs.get(0);
- tpData = fooGroup.getTouchpointData();
- assertEquals(1, tpData.size());
- ITouchpointInstruction instruction = tpData.iterator().next().getInstruction("install");
+ ITouchpointAdvice tData = capture.getValue();
+ ITouchpointInstruction instruction = tData.getTouchpointData(NO_TP_DATA).getInstruction("install");
assertNotNull(instruction);
- assertEquals("ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);chmod(targetDir:@artifact,targetFile:lib/lib.so,permissions:755);", instruction.getBody());
+ assertEquals(
+ "ln(targetDir:@artifact,linkTarget:foo/lib.1.so,linkName:lib.so);chmod(targetDir:@artifact,targetFile:lib/lib.so,permissions:755);",
+ instruction.getBody());
assertNull(fooGroup.getFilter());
- /*verify bar*/
- ArrayList<IInstallableUnit> barIUs = new ArrayList<>(publisherResult.getIUs("bar.feature.jar", IPublisherResult.NON_ROOT)); //$NON-NLS-1$
- assertTrue(barIUs.size() == 1);
+ /* verify bar */
+ ArrayList<IInstallableUnit> barIUs = new ArrayList<>(
+ publisherResult.getIUs("bar.feature.jar", IPublisherResult.NON_ROOT)); //$NON-NLS-1$
+ assertEquals(1, barIUs.size());
IInstallableUnit bar = barIUs.get(0);
- assertTrue(bar.getId().equals("bar.feature.jar")); //$NON-NLS-1$
- assertTrue(bar.getVersion().equals(barVersion));
- assertTrue(bar.getProperty("key1").equals("value1")); //$NON-NLS-1$//$NON-NLS-2$
- assertTrue(bar.getProperty("key2").equals("value2")); //$NON-NLS-1$//$NON-NLS-2$
+ assertEquals("bar.feature.jar", bar.getId()); //$NON-NLS-1$
+ assertEquals(barVersion, bar.getVersion());
+ assertEquals("value1", bar.getProperty("key1")); //$NON-NLS-1$//$NON-NLS-2$
+ assertEquals("value2", bar.getProperty("key2")); //$NON-NLS-1$//$NON-NLS-2$
assertTrue(bar.getProperties().containsKey("org.eclipse.update.installHandler")); //$NON-NLS-1$
assertTrue(bar.getProperties().containsValue("handler=bar handler")); //$NON-NLS-1$
- assertTrue(bar.getArtifacts().iterator().next().equals(BAR_KEY));
- assertEquals(bar.getFilter().getParameters()[0], ExpressionUtil.parseLDAP("(org.eclipse.update.install.features=true)")); //$NON-NLS-1$
+ assertEquals(BAR_KEY, bar.getArtifacts().iterator().next());
+ assertEquals(bar.getFilter().getParameters()[0],
+ ExpressionUtil.parseLDAP("(org.eclipse.update.install.features=true)")); //$NON-NLS-1$
assertTrue(bar.isSingleton());
barIUs = new ArrayList<>(publisherResult.getIUs("bar.feature.group", IPublisherResult.ROOT)); //$NON-NLS-1$
- assertTrue(fooIUs.size() == 1);
+ assertEquals(1, fooIUs.size());
IInstallableUnit barGroup = barIUs.get(0);
Collection<IRequirement> barRequiredCapabilities = barGroup.getRequirements();
- //contains(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar_root", new VersionRange(barVersion, true, barVersion, true), null, false /*multiple*/, false /*optional*/); //$NON-NLS-1$//$NON-NLS-2$
- verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", new VersionRange(barVersion, true, barVersion, true), "(org.eclipse.update.install.features=true)", 1, 1, true); //$NON-NLS-1$//$NON-NLS-2$
- verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "org.bar.feature.feature.group", VersionRange.emptyRange, "(&(|(osgi.nl=de)(osgi.nl=en)(osgi.nl=fr)))", 1, 1, true); //$NON-NLS-1$//$NON-NLS-2$
- assertEquals(barGroup.getFilter().getParameters()[0], ExpressionUtil.parseLDAP("(&(|(osgi.os=macosx)(osgi.os=win32))(|(osgi.ws=carbon)(osgi.ws=win32))(|(osgi.arch=ppc)(osgi.arch=x86))(osgi.nl=en))"));
-
- //check zipped=true in touchpointData
+ // contains(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID,
+ // "bar_root", new VersionRange(barVersion, true, barVersion, true), null, false
+ // /*multiple*/, false /*optional*/); //$NON-NLS-1$//$NON-NLS-2$
+ verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", //$NON-NLS-1$
+ new VersionRange(barVersion, true, barVersion, true), "(org.eclipse.update.install.features=true)", 1, //$NON-NLS-1$
+ 1, true);
+ verifyRequirement(barRequiredCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "org.bar.feature.feature.group", //$NON-NLS-1$
+ VersionRange.emptyRange, "(&(|(osgi.nl=de)(osgi.nl=en)(osgi.nl=fr)))", 1, 1, true); //$NON-NLS-1$
+ assertEquals(barGroup.getFilter().getParameters()[0], ExpressionUtil.parseLDAP(
+ "(&(|(osgi.os=macosx)(osgi.os=win32))(|(osgi.ws=carbon)(osgi.ws=win32))(|(osgi.arch=ppc)(osgi.arch=x86))(osgi.nl=en))"));
+
+ // check zipped=true in touchpointData
String barValue = bar.getTouchpointData().iterator().next().getInstructions().get("zipped").getBody(); //$NON-NLS-1$
assertTrue(barValue.equalsIgnoreCase("true")); //$NON-NLS-1$
- //check touchpointType
+ // check touchpointType
assertTrue(bar.getTouchpointType().getId().equalsIgnoreCase("org.eclipse.equinox.p2.osgi")); //$NON-NLS-1$
- assertTrue(bar.getTouchpointType().getVersion().equals(fooVersion));
- //String namespace, String name, VersionRange range, String filter, boolean optional, boolean multiple, boolean greedy)
+ assertEquals(fooVersion, bar.getTouchpointType().getVersion());
+ // String namespace, String name, VersionRange range, String filter, boolean
+ // optional, boolean multiple, boolean greedy)
barRequiredCapabilities = bar.getRequirements();
- assertTrue(barRequiredCapabilities.size() == 0);
+ assertTrue(barRequiredCapabilities.isEmpty());
Collection<IProvidedCapability> barProvidedCapabilities = bar.getProvidedCapabilities();
- verifyProvidedCapability(barProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", barVersion); //$NON-NLS-1$
- verifyProvidedCapability(barProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", fooVersion); //$NON-NLS-1$
+ verifyProvidedCapability(barProvidedCapabilities, IInstallableUnit.NAMESPACE_IU_ID, "bar.feature.jar", //$NON-NLS-1$
+ barVersion);
+ verifyProvidedCapability(barProvidedCapabilities, PublisherHelper.NAMESPACE_ECLIPSE_TYPE, "feature", //$NON-NLS-1$
+ fooVersion);
verifyProvidedCapability(barProvidedCapabilities, "org.eclipse.update.feature", BAR, barVersion); //$NON-NLS-1$
- assertTrue(barProvidedCapabilities.size() == 3);
+ assertEquals(3, barProvidedCapabilities.size());
}
private void verifyArtifacts() throws IOException {
ZipInputStream actualStream = artifactRepository.getZipInputStream(FOO_KEY);
- Map<String, Object[]> expected = getFileMap(new HashMap<>(), new File[] {new File(root, FOO)}, new Path(new File(root, FOO).getAbsolutePath()));
+ Map<String, Object[]> expected = getFileMap(new HashMap<>(), new File[] { new File(root, FOO) },
+ new Path(new File(root, FOO).getAbsolutePath()));
TestData.assertContains(expected, actualStream, true);
- expected = getFileMap(new HashMap<>(), new File[] {new File(root, BAR)}, new Path(new File(root, BAR).getAbsolutePath()));
+ expected = getFileMap(new HashMap<>(), new File[] { new File(root, BAR) },
+ new Path(new File(root, BAR).getAbsolutePath()));
actualStream = artifactRepository.getZipInputStream(BAR_KEY);
TestData.assertContains(expected, actualStream, true);
}
@Override
protected void insertPublisherInfoBehavior() {
- //setup metadataRepository with barIU
- metadataRepository = new TestMetadataRepository(getAgent(), new IInstallableUnit[] {mockIU(BAR, null)});
-
- ArrayList<IPropertyAdvice> adviceCollection = fillAdvice(new ArrayList<>());
- expect(publisherInfo.getAdvice(null, false, "bar.feature.jar", barVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar", barVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar", barVersion, IFeatureRootAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, ITouchpointAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, ICapabilityAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion,
- IAdditionalInstallableUnitAdvice.class)).andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.jar", fooVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, IUpdateDescriptorAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo", fooVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo", fooVersion, IFeatureRootAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, IPropertyAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, ICapabilityAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion,
- IAdditionalInstallableUnitAdvice.class)).andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, IUpdateDescriptorAdvice.class))
- .andReturn(Collections.emptyList()).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH).anyTimes();
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getMetadataRepository()).andReturn(metadataRepository).anyTimes();
- expect(publisherInfo.getContextMetadataRepository()).andReturn(null).anyTimes();
-
- //capture any touchpoint advice, and return the captured advice when the action asks for it
- publisherInfo.addAdvice(and(isA(ITouchpointAdvice.class), capture(tpAdvice)));
- EasyMock.expectLastCall().anyTimes();
- expect(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, ITouchpointAdvice.class)).andReturn(new CaptureList<>(tpAdvice)).anyTimes();
+ // setup metadataRepository with barIU
+ metadataRepository = new TestMetadataRepository(getAgent(), new IInstallableUnit[] { mockIU(BAR, null) });
+
+ List<IPropertyAdvice> adviceCollection = fillAdvice(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, false, "bar.feature.jar", barVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "bar", barVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "bar", barVersion, IFeatureRootAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, ITouchpointAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, ICapabilityAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion,
+ IAdditionalInstallableUnitAdvice.class)).thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "foo.feature.jar", fooVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "bar.feature.group", barVersion, IUpdateDescriptorAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "foo", fooVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "foo", fooVersion, IFeatureRootAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, IPropertyAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, ICapabilityAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion,
+ IAdditionalInstallableUnitAdvice.class)).thenReturn(Collections.emptyList());
+ when(publisherInfo.getAdvice(null, false, "foo.feature.group", fooVersion, IUpdateDescriptorAdvice.class))
+ .thenReturn(Collections.emptyList());
+ when(publisherInfo.getArtifactOptions())
+ .thenReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH);
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getMetadataRepository()).thenReturn(metadataRepository);
+ when(publisherInfo.getContextMetadataRepository()).thenReturn(null);
}
- private ArrayList<IPropertyAdvice> fillAdvice(ArrayList<IPropertyAdvice> adviceCollection) {
+ private List<IPropertyAdvice> fillAdvice(ArrayList<IPropertyAdvice> adviceCollection) {
Map<String, String> prop = new HashMap<>();
prop.put("key1", "value1"); //$NON-NLS-1$//$NON-NLS-2$
prop.put("key2", "value2"); //$NON-NLS-1$//$NON-NLS-2$
- IPropertyAdvice propertyAdvice = EasyMock.createMock(IPropertyAdvice.class);
- expect(propertyAdvice.getInstallableUnitProperties((InstallableUnitDescription) EasyMock.anyObject())).andReturn(prop).anyTimes();
- expect(propertyAdvice.getArtifactProperties((IInstallableUnit) EasyMock.anyObject(), (IArtifactDescriptor) EasyMock.anyObject())).andReturn(null).anyTimes();
- EasyMock.replay(propertyAdvice);
+ IPropertyAdvice propertyAdvice = mock(IPropertyAdvice.class);
+ when(propertyAdvice.getInstallableUnitProperties(any(InstallableUnitDescription.class))).thenReturn(prop);
+ when(propertyAdvice.getArtifactProperties(any(IInstallableUnit.class), any(IArtifactDescriptor.class)))
+ .thenReturn(null);
adviceCollection.add(propertyAdvice);
return adviceCollection;
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
index d1d3a4a20..dc5719e14 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/JREActionTest.java
@@ -16,7 +16,6 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.expect;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.errorStatus;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.okStatus;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.statusWithMessageWhich;
@@ -27,6 +26,7 @@ import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
+import static org.mockito.Mockito.when;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -276,7 +276,7 @@ public class JREActionTest extends ActionTest {
@Override
protected void insertPublisherInfoBehavior() {
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_PUBLISH).anyTimes();
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getArtifactOptions()).thenReturn(IPublisherInfo.A_PUBLISH);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/LocalUpdateSiteActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/LocalUpdateSiteActionTest.java
index 706760c4e..53d5f03b8 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/LocalUpdateSiteActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/LocalUpdateSiteActionTest.java
@@ -14,9 +14,11 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.expect;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
import java.io.File;
import java.util.Collection;
@@ -29,7 +31,6 @@ import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.ITouchpointData;
import org.eclipse.equinox.p2.metadata.ITouchpointInstruction;
import org.eclipse.equinox.p2.metadata.Version;
-import org.eclipse.equinox.p2.publisher.IPublisherAdvice;
import org.eclipse.equinox.p2.publisher.IPublisherInfo;
import org.eclipse.equinox.p2.tests.TestData;
import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
@@ -48,10 +49,11 @@ public class LocalUpdateSiteActionTest extends ActionTest {
@Override
protected void insertPublisherInfoBehavior() {
super.insertPublisherInfoBehavior();
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH).anyTimes();
- expect(publisherInfo.getAdvice((String) anyObject(), anyBoolean(), (String) anyObject(), (Version) anyObject(),
- (Class<IPublisherAdvice>) anyObject())).andReturn(Collections.emptyList()).anyTimes();
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getArtifactOptions())
+ .thenReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH);
+ when(publisherInfo.getAdvice(anyString(), anyBoolean(), anyString(), any(Version.class), any(Class.class)))
+ .thenReturn(Collections.emptyList());
}
/**
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionCapturingTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionCapturingTest.java
index eb9a2d1b8..898c5f0fb 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionCapturingTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionCapturingTest.java
@@ -16,65 +16,35 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.okStatus;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.verify;
import java.io.File;
-import java.util.Collections;
-import org.easymock.Capture;
-import org.easymock.EasyMock;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
-import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.publisher.IPublisherAdvice;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.actions.RootIUAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.IConfigAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.IExecutableAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.ProductAction;
import org.eclipse.equinox.p2.publisher.eclipse.ProductFileAdvice;
import org.eclipse.equinox.p2.tests.TestData;
import org.eclipse.equinox.p2.tests.publisher.TestArtifactRepository;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
public class ProductActionCapturingTest extends ActionTest {
File executablesFeatureLocation = null;
String source = "";
- private Capture<RootIUAdvice> rootIUAdviceCapture;
- private Capture<ProductFileAdvice> productFileAdviceCapture;
protected TestArtifactRepository artifactRepository = new TestArtifactRepository(getAgent());
@Override
- protected IPublisherInfo createPublisherInfoMock() {
- //override to create a nice mock, because we don't care about other method calls.
- return createNiceMock(IPublisherInfo.class);
- }
-
- @Override
- protected void insertPublisherInfoBehavior() {
- // capture these calls for assertions
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(RootIUAdvice.class), EasyMock.capture(rootIUAdviceCapture)));
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(ProductFileAdvice.class), EasyMock.capture(productFileAdviceCapture)));
-
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_PUBLISH).anyTimes();
- //Return an empty list every time getAdvice is called
- expect(publisherInfo.getAdvice((String) anyObject(), anyBoolean(), (String) anyObject(), (Version) anyObject(), (Class<IPublisherAdvice>) anyObject())).andReturn(Collections.emptyList());
- expectLastCall().anyTimes();
- }
-
- @Override
public void setUp() throws Exception {
- rootIUAdviceCapture = Capture.newInstance();
- productFileAdviceCapture = Capture.newInstance();
setupPublisherInfo();
setupPublisherResult();
}
@@ -84,15 +54,18 @@ public class ProductActionCapturingTest extends ActionTest {
* IConfigAdvice (start levels, auto-start).
*/
public void testSetBundleConfigData() throws Exception {
+ ArgumentCaptor<IPublisherAdvice> productFileAdviceCapture = ArgumentCaptor.forClass(IPublisherAdvice.class);
addContextIU("org.eclipse.rcp.feature.group", "3.5.0.v20081110-9C9tEvNEla71LZ2jFz-RFB-t");
ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "startLevel.product").toString());
- testAction = new ProductAction(source, productFile, flavorArg, executablesFeatureLocation);
+ testAction = Mockito.spy(new ProductAction(source, productFile, flavorArg, executablesFeatureLocation));
IStatus status = testAction.perform(publisherInfo, publisherResult, null);
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(productFileAdviceCapture.capture());
assertThat(status, is(okStatus()));
- IConfigAdvice configAdvice = productFileAdviceCapture.getValue();
+ IConfigAdvice configAdvice = (IConfigAdvice) productFileAdviceCapture.getAllValues().stream()
+ .filter(IConfigAdvice.class::isInstance).collect(Collectors.toList()).get(0);
BundleInfo[] bundles = configAdvice.getBundles();
assertEquals("1.0", 2, bundles.length);
assertEquals("1.1", "org.eclipse.equinox.common", bundles[0].getSymbolicName());
@@ -110,14 +83,17 @@ public class ProductActionCapturingTest extends ActionTest {
* Tests that correct advice is created for the org.eclipse.platform product.
*/
public void testPlatformProduct() throws Exception {
+ ArgumentCaptor<IPublisherAdvice> productFileAdviceCapture = ArgumentCaptor.forClass(IPublisherAdvice.class);
ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "platform.product").toString());
addContextIU("org.eclipse.platform.feature.group", "1.2.3");
- testAction = new ProductAction(source, productFile, flavorArg, executablesFeatureLocation);
+ testAction = Mockito.spy(new ProductAction(source, productFile, flavorArg, executablesFeatureLocation));
IStatus status = testAction.perform(publisherInfo, publisherResult, null);
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(productFileAdviceCapture.capture());
assertThat(status, is(okStatus()));
- IExecutableAdvice launchAdvice = productFileAdviceCapture.getValue();
+ IExecutableAdvice launchAdvice = (IExecutableAdvice) productFileAdviceCapture.getAllValues().stream()
+ .filter(ProductFileAdvice.class::isInstance).collect(Collectors.toList()).get(0);
assertEquals("1.0", "eclipse", launchAdvice.getExecutableName());
String[] programArgs = launchAdvice.getProgramArguments();
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTest.java
index 3405c53e5..994cfafcd 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTest.java
@@ -16,7 +16,6 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.createNiceMock;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.errorStatus;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.okStatus;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.statusWithMessageWhich;
@@ -71,21 +70,18 @@ public class ProductActionTest extends ActionTest {
String source = "";
protected TestArtifactRepository artifactRepository = new TestArtifactRepository(getAgent());
- @Override protected IPublisherInfo createPublisherInfoMock() {
- //override to create a nice mock, because we don't care about other method calls.
- return createNiceMock(IPublisherInfo.class);
- }
-
- @Override public void setUp() throws Exception {
+ @Override
+ public void setUp() throws Exception {
setupPublisherInfo();
setupPublisherResult();
}
- @Override public void setupPublisherInfo() {
+ @Override
+ public void setupPublisherInfo() {
PublisherInfo publisherInfoImpl = new PublisherInfo();
publisherInfoImpl.setArtifactRepository(artifactRepository);
publisherInfoImpl.setArtifactOptions(IPublisherInfo.A_PUBLISH);
- publisherInfoImpl.setConfigurations(new String[] {configSpec});
+ publisherInfoImpl.setConfigurations(new String[] { configSpec });
publisherInfo = publisherInfoImpl;
}
@@ -95,18 +91,20 @@ public class ProductActionTest extends ActionTest {
* splash screen, icon, etc.
*/
public void testBrandedApplication() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "brandedProduct/branded.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "brandedProduct/branded.product").toString());
addContextIU("org.eclipse.platform.feature.group", "1.2.3");
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("branded.product", IPublisherResult.NON_ROOT);
assertEquals("1.0", 1, ius.size());
- //TODO assert branding was done correctly
+ // TODO assert branding was done correctly
}
public void testLicense() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "productWithLicense.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "productWithLicense.product").toString());
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("licenseIU.product", IPublisherResult.NON_ROOT);
assertEquals("1.0", 1, ius.size());
@@ -116,7 +114,8 @@ public class ProductActionTest extends ActionTest {
}
public void testLicenseNoURL() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "licenseNoURL.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "licenseNoURL.product").toString());
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("licenseIU.product", IPublisherResult.NON_ROOT);
assertEquals("1.0", 1, ius.size());
@@ -126,7 +125,8 @@ public class ProductActionTest extends ActionTest {
}
public void testLicenseNoText() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "licenseNoText.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "licenseNoText.product").toString());
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("licenseIU.product", IPublisherResult.NON_ROOT);
assertEquals("1.0", 1, ius.size());
@@ -136,7 +136,8 @@ public class ProductActionTest extends ActionTest {
}
public void testMissingLicense() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "productWithNoLicense.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "productWithNoLicense.product").toString());
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("licenseIU.product", IPublisherResult.NON_ROOT);
assertEquals("1.0", 1, ius.size());
@@ -145,8 +146,10 @@ public class ProductActionTest extends ActionTest {
}
public void testMultiProductPublishing() throws Exception {
- ProductFile productFile1 = new ProductFile(TestData.getFile("ProductActionTest", "boundedVersionConfigurations.product").toString());
- ProductFile productFile2 = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile1 = new ProductFile(
+ TestData.getFile("ProductActionTest", "boundedVersionConfigurations.product").toString());
+ ProductFile productFile2 = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
addContextIU("org.eclipse.core.runtime", "4.0.0");
performProductAction(productFile1);
@@ -158,7 +161,8 @@ public class ProductActionTest extends ActionTest {
}
public void testMultiPlatformCUs_DifferentPlatforms() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
setConfiguration(LINUX_CONFIG_SPEC);
addContextIU("org.eclipse.core.runtime", "0.0.0", WIN_FILTER);
@@ -169,7 +173,8 @@ public class ProductActionTest extends ActionTest {
}
public void testMultiPlatformCUs_SamePlatforms() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
setConfiguration(LINUX_CONFIG_SPEC);
addContextIU("org.eclipse.core.runtime", "0.0.0", LINUX_FILTER);
@@ -180,7 +185,8 @@ public class ProductActionTest extends ActionTest {
}
public void testMultiPlatformCUs_SamePlatforms_NoVersion() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
setConfiguration(LINUX_CONFIG_SPEC);
addContextIU("org.eclipse.core.runtime", null, LINUX_FILTER);
@@ -191,11 +197,13 @@ public class ProductActionTest extends ActionTest {
}
public void testMultiPlatformCUs_SamePlatforms_BoundedVersions() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
setConfiguration(LINUX_CONFIG_SPEC);
- // Set a specific version number, the one in the .product file uses 0.0.0. Let's see if it binds properly
- //filter is different from linuxConfigSpec, but will still match
+ // Set a specific version number, the one in the .product file uses 0.0.0. Let's
+ // see if it binds properly
+ // filter is different from linuxConfigSpec, but will still match
addContextIU("org.eclipse.core.runtime", "4.0.0", "(osgi.os=linux)");
performProductAction(productFile);
@@ -205,36 +213,45 @@ public class ProductActionTest extends ActionTest {
}
public void testCUsHost() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
setConfiguration(LINUX_CONFIG_SPEC);
- // Set a specific version number, the one in the .product file uses 0.0.0. Let's see if it binds properly
- //filter is different from linuxConfigSpec, but will still match
+ // Set a specific version number, the one in the .product file uses 0.0.0. Let's
+ // see if it binds properly
+ // filter is different from linuxConfigSpec, but will still match
addContextIU("org.eclipse.core.runtime", "4.0.0", "(osgi.os=linux)");
performProductAction(productFile);
- IInstallableUnitFragment fragment = (IInstallableUnitFragment) getUniquePublishedIU(flavorArg + LINUX_CONFIG_SPEC + "org.eclipse.core.runtime");
- assertEquals("1.1", "org.eclipse.core.runtime", RequiredCapability.extractName(fragment.getHost().iterator().next().getMatches()));
- assertEquals("1.2", Version.create("4.0.0"), RequiredCapability.extractRange(fragment.getHost().iterator().next().getMatches()).getMinimum());
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) getUniquePublishedIU(
+ flavorArg + LINUX_CONFIG_SPEC + "org.eclipse.core.runtime");
+ assertEquals("1.1", "org.eclipse.core.runtime",
+ RequiredCapability.extractName(fragment.getHost().iterator().next().getMatches()));
+ assertEquals("1.2", Version.create("4.0.0"),
+ RequiredCapability.extractRange(fragment.getHost().iterator().next().getMatches()).getMinimum());
assertEquals("1.3", Version.create("1.0.0"), fragment.getVersion());
}
public void testMultiConfigspecProductPublishing() throws IOException, Exception {
ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "platform.product").toString());
- ((PublisherInfo) publisherInfo).setConfigurations(new String[] {"carbon.macos.x86", "cocoa.macos.x86"});
+ ((PublisherInfo) publisherInfo).setConfigurations(new String[] { "carbon.macos.x86", "cocoa.macos.x86" });
addContextIU("org.eclipse.platform.feature.group", "1.2.3");
performProductAction(productFile);
- Collection<IConfigAdvice> advice = publisherInfo.getAdvice("carbon.macos.x86", false, null, null, IConfigAdvice.class);
+ Collection<IConfigAdvice> advice = publisherInfo.getAdvice("carbon.macos.x86", false, null, null,
+ IConfigAdvice.class);
assertEquals("1.0", 1, advice.size());
}
public void testANYConfigSpecPublishing_GeneralBundle() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
- String configSpecANY = AbstractPublisherAction.createConfigSpec("ANY", "ANY", "ANY"); // configuration spec to create CUs without filters
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ String configSpecANY = AbstractPublisherAction.createConfigSpec("ANY", "ANY", "ANY"); // configuration spec to
+ // create CUs without
+ // filters
setConfiguration(configSpecANY);
addContextIU("org.eclipse.core.runtime", "4.0.0");
@@ -242,16 +259,22 @@ public class ProductActionTest extends ActionTest {
performProductAction(productFile);
// there is a CU for the IU because it applies to all platforms
- IInstallableUnitFragment fragment = (IInstallableUnitFragment) getUniquePublishedIU(flavorArg + configSpecANY + "org.eclipse.core.runtime");
- assertEquals("1.1", "org.eclipse.core.runtime", RequiredCapability.extractName(fragment.getHost().iterator().next().getMatches()));
- assertEquals("1.2", Version.create("4.0.0"), RequiredCapability.extractRange(fragment.getHost().iterator().next().getMatches()).getMinimum());
+ IInstallableUnitFragment fragment = (IInstallableUnitFragment) getUniquePublishedIU(
+ flavorArg + configSpecANY + "org.eclipse.core.runtime");
+ assertEquals("1.1", "org.eclipse.core.runtime",
+ RequiredCapability.extractName(fragment.getHost().iterator().next().getMatches()));
+ assertEquals("1.2", Version.create("4.0.0"),
+ RequiredCapability.extractRange(fragment.getHost().iterator().next().getMatches()).getMinimum());
assertEquals("1.3", Version.create("1.0.0"), fragment.getVersion());
assertNull("1.3", fragment.getFilter());
}
public void testANYConfigSpecPublishing_PlatformSpecificBundle() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
- String configSpecANY = AbstractPublisherAction.createConfigSpec("ANY", "ANY", "ANY"); // configuration spec to create CUs without filters
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "unboundedVersionConfigurations.product").toString());
+ String configSpecANY = AbstractPublisherAction.createConfigSpec("ANY", "ANY", "ANY"); // configuration spec to
+ // create CUs without
+ // filters
setConfiguration(configSpecANY);
addContextIU("org.eclipse.core.runtime", "4.0.0", WIN_FILTER); // any valid filter can be set here
@@ -276,13 +299,15 @@ public class ProductActionTest extends ActionTest {
testAction = new ProductAction(source, productFile, flavorArg, executablesFeatureLocation);
PublisherInfo info = new PublisherInfo();
info.setContextMetadataRepository(repository);
- // TODO this line doesn't have any effect -> is this a bug in the implementation?
+ // TODO this line doesn't have any effect -> is this a bug in the
+ // implementation?
info.addAdvice(new QueryableFilterAdvice(info.getContextMetadataRepository()));
IStatus status = testAction.perform(info, publisherResult, null);
assertThat(status, is(okStatus()));
- IQueryResult<IInstallableUnit> results = publisherResult.query(QueryUtil.createIUQuery("org.eclipse.platform.ide", Version.create("3.5.0.I20081118")), null);
+ IQueryResult<IInstallableUnit> results = publisherResult
+ .query(QueryUtil.createIUQuery("org.eclipse.platform.ide", Version.create("3.5.0.I20081118")), null);
assertEquals("1.0", 1, queryResultSize(results));
IInstallableUnit unit = results.iterator().next();
Collection<IRequirement> requiredCapabilities = unit.getRequirements();
@@ -296,12 +321,14 @@ public class ProductActionTest extends ActionTest {
}
}
assertTrue("1.1", capability != null);
- assertEquals("1.2", InstallableUnit.parseFilter("(org.eclipse.update.install.features=true)"), capability.getFilter());
+ assertEquals("1.2", InstallableUnit.parseFilter("(org.eclipse.update.install.features=true)"),
+ capability.getFilter());
}
public void testProductWithAdviceFile() throws Exception {
// product file that has a corresponding advice file (p2.inf).
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest/productWithAdvice", "productWithAdvice.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest/productWithAdvice", "productWithAdvice.product").toString());
testAction = new ProductAction(source, productFile, flavorArg, executablesFeatureLocation);
IStatus status = testAction.perform(new PublisherInfo(), publisherResult, null);
assertThat(status, is(okStatus()));
@@ -310,27 +337,30 @@ public class ProductActionTest extends ActionTest {
Collection<ITouchpointData> data = product.getTouchpointData();
assertEquals("1.1", 1, data.size());
String configure = data.iterator().next().getInstruction("configure").getBody();
- assertEquals("1.2", "addRepository(type:0,location:http${#58}//download.eclipse.org/releases/fred);addRepository(type:1,location:http${#58}//download.eclipse.org/releases/fred);", configure);
-
- //update.id = com.zoobar
- //update.range = [4.0,4.3)
- //update.severity = 0
- //update.description = This is the description
+ assertEquals("1.2",
+ "addRepository(type:0,location:http${#58}//download.eclipse.org/releases/fred);addRepository(type:1,location:http${#58}//download.eclipse.org/releases/fred);",
+ configure);
+
+ // update.id = com.zoobar
+ // update.range = [4.0,4.3)
+ // update.severity = 0
+ // update.description = This is the description
IUpdateDescriptor update = product.getUpdateDescriptor();
assertEquals("2.0", 0, update.getSeverity());
assertEquals("2.1", "This is the description", update.getDescription());
- //unit that fits in range
+ // unit that fits in range
assertTrue("2.2", update.isUpdateOf(createIU("com.zoobar", Version.createOSGi(4, 1, 0))));
- //unit that is too old for range
+ // unit that is too old for range
assertFalse("2.3", update.isUpdateOf(createIU("com.zoobar", Version.createOSGi(3, 1, 0))));
- //version that is too new and outside of range
+ // version that is too new and outside of range
assertFalse("2.4", update.isUpdateOf(createIU("com.zoobar", Version.createOSGi(6, 1, 0))));
- //unit with matching version but not matching id
+ // unit with matching version but not matching id
assertFalse("2.6", update.isUpdateOf(createIU("com.other", Version.createOSGi(4, 1, 0))));
}
public void testFiltersOfInclusions() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "productIncludingFragments.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "productIncludingFragments.product").toString());
addContextIU("generalbundle", "1.0.1");
addContextIU("fragment.win", "1.0.2", WIN_FILTER);
// no fragment.linux in the context
@@ -338,39 +368,48 @@ public class ProductActionTest extends ActionTest {
IStatus status = performProductActionAndReturnStatus(productFile);
IInstallableUnit productIU = getUniquePublishedIU("productIncludingFragments.uid");
- assertThat(productIU.getRequirements(), hasItem(createIURequirement("generalbundle", createStrictVersionRange("1.0.1"))));
- assertThat(productIU.getRequirements(), hasItem(createIURequirement("fragment.win", createStrictVersionRange("1.0.2"), WIN_FILTER)));
+ assertThat(productIU.getRequirements(),
+ hasItem(createIURequirement("generalbundle", createStrictVersionRange("1.0.1"))));
+ assertThat(productIU.getRequirements(),
+ hasItem(createIURequirement("fragment.win", createStrictVersionRange("1.0.2"), WIN_FILTER)));
- // this is bug 390361: the Linux fragment is required without filter, so the product cannot be installed for Windows ...
+ // this is bug 390361: the Linux fragment is required without filter, so the
+ // product cannot be installed for Windows ...
assertThat(productIU.getRequirements(), hasItem(createIURequirement("fragment.linux", ANY_VERSION)));
// ... therefore the action shall report an error
assertThat(status, is(errorStatus()));
- assertThat(Arrays.asList(status.getChildren()), hasItem(statusWithMessageWhich(containsString("Included element fragment.linux 0.0.0 is missing"))));
+ assertThat(Arrays.asList(status.getChildren()),
+ hasItem(statusWithMessageWhich(containsString("Included element fragment.linux 0.0.0 is missing"))));
}
public void testMessageForProductWithIgnoredContent() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "mixedContentIgnored.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "mixedContentIgnored.product").toString());
IStatus status = performProductActionAndReturnStatus(productFile);
- // expect a warning about redundant, ignored content in product file -> requested in bug 325611
+ // expect a warning about redundant, ignored content in product file ->
+ // requested in bug 325611
assertThat(Arrays.asList(status.getChildren()), hasItem(statusWithMessageWhich(containsString("are ignored"))));
// TODO the message should have a code identifying it
}
public void testJREIncluded() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "brandedProduct/branded.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "brandedProduct/branded.product").toString());
addContextIU("org.eclipse.platform.feature.group", "1.2.3");
performProductAction(productFile);
Collection<IInstallableUnit> ius = publisherResult.getIUs("branded.product", IPublisherResult.NON_ROOT);
assertEquals(1, ius.size());
assertEquals("Missing a.jre.javase", 1, publisherResult.getIUs("a.jre.javase", IPublisherResult.ROOT).size());
- assertEquals("Missing config.a.jre.javase", 1, publisherResult.getIUs("config.a.jre.javase", IPublisherResult.ROOT).size());
+ assertEquals("Missing config.a.jre.javase", 1,
+ publisherResult.getIUs("config.a.jre.javase", IPublisherResult.ROOT).size());
}
public void testRequiredEEAsSpecified() throws Exception {
- ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "productFileActionTest.product").toString());
+ ProductFile productFile = new ProductFile(
+ TestData.getFile("ProductActionTest", "productFileActionTest.product").toString());
addContextIU("org.eclipse.core.commands", "5.0.0");
performProductAction(productFile);
@@ -407,7 +446,7 @@ public class ProductActionTest extends ActionTest {
}
private void setConfiguration(String configSpec) {
- ((PublisherInfo) publisherInfo).setConfigurations(new String[] {configSpec});
+ ((PublisherInfo) publisherInfo).setConfigurations(new String[] { configSpec });
}
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTestMac.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTestMac.java
index a14b660b5..7673a092c 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTestMac.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductActionTestMac.java
@@ -13,30 +13,23 @@
*******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.anyBoolean;
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
import static org.eclipse.equinox.p2.tests.publisher.actions.StatusMatchers.okStatus;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.verify;
import java.io.File;
-import java.util.Collections;
-import org.easymock.Capture;
-import org.easymock.EasyMock;
+import java.util.stream.Collectors;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
-import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
import org.eclipse.equinox.p2.publisher.IPublisherAdvice;
-import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.actions.RootIUAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.IExecutableAdvice;
import org.eclipse.equinox.p2.publisher.eclipse.ProductAction;
import org.eclipse.equinox.p2.publisher.eclipse.ProductFileAdvice;
import org.eclipse.equinox.p2.tests.TestData;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
/**
* Tests for {@link ProductAction} specific to Mac.
@@ -44,30 +37,11 @@ import org.eclipse.equinox.p2.tests.TestData;
public class ProductActionTestMac extends ActionTest {
private File executablesFeatureLocation = null;
- private Capture<RootIUAdvice> rootIUAdviceCapture;
- private Capture<ProductFileAdvice> productFileAdviceCapture;
private String source = "";
@Override
- protected IPublisherInfo createPublisherInfoMock() {
- //override to create a nice mock, because we don't care about other method calls.
- return createNiceMock(IPublisherInfo.class);
- }
-
- @Override
- protected void insertPublisherInfoBehavior() {
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(RootIUAdvice.class), EasyMock.capture(rootIUAdviceCapture)));
- publisherInfo.addAdvice(EasyMock.and(EasyMock.isA(ProductFileAdvice.class), EasyMock.capture(productFileAdviceCapture)));
- //Return an empty list every time getAdvice is called
- expect(publisherInfo.getAdvice((String) anyObject(), anyBoolean(), (String) anyObject(), (Version) anyObject(), (Class<IPublisherAdvice>) anyObject())).andReturn(Collections.emptyList());
- expectLastCall().anyTimes();
- }
-
- @Override
public void setUp() throws Exception {
configSpec = AbstractPublisherAction.createConfigSpec("carbon", "macosx", "x86");
- rootIUAdviceCapture = Capture.newInstance();
- productFileAdviceCapture = Capture.newInstance();
setupPublisherInfo();
setupPublisherResult();
}
@@ -76,13 +50,16 @@ public class ProductActionTestMac extends ActionTest {
* Tests that correct advice is created for the org.eclipse.platform product.
*/
public void testPlatformProduct() throws Exception {
+ ArgumentCaptor<IPublisherAdvice> productFileAdviceCapture = ArgumentCaptor.forClass(IPublisherAdvice.class);
ProductFile productFile = new ProductFile(TestData.getFile("ProductActionTest", "platform.product").toString());
addContextIU("org.eclipse.platform.feature.group", "3.8.3");
- testAction = new ProductAction(source, productFile, flavorArg, executablesFeatureLocation);
+ testAction = Mockito.spy(new ProductAction(source, productFile, flavorArg, executablesFeatureLocation));
IStatus status = testAction.perform(publisherInfo, publisherResult, null);
+ verify(publisherInfo, Mockito.atLeastOnce()).addAdvice(productFileAdviceCapture.capture());
assertThat(status, is(okStatus()));
- IExecutableAdvice launchAdvice = productFileAdviceCapture.getValue();
+ IExecutableAdvice launchAdvice = (IExecutableAdvice) productFileAdviceCapture.getAllValues().stream()
+ .filter(ProductFileAdvice.class::isInstance).collect(Collectors.toList()).get(0);
assertEquals("1.0", "eclipse", launchAdvice.getExecutableName());
String[] programArgs = launchAdvice.getProgramArguments();
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileAdviceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileAdviceTest.java
index 3a93eb59a..91bc64d39 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileAdviceTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileAdviceTest.java
@@ -208,7 +208,7 @@ public class ProductFileAdviceTest extends AbstractProvisioningTest {
configProperties.put("osgi.bundles", "org.eclipse.equinox.simpleconfigurator@1:start");
writeProperties(new File(rootFolder, "config.ini"), configProperties);
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("org.eclipse.equinox.common,3.5.100.v20090817,plugins/org.eclipse.equinox.common_3.5.100.v20090817.jar,2,true\n");
buffer.append("org.eclipse.equinox.simpleconfigurator,1.0.200.v20090729-1800,plugins/org.eclipse.equinox.simpleconfigurator_1.0.200.v20090729-1800.jar,1,true\n");
writeBuffer(new File(rootFolder, "org.eclipse.equinox.simpleconfigurator/bundles.info"), buffer);
@@ -229,7 +229,7 @@ public class ProductFileAdviceTest extends AbstractProvisioningTest {
File root = getTestFolder("configNullLauncher");
File testProduct = new File(root, "test.product");
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
buffer.append("<product id=\"test.product\" version=\"1\" useFeatures=\"false\"> \n");
buffer.append(" <configIni use=\"default\"> \n");
buffer.append(" <win32>config.ini</win32> \n");
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootFilesActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootFilesActionTest.java
index 9fa2a5d65..030cd8b2a 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootFilesActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootFilesActionTest.java
@@ -15,19 +15,30 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.expect;
-
-import java.io.*;
-import java.util.*;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.zip.ZipInputStream;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.publisher.AbstractPublisherAction;
import org.eclipse.equinox.p2.publisher.IPublisherInfo;
-import org.eclipse.equinox.p2.publisher.actions.*;
+import org.eclipse.equinox.p2.publisher.actions.IRootFilesAdvice;
+import org.eclipse.equinox.p2.publisher.actions.ITouchpointAdvice;
+import org.eclipse.equinox.p2.publisher.actions.RootFilesAction;
+import org.eclipse.equinox.p2.publisher.actions.RootFilesAdvice;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.tests.TestActivator;
import org.eclipse.equinox.p2.tests.TestData;
@@ -68,10 +79,13 @@ public class RootFilesActionTest extends ActionTest {
@Override
public void insertPublisherInfoBehavior() {
- expect(publisherInfo.getArtifactRepository()).andReturn(artifactRepository).anyTimes();
- expect(publisherInfo.getArtifactOptions()).andReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH).anyTimes();
- expect(publisherInfo.getAdvice(configSpec, true, null, null, IRootFilesAdvice.class)).andReturn(adviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(configSpec, false, flavorArg + topArg, versionArg, ITouchpointAdvice.class)).andReturn(null).anyTimes();
+ when(publisherInfo.getArtifactRepository()).thenReturn(artifactRepository);
+ when(publisherInfo.getArtifactOptions())
+ .thenReturn(IPublisherInfo.A_INDEX | IPublisherInfo.A_OVERWRITE | IPublisherInfo.A_PUBLISH);
+ when(publisherInfo.getAdvice(configSpec, true, null, null, IRootFilesAdvice.class))
+ .thenReturn(adviceCollection);
+ when(publisherInfo.getAdvice(configSpec, false, flavorArg + topArg, versionArg, ITouchpointAdvice.class))
+ .thenReturn(null);
}
private void setupTestCase(int testArg) throws Exception {
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootIUActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootIUActionTest.java
index 21b4dd4b2..637465c39 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootIUActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/RootIUActionTest.java
@@ -15,7 +15,7 @@
******************************************************************************/
package org.eclipse.equinox.p2.tests.publisher.actions;
-import static org.easymock.EasyMock.expect;
+import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collection;
@@ -358,16 +358,22 @@ public class RootIUActionTest extends ActionTest {
@Override
public void insertPublisherInfoBehavior() {
- expect(publisherInfo.getAdvice(null, false, rootIU, versionArg, ICapabilityAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getAdvice(null, true, null, null, IRootIUAdvice.class)).andReturn(rootIUAdviceCollection).anyTimes();
- expect(publisherInfo.getAdvice(null, true, null, null, IVersionAdvice.class)).andReturn(null).anyTimes();
- expect(publisherInfo.getAdvice(null, false, rootIU, versionArg, ITouchpointAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, rootIU, versionArg, IUpdateDescriptorAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, rootIU, versionArg, IPropertyAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getAdvice(null, false, rootIU, versionArg, IAdditionalInstallableUnitAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getAdvice(null, true, rootIU, versionArg, ILicenseAdvice.class)).andReturn(new ArrayList<>()).anyTimes();
- expect(publisherInfo.getMetadataRepository()).andReturn(metadataRepository).anyTimes();
- expect(publisherInfo.getContextMetadataRepository()).andReturn(null).anyTimes();
+ when(publisherInfo.getAdvice(null, false, rootIU, versionArg, ICapabilityAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, true, null, null, IRootIUAdvice.class)).thenReturn(rootIUAdviceCollection);
+ when(publisherInfo.getAdvice(null, true, null, null, IVersionAdvice.class)).thenReturn(null);
+ when(publisherInfo.getAdvice(null, false, rootIU, versionArg, ITouchpointAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, false, rootIU, versionArg, IUpdateDescriptorAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, false, rootIU, versionArg, IPropertyAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, false, rootIU, versionArg, IAdditionalInstallableUnitAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getAdvice(null, true, rootIU, versionArg, ILicenseAdvice.class))
+ .thenReturn(new ArrayList<>());
+ when(publisherInfo.getMetadataRepository()).thenReturn(metadataRepository);
+ when(publisherInfo.getContextMetadataRepository()).thenReturn(null);
}
@Override
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/reconciler/dropins/AbstractReconcilerTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/reconciler/dropins/AbstractReconcilerTest.java
index f1b090aa9..81d99b186 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/reconciler/dropins/AbstractReconcilerTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/reconciler/dropins/AbstractReconcilerTest.java
@@ -281,7 +281,7 @@ public class AbstractReconcilerTest extends AbstractProvisioningTest {
detailedMessage.append(" install location is ").append(getInstallLocation()).append('\n');
String message = "Need to set the \"org.eclipse.equinox.p2.reconciler.tests.platform.archive\" system property with a valid path to the platform binary drop or copy the archive to be a sibling of the install folder.";
assertNotNull(message + "\n" + detailedMessage, file);
- assertTrue(message, file.exists());
+ assertTrue(message + "\nThe file '" + file.getAbsolutePath() + "' does not exist", file.exists());
assertTrue("File is zero length: " + file.getAbsolutePath(), file.length() > 0);
return file;
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/eclipse/SetLauncherNameActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/eclipse/SetLauncherNameActionTest.java
index de6ddd662..f01f88db3 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/eclipse/SetLauncherNameActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/eclipse/SetLauncherNameActionTest.java
@@ -14,7 +14,9 @@
package org.eclipse.equinox.p2.tests.touchpoint.eclipse;
import java.io.File;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.p2.engine.InstallableUnitOperand;
import org.eclipse.equinox.internal.p2.touchpoint.eclipse.EclipseTouchpoint;
@@ -99,7 +101,7 @@ public class SetLauncherNameActionTest extends AbstractProvisioningTest {
//profile will start using "eclipse" by default, give it some content and see if it
//survives a name change.
File eclipseIni = new File(tempFolder, "eclipse.ini");
- StringBuffer ini = new StringBuffer();
+ StringBuilder ini = new StringBuilder();
ini.append("-startup\n");
ini.append("plugins/org.eclipse.equinox.launcher_1.2.4.v1234.jar\n");
writeBuffer(eclipseIni, ini);
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/generator/Europa/site.xml b/bundles/org.eclipse.equinox.p2.tests/testData/generator/Europa/site.xml
index a9bf0170d..d9102ed21 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/generator/Europa/site.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/generator/Europa/site.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<site digestURL="http://download.eclipse.org/releases/europa/" mirrorsURL="http://www.eclipse.org/downloads/download.php?file=/releases/europa/site.xml&amp;format=xml&amp;protocol=http" pack200="true">
+<site digestURL="https://download.eclipse.org/releases/europa/" mirrorsURL="http://www.eclipse.org/downloads/download.php?file=/releases/europa/site.xml&amp;format=xml&amp;protocol=http" pack200="true">
<description url="http://www.eclipse.org/europa/">
This Europa Discovery Site contains a number of Eclipse based projects
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform.source_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform.source_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
index b9cb4db57..5357a19cc 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform.source_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform.source_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
@@ -10,9 +10,9 @@
%license
</license>
<url>
- <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/releases/europa"/>
+ <update label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%secondaryUpdateSiteName" url="https://download.eclipse.org/releases/europa"/>
</url>
<includes id="org.eclipse.rcp.source" version="3.3.0.v20070607-8y8eE8NEbsN3X_fjWS8HPNG"/>
<plugin fragment="false" unpack="false" download-size="0" install-size="0" id="org.eclipse.platform.doc.isv" version="3.3.0.v20070621"/>
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
index e4974b851..8f1ffb44d 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.platform_3.3.0.v20070612-_19UEkLEzwsdF9jSqQ-G/feature.xml
@@ -19,9 +19,9 @@
</license>
<url>
- <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/releases/europa"/>
+ <update label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%secondaryUpdateSiteName" url="https://download.eclipse.org/releases/europa"/>
</url>
<plugin
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.sdk_3.3.0.v20070607-7M7J-BIolz-OcxWxvWAPSfLPqevO/feature.xml b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.sdk_3.3.0.v20070607-7M7J-BIolz-OcxWxvWAPSfLPqevO/feature.xml
index 0b59abbde..87abcbbfd 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.sdk_3.3.0.v20070607-7M7J-BIolz-OcxWxvWAPSfLPqevO/feature.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/generator/eclipse3.3/features/org.eclipse.sdk_3.3.0.v20070607-7M7J-BIolz-OcxWxvWAPSfLPqevO/feature.xml
@@ -19,9 +19,9 @@
</license>
<url>
- <update label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%updateSiteName" url="http://update.eclipse.org/updates/3.3"/>
- <discovery label="%secondaryUpdateSiteName" url="http://download.eclipse.org/releases/europa"/>
+ <update label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%updateSiteName" url="https://update.eclipse.org/updates/3.3"/>
+ <discovery label="%secondaryUpdateSiteName" url="https://download.eclipse.org/releases/europa"/>
</url>
<includes
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/importexport/unknownformat.p2f b/bundles/org.eclipse.equinox.p2.tests/testData/importexport/unknownformat.p2f
index 9ae98bf32..56e172939 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/importexport/unknownformat.p2f
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/importexport/unknownformat.p2f
@@ -131,7 +131,7 @@
</unit>
</units>
<repositories>
- <repository uri='http://download.eclipse.org/releases/helios'/>
+ <repository uri='https://download.eclipse.org/releases/helios'/>
<repository uri='file:/folk/kzhu0/tmp/plugins/'/>
<repository uri='http://hge.javaforge.com/hgeclipse'/>
</repositories>
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/mirror/mirrorSourceRepoWithRefs/content.xml b/bundles/org.eclipse.equinox.p2.tests/testData/mirror/mirrorSourceRepoWithRefs/content.xml
index 3a3575af8..d53fba1e4 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/mirror/mirrorSourceRepoWithRefs/content.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/mirror/mirrorSourceRepoWithRefs/content.xml
@@ -6,10 +6,10 @@
<property name='p2.timestamp' value='1222693511921'/>
</properties>
<references size='4'>
- <repository uri='http://download.eclipse.org/eclipse/updates/3.5/' url='http://download.eclipse.org/eclipse/updates/3.5/' type='0' options='0'/>
- <repository uri='http://download.eclipse.org/eclipse/updates/3.5/' url='http://download.eclipse.org/eclipse/updates/3.5/' type='1' options='0'/>
- <repository uri='http://download.eclipse.org/eclipse/updates/3.6/' url='http://download.eclipse.org/eclipse/updates/3.6/' type='0' options='0'/>
- <repository uri='http://download.eclipse.org/eclipse/updates/3.6/' url='http://download.eclipse.org/eclipse/updates/3.6/' type='1' options='0'/>
+ <repository uri='https://download.eclipse.org/eclipse/updates/3.5/' url='https://download.eclipse.org/eclipse/updates/3.5/' type='0' options='0'/>
+ <repository uri='https://download.eclipse.org/eclipse/updates/3.5/' url='https://download.eclipse.org/eclipse/updates/3.5/' type='1' options='0'/>
+ <repository uri='https://download.eclipse.org/eclipse/updates/3.6/' url='https://download.eclipse.org/eclipse/updates/3.6/' type='0' options='0'/>
+ <repository uri='https://download.eclipse.org/eclipse/updates/3.6/' url='https://download.eclipse.org/eclipse/updates/3.6/' type='1' options='0'/>
</references>
<units size='8'>
<unit id='helloworldfeature.feature.jar' version='1.0.1'>
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/pausefeature/artifacts.xml b/bundles/org.eclipse.equinox.p2.tests/testData/pausefeature/artifacts.xml
index baf533cae..a9f083ecd 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/pausefeature/artifacts.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/pausefeature/artifacts.xml
@@ -12,14 +12,14 @@
</properties>
<mappings size='5'>
<rule filter='(&amp; (classifier=osgi.bundle) (format=packed))'
- output='http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/${id}_${version}.jar.pack.gz' />
- <rule filter='(&amp; (classifier=osgi.bundle))' output='http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/${id}_${version}.jar' />
- <rule filter='(&amp; (classifier=binary))' output='http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/binary/${id}_${version}' />
+ output='https://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/${id}_${version}.jar.pack.gz' />
+ <rule filter='(&amp; (classifier=osgi.bundle))' output='https://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/plugins/${id}_${version}.jar' />
+ <rule filter='(&amp; (classifier=binary))' output='https://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/binary/${id}_${version}' />
<rule
filter='(&amp; (classifier=org.eclipse.update.feature) (format=packed))'
- output='http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/features/${id}_${version}.jar.pack.gz' />
+ output='https://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/features/${id}_${version}.jar.pack.gz' />
<rule filter='(&amp; (classifier=org.eclipse.update.feature))'
- output='http://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/features/${id}_${version}.jar' />
+ output='https://download.eclipse.org/eclipse/updates/3.7/R-3.7.2-201202080800/features/${id}_${version}.jar' />
</mappings>
<artifacts size='13433'>
<artifact classifier='binary'
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/pgp/signer2-publickey.asc b/bundles/org.eclipse.equinox.p2.tests/testData/pgp/signer2-publickey.asc
new file mode 100644
index 000000000..0218bdce7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/pgp/signer2-publickey.asc
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGHUyxYBEADATeNx4XA4H2fP9mD5xwlIyh7qvHLezgXpqCwNS9ATqBwnfrCV
+06a+pfSLsLoXrP/sdaB5WhijfuxTis18RMfoDVwGMRqyD2GiBCl2vwJDg3BUwHnc
+H7W6XkWKO7dkPmF+TUbD3cTWZ7cvrPmMjinmXaq8htuktGuE2VEGZRnuG1m+ChDM
+PnSb1ioFS2+MJv13P2fagVk2qC95DkPJGpMk3CY3ghLDEaY/KaJl+8axAlUUUk9N
+d3k/KVxxf5k3g26EVQkWWgH2mmolptGO101xW64iked97Cy4NK2yafOF/wmpsavx
+PGpOewnDgAJBBPkum6mPH0vcOZgxmLyh4uqfPfr3IaBQlbJLN2dXaDsV83j5t1wZ
+2qxOPcWBfORm6W7dC0TQgCXbEG0geMBpJtvnMX83Q2ORqDpjbHRJsV2k+8NxaXON
+pYXGr+Lj/9n0xfNEDXhCdGab0XP2tVZ5jfr2OQ5dAomEaPqK5Kq7akoWMddpDLNC
+G4IvH8G0cxwruJk00uwd6Nd2NVqVMRYCsBbA89VanUnutLUIpVnnOAetlX9blXHO
+JtmiCPGgHyp+iYGhKYVzfuZQyFhonbi0AhidJDvbHsoLT3p4Mcog1B9y6MODBE7R
+jwrU+qMqYsYeFhGYKbYyXv9TfEyUvtCQ/GnTtRJAQyicFdOdbK37WecS6QARAQAB
+tDdFY2xpcHNlIHAyIHRlc3QgU2lnbmVyIDIgPHNpZ25lcjJAZmFrZXVzZXIuZWNs
+aXBzZS5vcmc+iQJYBBMBCABCFiEEzZ1aK4a8T+GDlFHh4vaU9BsKs3AFAmHUyxYC
+GwMFCQPCZwAFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJEOL2lPQbCrNw
+wH4QAIiCaw1mREgt4ldz7hQvmGxdMuQwVKZPzbOIAlYbZBo0q9SmeMf/CBCO90hg
+LFmJmsZV4KUU5NKI7UwkDVrpUCl00Ok6+gtiUTId2tRcwXI+25I478VX27j6OkQj
+7Xr6giv8cn8nstt5CF6xxeqrxvpmnZC0u30jE6CL6SdXSd0vViFDPQj3KgGJCRc9
+St+LHB3XJTsadihzQnscqI4E2i5Z3Uj1GogqxtR59M1NAXubl5dySM0qHhwn8O+6
+lcgCCeuyMLLde1M1v8w07jdRUM+IFqHrRnE89EPH3MQeZbQ3UfFXK2r7wx2BJCqL
+Irtn68kz834ByKchGR6DqaAw0q+iF2QkgzYxpwai41BgmtUCYnj+HxQNIF4KTzDe
+nd8mDAPWttGCoVuV2Tyu9peYOaqyAZ2PZwUEH5MqihPCbenU17RLXzRu/IT/SH47
+NGrN3yKGgLZr2EVWPWFibpoxP4G4NUCHsY75uiL2EWPVSjK/+OOeHIE5k3U3lYwB
+7clhBwMkIhQHJ+a0SHRkKixkwrQDw4veKY4LaD0NCBLHFoV5L9orH1ToGM729kr/
++4I1VQFkL3KvfLjmRbTUgwHeqEquQ96JtqowbNwlpujfHXQKDNsuiKGP5OazXll5
+sH2CR7e4ePqhhzxjLvi9e/79Khq+08eqllS3rs06EXEAJYTo
+=807V
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/updatesite/CategoryXMLActionTest/associateSites.xml b/bundles/org.eclipse.equinox.p2.tests/testData/updatesite/CategoryXMLActionTest/associateSites.xml
index 1238ec316..bddf9e047 100644
--- a/bundles/org.eclipse.equinox.p2.tests/testData/updatesite/CategoryXMLActionTest/associateSites.xml
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/updatesite/CategoryXMLActionTest/associateSites.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<associateSites>
-<associateSite url="http://download.eclipse.org/eclipse/updates/3.5" label="Eclipse Project Update Site"/>
+<associateSite url="https://download.eclipse.org/eclipse/updates/3.5" label="Eclipse Project Update Site"/>
<associateSite url="This is a bogus URI" label="broken"/>
</associateSites> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.testserver/pom.xml b/bundles/org.eclipse.equinox.p2.testserver/pom.xml
index 5310f6302..15046df14 100644
--- a/bundles/org.eclipse.equinox.p2.testserver/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.testserver/pom.xml
@@ -4,7 +4,7 @@
<parent>
<artifactId>org.eclipse.equinox.p2.tests-parent</artifactId>
<groupId>org.eclipse</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html
index c07f8d265..9f1800e6e 100644
--- a/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html
@@ -8,10 +8,10 @@ log in. The credentials are: user: <b>Aladdin</b>, password: <b>open sesame</b>.
<a href="http://localhost:8080/private/index.html">here</a></p>
<p>The following real content is registered:</p>
<ul>
-<li>/proxy/private/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but requires authentication.</li>
-<li>/proxy/public/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, (useful in redirects).</li>
-<li>/proxy/never/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but always fail authentication.</li>
-<li>/proxy/flipFlop/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but fails authentication every second attempt.</li>
+<li>/proxy/private/ - goes to https://download.eclipse.org/eclipse/updates/3.4, but requires authentication.</li>
+<li>/proxy/public/ - goes to https://download.eclipse.org/eclipse/updates/3.4, (useful in redirects).</li>
+<li>/proxy/never/ - goes to https://download.eclipse.org/eclipse/updates/3.4, but always fail authentication.</li>
+<li>/proxy/flipFlop/ - goes to https://download.eclipse.org/eclipse/updates/3.4, but fails authentication every second attempt.</li>
<li>/proxy/truncated - goes to updates/3.4, but truncates all files</li>
<li>/proxy/molested - goes to updates/3.4, but generates gibberish for all files</li>
<li>/proxy/decelerate - goes to updates/3.4, but delivers files in very small delayed packets - delay increases.</li>
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/pom.xml b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/pom.xml
index 2fb3c4137..7fff2566e 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.eclipse/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
index fa30088a2..3e794a0db 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.touchpoint.natives;singleton:=true
-Bundle-Version: 1.4.200.qualifier
+Bundle-Version: 1.4.300.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.touchpoint.natives.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml b/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
index ccb91e06b..f90831920 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.touchpoint.natives</artifactId>
- <version>1.4.200-SNAPSHOT</version>
+ <version>1.4.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
index a7204930b..298d24fa7 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/messages.properties
@@ -33,7 +33,7 @@ BackupStore_manual_restore_needed=Restore failed: {0}. Manual restore of backup
BackupStore_missing_backup_directory=Missing backup directory - can not restore: {0}
BackupStore_not_a_directory=File is not a directory: {0}
BlockMacUpdate_0=Installation impossible
-BlockMacUpdate_1=The installation/update you are trying to perform can not be completed because of structural changes to Eclipse. The installation/update will stop and will leave your existing Eclipse installation intact. You need to retrieve a new version of Eclipse from http://download.eclipse.org/.
+BlockMacUpdate_1=The installation/update you are trying to perform can not be completed because of structural changes to Eclipse. The installation/update will stop and will leave your existing Eclipse installation intact. You need to retrieve a new version of Eclipse from https://download.eclipse.org/.
action_0_status=The action {0} was performed.
action_0_failed_on_file_1_reason_2=The action {0} on file {1} failed. Reason: {2}
diff --git a/bundles/org.eclipse.equinox.p2.transport.ecf/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.transport.ecf/META-INF/MANIFEST.MF
index 9d7b3fde5..31f2492ff 100644
--- a/bundles/org.eclipse.equinox.p2.transport.ecf/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.transport.ecf/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.transport.ecf
-Bundle-Version: 1.3.200.qualifier
+Bundle-Version: 1.3.300.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.ecf;bundle-version="3.1.0",
org.eclipse.ecf.filetransfer;bundle-version="4.0.0",
diff --git a/bundles/org.eclipse.equinox.p2.transport.ecf/pom.xml b/bundles/org.eclipse.equinox.p2.transport.ecf/pom.xml
index 34c1bcac3..7d8611d3e 100644
--- a/bundles/org.eclipse.equinox.p2.transport.ecf/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.transport.ecf/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.transport.ecf</artifactId>
- <version>1.3.200-SNAPSHOT</version>
+ <version>1.3.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/Activator.java b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/Activator.java
index d0e8b4e7b..7b6649c20 100644
--- a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/Activator.java
+++ b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/Activator.java
@@ -16,6 +16,7 @@
******************************************************************************/
package org.eclipse.equinox.internal.p2.transport.ecf;
+import java.util.Optional;
import org.eclipse.ecf.filetransfer.service.IRetrieveFileTransferFactory;
import org.eclipse.ecf.provider.filetransfer.IFileTransferProtocolToFactoryMapper;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
@@ -173,4 +174,18 @@ public class Activator implements BundleActivator {
return false;
}
+ public static String getProperty(String key) {
+ if (context != null) {
+ return context.getProperty(key);
+ }
+ return System.getProperty(key);
+ }
+
+ public static Optional<Version> getVersion() {
+ return Optional.ofNullable(context) //
+ .map(BundleContext::getBundle) //
+ .or(() -> Optional.ofNullable(FrameworkUtil.getBundle(FileReader.class)))//
+ .map(Bundle::getVersion);
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java
index 8a45c5486..cfca3d832 100644
--- a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java
+++ b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileInfoReader.java
@@ -163,7 +163,7 @@ public class FileInfoReader extends Job implements IRemoteFileSystemListener {
try {
container = ContainerFactory.getDefault().createContainer();
} catch (ContainerCreateException e) {
- throw RepositoryStatusHelper.fromMessage(Messages.ecf_configuration_error);
+ throw RepositoryStatusHelper.fromExceptionMessage(e ,Messages.ecf_configuration_error);
}
IRemoteFileSystemBrowserContainerAdapter adapter = container.getAdapter(IRemoteFileSystemBrowserContainerAdapter.class);
diff --git a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileReader.java b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileReader.java
index 97c7e2fb4..7d95289f4 100644
--- a/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileReader.java
+++ b/bundles/org.eclipse.equinox.p2.transport.ecf/src/org/eclipse/equinox/internal/p2/transport/ecf/FileReader.java
@@ -34,7 +34,7 @@ import org.eclipse.equinox.internal.p2.repository.*;
import org.eclipse.equinox.internal.p2.repository.Messages;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.Version;
/**
* FileReader is an ECF FileTransferJob implementation.
@@ -64,11 +64,11 @@ public final class FileReader extends FileTransferJob implements IFileTransferLi
static Map<String, Map<String, String>> options;
static private String getProperty(String key, String defaultValue) {
- String value = FrameworkUtil.getBundle(FileReader.class).getBundleContext().getProperty(key);
- if (value == null) {
- value = defaultValue;
+ String value = Activator.getProperty(key);
+ if (value != null) {
+ return value;
}
- return value;
+ return defaultValue;
}
static {
@@ -80,7 +80,7 @@ public final class FileReader extends FileTransferJob implements IFileTransferLi
String osgiArch = getProperty("org.osgi.framework.processor", "unknownArch");//$NON-NLS-1$//$NON-NLS-2$
String language = getProperty("osgi.nl", "unknownLanguage");//$NON-NLS-1$//$NON-NLS-2$
String osVersion = getProperty("org.osgi.framework.os.version", "unknownOSVersion"); //$NON-NLS-1$ //$NON-NLS-2$
- String p2Version = FrameworkUtil.getBundle(FileReader.class).getVersion().toString();
+ String p2Version = Activator.getVersion().map(Version::toString).orElse("unknownVersion"); //$NON-NLS-1$
userAgent = "p2/" + p2Version + " (Java " + javaSpec + ' ' + javaVendor + "; " + osName + ' ' + osVersion + ' ' //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ osgiArch + "; " + language + ") "; //$NON-NLS-1$ //$NON-NLS-2$
String userAgentProvided = getProperty("p2.userAgent", null); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/META-INF/MANIFEST.MF
index a48a7e72a..78f885414 100644
--- a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-Name: %bundleName
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-SymbolicName: org.eclipse.equinox.p2.ui.admin.rcp; singleton:=true
-Bundle-Version: 1.3.100.qualifier
+Bundle-Version: 1.3.200.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.ui.admin.rcp.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.ui,
diff --git a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/pom.xml b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/pom.xml
index 9ac0df9f6..be007c637 100644
--- a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.ui.admin.rcp</artifactId>
- <version>1.3.100-SNAPSHOT</version>
+ <version>1.3.200-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/rcp.product b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/rcp.product
index 5c61916cd..9ba3bcdc0 100644
--- a/bundles/org.eclipse.equinox.p2.ui.admin.rcp/rcp.product
+++ b/bundles/org.eclipse.equinox.p2.ui.admin.rcp/rcp.product
@@ -165,7 +165,7 @@ Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in t
<plugin id="org.eclipse.core.filesystem.macosx" fragment="true"/>
<plugin id="org.eclipse.core.jobs"/>
<plugin id="org.eclipse.core.net"/>
- <plugin id="org.eclipse.core.net.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.core.net.linux" fragment="true"/>
<plugin id="org.eclipse.core.resources"/>
<plugin id="org.eclipse.core.runtime"/>
<plugin id="org.eclipse.e4.core.commands"/>
@@ -239,7 +239,7 @@ Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in t
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.security.macosx" fragment="true"/>
<plugin id="org.eclipse.equinox.security.ui"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
diff --git a/bundles/org.eclipse.equinox.p2.ui.admin/pom.xml b/bundles/org.eclipse.equinox.p2.ui.admin/pom.xml
index cac9c880a..af1847806 100644
--- a/bundles/org.eclipse.equinox.p2.ui.admin/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.admin/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/pom.xml b/bundles/org.eclipse.equinox.p2.ui.discovery/pom.xml
index 19b456343..54fa0b47d 100644
--- a/bundles/org.eclipse.equinox.p2.ui.discovery/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.ui.importexport/pom.xml b/bundles/org.eclipse.equinox.p2.ui.importexport/pom.xml
index c55bcd02f..0d01faecf 100644
--- a/bundles/org.eclipse.equinox.p2.ui.importexport/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.importexport/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF
index 93ad2243d..f6a0f04ed 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.equinox.p2.ui.sdk.scheduler;singleton:=true
-Bundle-Version: 1.5.200.qualifier
+Bundle-Version: 1.5.300.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/pom.xml b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/pom.xml
index c8360feff..f5f8a49f1 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.ui.sdk.scheduler</artifactId>
- <version>1.5.200-SNAPSHOT</version>
+ <version>1.5.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
index 504202512..6d56f31c9 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/AutomaticUpdateScheduler.java
@@ -33,6 +33,7 @@ import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IStartup;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;
/**
@@ -54,8 +55,6 @@ public class AutomaticUpdateScheduler implements IStartup {
private IUpdateListener listener;
private IUpdateChecker checker;
- private IProvisioningAgent agent;
-
@Override
public void earlyStartup() {
AutomaticUpdatePlugin.getDefault().setScheduler(this);
@@ -64,7 +63,13 @@ public class AutomaticUpdateScheduler implements IStartup {
@Override
protected IStatus run(IProgressMonitor monitor) {
- agent = ServiceHelper.getService(AutomaticUpdatePlugin.getContext(), IProvisioningAgent.class);
+ IProvisioningAgent agent = ServiceHelper.getService(AutomaticUpdatePlugin.getContext(),
+ IProvisioningAgent.class);
+ if (agent == null) {
+ String message = "No provisioning agent service found"; //$NON-NLS-1$
+ AutomaticUpdatePlugin.getDefault().getLog().warn(message, new IllegalStateException(message));
+ return Status.CANCEL_STATUS;
+ }
IProfileRegistry registry = agent.getService(IProfileRegistry.class);
IProfile currentProfile = registry.getProfile(IProfileRegistry.SELF);
if (currentProfile != null
@@ -72,7 +77,7 @@ public class AutomaticUpdateScheduler implements IStartup {
return Status.OK_STATUS;
}
- removeUnusedPlugins(registry);
+ removeUnusedPlugins(registry, agent);
scheduleUpdate();
return Status.OK_STATUS;
}
@@ -81,6 +86,11 @@ public class AutomaticUpdateScheduler implements IStartup {
public boolean belongsTo(Object family) {
return AutomaticUpdateScheduler.class == family;
}
+
+ @Override
+ public boolean shouldRun() {
+ return PlatformUI.isWorkbenchRunning();
+ }
};
updateJob.setSystem(true);
@@ -92,8 +102,9 @@ public class AutomaticUpdateScheduler implements IStartup {
* Invokes the garbage collector to discard unused plugins, if specified by a
* corresponding preference.
*
+ * @param agent non null
*/
- private void removeUnusedPlugins(IProfileRegistry registry) {
+ private void removeUnusedPlugins(IProfileRegistry registry, IProvisioningAgent agent) {
// check if gc is enabled
IPreferenceStore pref = AutomaticUpdatePlugin.getDefault().getPreferenceStore();
if (!pref.getBoolean(PreferenceConstants.PREF_GC_ON_STARTUP)) {
@@ -149,10 +160,12 @@ public class AutomaticUpdateScheduler implements IStartup {
}
};
- IProvisioningAgent pagent = agent;
+ IProvisioningAgent pagent = ServiceHelper.getService(AutomaticUpdatePlugin.getContext(),
+ IProvisioningAgent.class);
if (pagent == null) {
- // Job not executed yet
- pagent = ServiceHelper.getService(AutomaticUpdatePlugin.getContext(), IProvisioningAgent.class);
+ String message = "No provisioning agent service found"; //$NON-NLS-1$
+ AutomaticUpdatePlugin.getDefault().getLog().warn(message, new IllegalStateException(message));
+ return;
}
checker = pagent.getService(IUpdateChecker.class);
if (checker == null) {
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
index 988cfdd1b..4293409db 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.equinox.p2.ui.sdk;singleton:=true
-Bundle-Version: 1.2.3.qualifier
+Bundle-Version: 1.2.4.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.ui.sdk.ProvSDKUIActivator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -16,15 +16,16 @@ Import-Package: javax.xml.parsers,
org.bouncycastle.openpgp;version="1.69.0",
org.eclipse.compare;resolution:=optional,
org.eclipse.compare.structuremergeviewer;resolution:=optional,
+ org.eclipse.equinox.internal.p2.artifact.processors.pgp,
org.eclipse.equinox.internal.p2.engine.phases,
org.eclipse.equinox.p2.core;version="[2.0.0,3.0.0)",
- org.eclipse.equinox.internal.p2.artifact.processors.pgp,
org.eclipse.equinox.p2.engine;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.engine.query;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.metadata;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.operations;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.planner;version="2.0.0",
org.eclipse.equinox.p2.query;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.repository.spi;version="2.0.0",
org.eclipse.osgi.util;version="1.1.0",
org.osgi.framework;version="1.6.0",
org.w3c.dom,
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml b/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml
index 32f6d437e..bcca1f5ac 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml
@@ -4,11 +4,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.ui.sdk</artifactId>
- <version>1.2.3-SNAPSHOT</version>
+ <version>1.2.4-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java
index bf0a1956c..26d979317 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java
@@ -52,12 +52,30 @@ public class ProvSDKMessages extends NLS {
public static String RemediationOperation_ResolveJobTask;
public static String TrustPreferencePage_title;
public static String TrustPreferencePage_export;
- public static String TrustPreferencePage_idColumn;
- public static String TrustPreferencePage_userColumn;
public static String TrustPreferencePage_fileExportTitle;
public static String TrustPreferencePage_pgpIntro;
public static String TrustPreferencePage_fileImportTitle;
public static String TrustPreferencePage_addPGPKeyButtonLabel;
+ public static String TrustPreferencePage_Contributor;
+ public static String TrustPreferencePage_CopyFingerprint;
+ public static String TrustPreferencePage_DataValidExpires;
+ public static String TrustPreferencePage_DateExpired;
+ public static String TrustPreferencePage_DateExpiredSince;
+ public static String TrustPreferencePage_DateNotYetvalid;
+ public static String TrustPreferencePage_DateNotYetValid;
+ public static String TrustPreferencePage_DateValid;
+ public static String TrustPreferencePage_Details;
+ public static String TrustPreferencePage_Export;
+ public static String TrustPreferencePage_FingerprintIdColumn;
+ public static String TrustPreferencePage_NameColumn;
+ public static String TrustPreferencePage_PreferenceContributor;
public static String TrustPreferencePage_removePGPKeyButtonLabel;
+ public static String TrustPreferencePage_TrustAll;
+ public static String TrustPreferencePage_TrustAllConfirmationDescription;
+ public static String TrustPreferencePage_TrustAllConfirmationTitle;
+ public static String TrustPreferencePage_TrustAllNo;
+ public static String TrustPreferencePage_TrustAllYes;
+ public static String TrustPreferencePage_TypeColumn;
+ public static String TrustPreferencePage_ValidityColumn;
}
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java
index 417ba2d68..bb0ef513e 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java
@@ -10,33 +10,60 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.sdk;
+import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
+
import java.io.*;
-import java.util.ArrayList;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.cert.*;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
import java.util.List;
+import java.util.function.Function;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPPublicKey;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPPublicKeyStore;
import org.eclipse.equinox.internal.p2.engine.phases.CertificateChecker;
-import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
-import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.equinox.internal.p2.ui.dialogs.PGPPublicKeyViewDialog;
+import org.eclipse.equinox.internal.p2.ui.viewers.CertificateLabelProvider;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.engine.IProfileRegistry;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.widgets.LabelFactory;
+import org.eclipse.jface.widgets.WidgetFactory;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
public class TrustPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+ private static final String EXPORT_FILTER_PATH = "exportFilterPath"; //$NON-NLS-1$
+ private static final String ADD_FILTER_PATH = "addFilterPath"; //$NON-NLS-1$
+
private CertificateChecker certificateChecker;
+ private Set<Certificate> trustedCertificates;
private PGPPublicKeyStore trustedKeys;
- private boolean dirty = false;
+ private Map<PGPPublicKey, Set<Bundle>> contributedTrustedKeys;
+ private boolean dirty;
private TableViewer viewer;
public TrustPreferencePage() {
@@ -50,108 +77,324 @@ public class TrustPreferencePage extends PreferencePage implements IWorkbenchPre
@Override
protected Control createContents(Composite parent) {
+ IProvisioningAgent provisioningAgent = ProvSDKUIActivator.getDefault().getProvisioningAgent();
+ certificateChecker = new CertificateChecker(provisioningAgent);
+ certificateChecker
+ .setProfile(provisioningAgent.getService(IProfileRegistry.class).getProfile(IProfileRegistry.SELF));
+ trustedCertificates = new LinkedHashSet<>(certificateChecker.getPreferenceTrustedCertificates());
+ contributedTrustedKeys = certificateChecker.getContributedTrustedKeys();
+ trustedKeys = certificateChecker.getPreferenceTrustedKeys();
+
Composite res = new Composite(parent, SWT.NONE);
+ res.setLayout(new GridLayout(2, false));
- Label pgpLabel = new Label(res, SWT.WRAP);
- pgpLabel.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1));
- pgpLabel.setText(ProvSDKMessages.TrustPreferencePage_pgpIntro);
+ // Ensure that the message supports wrapping for a long text message.
+ GridData data = new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1);
+ data.widthHint = convertWidthInCharsToPixels(90);
+ LabelFactory factory = WidgetFactory.label(SWT.WRAP).text(ProvSDKMessages.TrustPreferencePage_pgpIntro)
+ .font(parent.getFont()).layoutData(data);
+ factory.create(res);
- res.setLayout(new GridLayout(2, false));
- viewer = new TableViewer(res);
- viewer.getTable().setHeaderVisible(true);
+ TableColumnLayout tableColumnLayout = new TableColumnLayout();
+ Composite tableComposite = WidgetFactory.composite(SWT.NONE)
+ .layoutData(new GridData(SWT.FILL, SWT.FILL, true, true)).layout(tableColumnLayout).create(res);
+ Table keyTable = WidgetFactory.table(SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION)
+ .headerVisible(true).linesVisible(true).font(parent.getFont()).create(tableComposite);
+ viewer = new TableViewer(keyTable);
+ keyTable.setHeaderVisible(true);
viewer.setContentProvider(new ArrayContentProvider());
- TableViewerColumn idColumn = new TableViewerColumn(viewer, SWT.NONE);
- idColumn.setLabelProvider(new ColumnLabelProvider() {
- @Override
- public String getText(Object element) {
- return Long.toHexString(((PGPPublicKey) element).getKeyID()).toUpperCase();
+
+ // This column is packed later.
+ TableViewerColumn typeColumn = createColumn(viewer, ProvSDKMessages.TrustPreferencePage_TypeColumn,
+ key -> "PGP", cert -> "x509", tableColumnLayout, 1); //$NON-NLS-1$ //$NON-NLS-2$
+
+ createColumn(viewer, ProvSDKMessages.TrustPreferencePage_FingerprintIdColumn,
+ key -> PGPPublicKeyService.toHexFingerprint(key),
+ cert -> cert.getSerialNumber().toString(), tableColumnLayout, 10);
+
+ createColumn(viewer, ProvSDKMessages.TrustPreferencePage_NameColumn, key -> {
+ List<String> userIds = new ArrayList<>();
+ key.getUserIDs().forEachRemaining(userIds::add);
+ return String.join(", ", userIds); //$NON-NLS-1$
+ }, cert -> CertificateLabelProvider.getText(cert), tableColumnLayout, 15);
+
+ createColumn(viewer, ProvSDKMessages.TrustPreferencePage_Contributor, key -> {
+ {
+ Set<String> contributors = new LinkedHashSet<>();
+ if (trustedKeys.all().contains(key)) {
+ contributors.add(ProvSDKMessages.TrustPreferencePage_PreferenceContributor);
+ }
+ Set<Bundle> bundles = contributedTrustedKeys.get(key);
+ if (bundles != null) {
+ Set<String> bundleContributors = new TreeSet<>(Policy.getComparator());
+ bundles.stream().map(bundle -> getBundleName(bundle)).forEach(bundleContributors::add);
+ contributors.addAll(bundleContributors);
+ }
+ return String.join(", ", contributors); //$NON-NLS-1$
}
- });
- idColumn.getColumn().setWidth(16 * 10); // number of chars in a key Id * some heuristic of width
- idColumn.getColumn().setText(ProvSDKMessages.TrustPreferencePage_idColumn);
- TableViewerColumn userColumn = new TableViewerColumn(viewer, SWT.NONE);
- userColumn.setLabelProvider(new ColumnLabelProvider() {
- @Override
- public String getText(Object element) {
- List<String> userIds = new ArrayList<>();
- ((PGPPublicKey) element).getUserIDs().forEachRemaining(userIds::add);
- return String.join(",", userIds); //$NON-NLS-1$
+ }, cert -> ProvSDKMessages.TrustPreferencePage_PreferenceContributor, tableColumnLayout,
+ contributedTrustedKeys.isEmpty() ? 8 : 15);
+
+ createColumn(viewer, ProvSDKMessages.TrustPreferencePage_ValidityColumn, pgp -> {
+ if (pgp.getCreationTime().after(Date.from(Instant.now()))) {
+ return NLS.bind(ProvSDKMessages.TrustPreferencePage_DateNotYetValid, pgp.getCreationTime());
}
- });
- userColumn.getColumn().setWidth(400);
- userColumn.getColumn().setText(ProvSDKMessages.TrustPreferencePage_userColumn);
- viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- certificateChecker = new CertificateChecker(ProvSDKUIActivator.getDefault().getProvisioningAgent());
- trustedKeys = certificateChecker.buildPGPTrustore();
- viewer.setInput(trustedKeys.all());
+ long validSeconds = pgp.getValidSeconds();
+ if (validSeconds == 0) {
+ return ProvSDKMessages.TrustPreferencePage_DateValid;
+ }
+ Instant expires = pgp.getCreationTime().toInstant().plus(validSeconds, ChronoUnit.SECONDS);
+ return expires.isBefore(Instant.now())
+ ? NLS.bind(ProvSDKMessages.TrustPreferencePage_DateExpiredSince, expires)
+ : NLS.bind(ProvSDKMessages.TrustPreferencePage_DataValidExpires, expires);
+ }, x509 -> {
+ try {
+ x509.checkValidity();
+ return ProvSDKMessages.TrustPreferencePage_DateValid;
+ } catch (CertificateExpiredException expired) {
+ return ProvSDKMessages.TrustPreferencePage_DateExpired;
+ } catch (CertificateNotYetValidException notYetValid) {
+ return ProvSDKMessages.TrustPreferencePage_DateNotYetvalid;
+ }
+ }, tableColumnLayout, 8);
+
+ updateInput();
+
Composite buttonComposite = createVerticalButtonBar(res);
buttonComposite.setLayoutData(new GridData(SWT.DEFAULT, SWT.BEGINNING, false, false));
+
Button exportButton = new Button(buttonComposite, SWT.PUSH);
exportButton.setText(ProvSDKMessages.TrustPreferencePage_export);
setVerticalButtonLayoutData(exportButton);
+ exportButton.setEnabled(false);
+
exportButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
- PGPPublicKey key = getSelectedKey();
- if (key == null) {
- return;
- }
+ Object element = viewer.getStructuredSelection().getFirstElement();
FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
+ dialog.setFilterPath(getFilterPath(EXPORT_FILTER_PATH));
dialog.setText(ProvSDKMessages.TrustPreferencePage_fileExportTitle);
dialog.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$
- dialog.setFileName(Long.toHexString(key.getKeyID()).toUpperCase() + ".asc"); //$NON-NLS-1$
- String path = dialog.open();
- if (path == null) {
- return;
- }
- File destinationFile = new File(path);
- try (OutputStream output = new ArmoredOutputStream(new FileOutputStream(destinationFile))) {
- output.write(key.getEncoded());
- } catch (IOException ex) {
- ProvSDKUIActivator.getDefault().getLog()
- .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ FileDialog destination = new FileDialog(exportButton.getShell(), SWT.SAVE);
+ destination.setFilterPath(getFilterPath(EXPORT_FILTER_PATH));
+ destination.setText(ProvSDKMessages.TrustPreferencePage_Export);
+ if (element instanceof X509Certificate) {
+ X509Certificate cert = (X509Certificate) element;
+ destination.setFilterExtensions(new String[] { "*.der" }); //$NON-NLS-1$
+ destination.setFileName(cert.getSerialNumber().toString() + ".der"); //$NON-NLS-1$
+ String path = destination.open();
+ setFilterPath(EXPORT_FILTER_PATH, destination.getFilterPath());
+ if (path == null) {
+ return;
+ }
+ File destinationFile = new File(path);
+ try (FileOutputStream output = new FileOutputStream(destinationFile)) {
+ output.write(cert.getEncoded());
+ } catch (IOException | CertificateEncodingException ex) {
+ ProvSDKUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvSDKUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ }
+ } else {
+ PGPPublicKey key = (PGPPublicKey) element;
+ destination.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$
+ destination.setFileName(PGPPublicKeyService.toHexFingerprint(key) + ".asc"); //$NON-NLS-1$
+ String path = destination.open();
+ setFilterPath(EXPORT_FILTER_PATH, destination.getFilterPath());
+ if (path == null) {
+ return;
+ }
+ File destinationFile = new File(path);
+ try (OutputStream output = new ArmoredOutputStream(new FileOutputStream(destinationFile))) {
+ key.encode(output);
+ } catch (IOException ex) {
+ ProvSDKUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvSDKUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ }
}
}));
+
Button addButton = new Button(buttonComposite, SWT.PUSH);
addButton.setText(ProvSDKMessages.TrustPreferencePage_addPGPKeyButtonLabel);
addButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
+ dialog.setFilterPath(getFilterPath(ADD_FILTER_PATH));
dialog.setText(ProvSDKMessages.TrustPreferencePage_fileImportTitle);
- dialog.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$
+ dialog.setFilterExtensions(new String[] { "*.asc;*.der" }); //$NON-NLS-1$
String path = dialog.open();
+ setFilterPath(ADD_FILTER_PATH, dialog.getFilterPath());
if (path == null) {
return;
}
- trustedKeys.add(new File(path));
- viewer.setInput(trustedKeys.all());
+
+ if (path.endsWith(".der")) { //$NON-NLS-1$
+ try {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
+ try (InputStream input = Files.newInputStream(Paths.get(path))) {
+ Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(input);
+ trustedCertificates.addAll(certificates);
+ updateInput();
+ viewer.setSelection(new StructuredSelection(certificates.toArray()), true);
+ }
+ } catch (IOException | CertificateException ex) {
+ ProvSDKUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvSDKUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ }
+ } else {
+ HashSet<Object> oldKeys = new HashSet<>(trustedKeys.all());
+ trustedKeys.add(new File(path));
+
+ HashSet<Object> newKeys = new HashSet<>(trustedKeys.all());
+ newKeys.removeAll(oldKeys);
+ updateInput();
+ viewer.setSelection(new StructuredSelection(newKeys.toArray()), true);
+ }
dirty = true;
}));
setVerticalButtonLayoutData(addButton);
+
Button removeButton = new Button(buttonComposite, SWT.PUSH);
removeButton.setText(ProvSDKMessages.TrustPreferencePage_removePGPKeyButtonLabel);
removeButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
- trustedKeys.remove(getSelectedKey());
- viewer.setInput(trustedKeys.all());
+ for (Object key : getSelectedKeys()) {
+ if (key instanceof PGPPublicKey) {
+ trustedKeys.remove((PGPPublicKey) key);
+ } else {
+ trustedCertificates.remove(key);
+ }
+ }
+ updateInput();
dirty = true;
}));
+ removeButton.setEnabled(false);
setVerticalButtonLayoutData(removeButton);
+
+ Runnable details = () -> {
+ Object element = viewer.getStructuredSelection().getFirstElement();
+ if (element instanceof X509Certificate) {
+ // create and open dialog for certificate chain
+ CertificateLabelProvider.openDialog(getShell(), (X509Certificate) element);
+ } else {
+ new PGPPublicKeyViewDialog(getShell(), (PGPPublicKey) element,
+ provisioningAgent.getService(PGPPublicKeyService.class)).open();
+ }
+ };
+
+ Button detailsButton = new Button(buttonComposite, SWT.PUSH);
+ detailsButton.setText(ProvSDKMessages.TrustPreferencePage_Details);
+ detailsButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> details.run()));
+ detailsButton.setEnabled(false);
+ setVerticalButtonLayoutData(detailsButton);
+
viewer.addPostSelectionChangedListener(e -> {
- exportButton.setEnabled(getSelectedKey() != null);
- removeButton.setEnabled(getSelectedKey() != null);
+ List<Object> selectedKeys = getSelectedKeys();
+ exportButton.setEnabled(selectedKeys.size() == 1);
+ Collection<PGPPublicKey> keys = trustedKeys.all();
+ removeButton.setEnabled(
+ selectedKeys.stream().anyMatch(o -> keys.contains(o) || trustedCertificates.contains(o)));
+ detailsButton.setEnabled(selectedKeys.size() == 1);
});
- exportButton.setEnabled(getSelectedKey() != null);
- removeButton.setEnabled(getSelectedKey() != null);
+
+ Button trustAllButton = WidgetFactory.button(SWT.CHECK).text(ProvSDKMessages.TrustPreferencePage_TrustAll)
+ .font(JFaceResources.getDialogFont()).create(res);
+ setButtonLayoutData(trustAllButton).verticalSpan = 2;
+ trustAllButton.setSelection(certificateChecker.isTrustAlways());
+ trustAllButton.addSelectionListener(widgetSelectedAdapter(e -> {
+ if (trustAllButton.getSelection()) {
+ // Prompt the user to ensure they really understand what they've chosen, the
+ // risk, and where the preference is stored if they wish to change it in the
+ // future. Also ensure that the default button is no so that they must
+ // explicitly click the yes button, not just hit enter.
+ MessageDialog messageDialog = new MessageDialog(getShell(),
+ ProvSDKMessages.TrustPreferencePage_TrustAllConfirmationTitle, null,
+ ProvSDKMessages.TrustPreferencePage_TrustAllConfirmationDescription, MessageDialog.QUESTION,
+ new String[] { ProvSDKMessages.TrustPreferencePage_TrustAllYes,
+ ProvSDKMessages.TrustPreferencePage_TrustAllNo },
+ 1) {
+ @Override
+ public Image getImage() {
+ return getWarningImage();
+ }
+ };
+ int result = messageDialog.open();
+ if (result != Window.OK) {
+ certificateChecker.setTrustAlways(false);
+ // Restore the setting.
+ trustAllButton.setSelection(false);
+ } else {
+ certificateChecker.setTrustAlways(true);
+ }
+
+ }
+ }));
+
+ viewer.addDoubleClickListener(e -> details.run());
+
+ typeColumn.getColumn().pack();
+
+ createMenu();
+
return res;
}
- private PGPPublicKey getSelectedKey() {
- ISelection sel = viewer.getSelection();
- if (!(sel instanceof IStructuredSelection)) {
- return null;
- }
- Object o = ((IStructuredSelection) sel).getFirstElement();
- if (!(o instanceof PGPPublicKey)) {
- return null;
- }
- return (PGPPublicKey) o;
+ private void createMenu() {
+ Control control = viewer.getControl();
+ Menu menu = new Menu(control);
+ control.setMenu(menu);
+ MenuItem item = new MenuItem(menu, SWT.PUSH);
+ item.setText(ProvSDKMessages.TrustPreferencePage_CopyFingerprint);
+ item.addSelectionListener(widgetSelectedAdapter(e -> {
+ Object element = viewer.getStructuredSelection().getFirstElement();
+ if (element instanceof PGPPublicKey) {
+ Clipboard clipboard = new Clipboard(getShell().getDisplay());
+ clipboard.setContents(new Object[] {
+ PGPPublicKeyService.toHexFingerprint((PGPPublicKey) element) },
+ new Transfer[] { TextTransfer.getInstance() });
+ clipboard.dispose();
+ }
+ }));
+
+ viewer.addSelectionChangedListener(
+ e -> item.setEnabled(viewer.getStructuredSelection().getFirstElement() instanceof PGPPublicKey));
+ }
+
+ private TableViewerColumn createColumn(TableViewer tableViewer, String text, Function<PGPPublicKey, String> pgpMap,
+ Function<X509Certificate, String> x509Map, TableColumnLayout tableColumnLayout, int columnWeight) {
+ TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
+ column.getColumn().setText(text);
+ column.setLabelProvider(new PGPOrX509ColumnLabelProvider(pgpMap, x509Map));
+
+ tableColumnLayout.setColumnData(column.getColumn(), new ColumnWeightData(columnWeight));
+ return column;
+ }
+
+ private void updateInput() {
+ Set<PGPPublicKey> input = new TreeSet<>((k1, k2) -> {
+ return Arrays.compare(k1.getFingerprint(), k2.getFingerprint());
+ });
+ input = new LinkedHashSet<>();
+ Collection<PGPPublicKey> all = trustedKeys.all();
+ input = new TreeSet<>((k1, k2) -> {
+ boolean contains1 = all.contains(k1);
+ boolean contains2 = all.contains(k2);
+ if (contains1 != contains2) {
+ if (contains1) {
+ return -1;
+ }
+ return 1;
+ }
+ return PGPPublicKeyService.toHexFingerprint(k1).compareTo(PGPPublicKeyService.toHexFingerprint(k2));
+ });
+ input.addAll(all);
+ input.addAll(contributedTrustedKeys.keySet());
+
+ LinkedHashSet<Object> allInput = new LinkedHashSet<>();
+ allInput.addAll(trustedCertificates);
+ allInput.addAll(input);
+ viewer.setInput(allInput);
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Object> getSelectedKeys() {
+ return viewer.getStructuredSelection().toList();
}
private Composite createVerticalButtonBar(Composite parent) {
@@ -181,12 +424,68 @@ public class TrustPreferencePage extends PreferencePage implements IWorkbenchPre
return data;
}
+ private String getFilterPath(String key) {
+ IDialogSettings dialogSettings = DialogSettings
+ .getOrCreateSection(ProvSDKUIActivator.getDefault().getDialogSettings(), getClass().getName());
+ String filterPath = dialogSettings.get(key);
+ if (filterPath == null) {
+ filterPath = System.getProperty("user.home"); //$NON-NLS-1$
+ }
+ return filterPath;
+ }
+
+ private void setFilterPath(String key, String filterPath) {
+ if (filterPath != null) {
+ IDialogSettings dialogSettings = DialogSettings
+ .getOrCreateSection(ProvSDKUIActivator.getDefault().getDialogSettings(), getClass().getName());
+ dialogSettings.put(key, filterPath);
+ }
+ }
+
+ private String getBundleName(Bundle bundle) {
+ String value = bundle.getHeaders().get(Constants.BUNDLE_NAME);
+ return value == null ? bundle.getSymbolicName() : Platform.getResourceString(bundle, value);
+ }
+
+ @Override
+ protected void performDefaults() {
+ trustedCertificates = new LinkedHashSet<>(certificateChecker.getPreferenceTrustedCertificates());
+ trustedKeys = certificateChecker.getPreferenceTrustedKeys();
+ updateInput();
+ super.performDefaults();
+ }
+
@Override
public boolean performOk() {
if (dirty) {
- return certificateChecker.persistTrustedKeys(trustedKeys).isOK();
+ IStatus persistTrustedCertificates = certificateChecker.persistTrustedCertificates(trustedCertificates);
+ IStatus persistTrustedKeys = certificateChecker.persistTrustedKeys(trustedKeys);
+ dirty = false;
+ return persistTrustedKeys.isOK() && persistTrustedCertificates.isOK();
}
return true;
}
+ private static class PGPOrX509ColumnLabelProvider extends ColumnLabelProvider {
+ private Function<PGPPublicKey, String> pgpMap;
+ private Function<X509Certificate, String> x509map;
+
+ public PGPOrX509ColumnLabelProvider(Function<PGPPublicKey, String> pgpMap,
+ Function<X509Certificate, String> x509map) {
+ this.pgpMap = pgpMap;
+ this.x509map = x509map;
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof PGPPublicKey) {
+ return pgpMap.apply((PGPPublicKey) element);
+ }
+ if (element instanceof X509Certificate) {
+ return x509map.apply((X509Certificate) element);
+ }
+ return super.getText(element);
+ }
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties
index 0e344af3d..93df84f7f 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties
@@ -37,12 +37,28 @@ RemediationOperation_ResolveJobName=Searching alternate solutions...
RemediationOperation_ResolveJobTask=Some items cannot be at the highest version. Searching for the highest common denominator ...
TrustPreferencePage_title=Trust
TrustPreferencePage_export=\uD83D\uDCE5 E&xport...
-TrustPreferencePage_idColumn=Id
-TrustPreferencePage_userColumn=User
TrustPreferencePage_fileExportTitle=Export PGP public key
TrustPreferencePage_fileImportTitle=Import PGP public key to trust
TrustPreferencePage_addPGPKeyButtonLabel=\u2795 &Add...
+TrustPreferencePage_Contributor=Contributor
+TrustPreferencePage_CopyFingerprint=Copy Fingerprint
+TrustPreferencePage_DataValidExpires=\u2714\uFE0F Valid, expires {0}
+TrustPreferencePage_DateExpired=\u274C Expired
+TrustPreferencePage_DateExpiredSince=\u274C Expired since {0}
+TrustPreferencePage_DateNotYetvalid=\u274C Not yet valid
+TrustPreferencePage_DateNotYetValid=\u274C Not yet valid, starts {0}
+TrustPreferencePage_DateValid=\u2714\uFE0F Valid
+TrustPreferencePage_Details=\uD83D\uDD0D D&etails...
+TrustPreferencePage_Export=Export...
+TrustPreferencePage_FingerprintIdColumn=Fingerprint/Id
+TrustPreferencePage_NameColumn=Name
+TrustPreferencePage_PreferenceContributor=<preferences>
TrustPreferencePage_removePGPKeyButtonLabel=\uD83D\uDDD1\uFE0F &Remove
-
-TrustPreferencePage_pgpIntro=The following PGP public keys are considered as trusted.\n\
-Artifacts that are signed and verified by one of those keys will be trusted and installed without further trust confirmation request. \ No newline at end of file
+TrustPreferencePage_pgpIntro=Artifacts verifiably signed by the following trusted certificates and PGP public keys will be installed without confirmation.
+TrustPreferencePage_TrustAll=Trust all content
+TrustPreferencePage_TrustAllConfirmationDescription=Are you certain you wish to trust all content, including unsigned content of unknown origin, with no confirmation for all future operations?
+TrustPreferencePage_TrustAllConfirmationTitle=Always Trust Everything Confirmation
+TrustPreferencePage_TrustAllNo=No, Prompt Me Instead
+TrustPreferencePage_TrustAllYes=Yes, I Accept the Risk
+TrustPreferencePage_TypeColumn=Type
+TrustPreferencePage_ValidityColumn=Validity Dates
diff --git a/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
index 429c0b980..433d2e820 100644
--- a/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.equinox.p2.ui;singleton:=true
-Bundle-Version: 2.7.300.qualifier
+Bundle-Version: 2.7.400.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.ui.ProvUIActivator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -19,6 +19,7 @@ Export-Package: org.eclipse.equinox.internal.p2.ui;
org.eclipse.equinox.internal.p2.ui.dialogs;
x-friends:="org.eclipse.equinox.p2.ui.admin,
org.eclipse.equinox.p2.ui.sdk.scheduler,
+ org.eclipse.equinox.p2.ui.sdk,
org.eclipse.pde.ui,
org.eclipse.equinox.p2.ui.importexport",
org.eclipse.equinox.internal.p2.ui.model;
@@ -28,7 +29,7 @@ Export-Package: org.eclipse.equinox.internal.p2.ui;
org.eclipse.equinox.p2.ui.sdk,
org.eclipse.equinox.p2.ui.importexport",
org.eclipse.equinox.internal.p2.ui.query;x-friends:="org.eclipse.equinox.internal.p2.ui.analysis,org.eclipse.equinox.p2.ui.admin",
- org.eclipse.equinox.internal.p2.ui.viewers;x-friends:="org.eclipse.equinox.p2.ui.admin,org.eclipse.equinox.p2.ui.sdk.scheduler,org.eclipse.equinox.p2.ui.importexport",
+ org.eclipse.equinox.internal.p2.ui.viewers;x-friends:="org.eclipse.equinox.p2.ui.admin,org.eclipse.equinox.p2.ui.sdk,org.eclipse.equinox.p2.ui.sdk.scheduler,org.eclipse.equinox.p2.ui.importexport",
org.eclipse.equinox.p2.ui;version="2.6.0"
Require-Bundle: org.eclipse.ui;bundle-version="3.107.0",
org.eclipse.core.runtime;bundle-version="[3.18.0,4.0.0)",
@@ -39,9 +40,11 @@ Import-Package: javax.xml.parsers,
org.bouncycastle.bcpg;version="1.65.0",
org.bouncycastle.openpgp;version="1.65.0",
org.bouncycastle.util;version="1.65.1",
+ org.eclipse.equinox.internal.p2.artifact.processors.pgp,
org.eclipse.equinox.internal.p2.artifact.repository,
org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.p2.director,
+ org.eclipse.equinox.internal.p2.extensionlocation,
org.eclipse.equinox.internal.p2.metadata,
org.eclipse.equinox.internal.p2.metadata.repository,
org.eclipse.equinox.internal.p2.operations,
@@ -60,7 +63,9 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.p2.query;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.artifact;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.repository.artifact.spi;version="[2.0.0,3.0.0)",
org.eclipse.equinox.p2.repository.metadata;version="[2.0.0,3.0.0)",
+ org.eclipse.equinox.p2.repository.spi;version="2.0.0",
org.osgi.framework;version="1.6.0",
org.osgi.service.packageadmin;version="1.2.0",
org.w3c.dom,
diff --git a/bundles/org.eclipse.equinox.p2.ui/plugin.xml b/bundles/org.eclipse.equinox.p2.ui/plugin.xml
index 6f6031e2e..87e8645fd 100644
--- a/bundles/org.eclipse.equinox.p2.ui/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.ui/plugin.xml
@@ -12,6 +12,13 @@
<adapter type="org.eclipse.equinox.p2.repository.metadata.IMetadataRepository"/>
<adapter type="org.eclipse.equinox.p2.repository.artifact.IArtifactRepository"/>
</factory>
+ <factory
+ adaptableType="org.eclipse.ui.internal.about.AboutPluginsPage"
+ class="org.eclipse.equinox.internal.p2.ui.KeySigningInfoFactory">
+ <adapter
+ type="org.eclipse.ui.internal.about.AboutBundleData$ExtendedSigningInfo">
+ </adapter>
+ </factory>
</extension>
<extension
diff --git a/bundles/org.eclipse.equinox.p2.ui/pom.xml b/bundles/org.eclipse.equinox.p2.ui/pom.xml
index 027ad5f4a..13cace16e 100644
--- a/bundles/org.eclipse.equinox.p2.ui/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.ui/pom.xml
@@ -14,11 +14,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.ui</artifactId>
- <version>2.7.300-SNAPSHOT</version>
+ <version>2.7.400-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/IProvHelpContextIds.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/IProvHelpContextIds.java
index cba53aa52..3c75aa5e9 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/IProvHelpContextIds.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/IProvHelpContextIds.java
@@ -13,35 +13,37 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui;
-
/**
* Help context ids for the P2 UI
* <p>
* This interface contains constants only; it is not intended to be implemented
* or extended.
* </p>
+ *
* @since 3.4
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IProvHelpContextIds {
- public static final String PREFIX = ProvUIActivator.PLUGIN_ID + "."; //$NON-NLS-1$
+ String PREFIX = ProvUIActivator.PLUGIN_ID + "."; //$NON-NLS-1$
+
+ String REVERT_CONFIGURATION_WIZARD = PREFIX + "revert_configuration_wizard_context"; //$NON-NLS-1$
- public static final String REVERT_CONFIGURATION_WIZARD = PREFIX + "revert_configuration_wizard_context"; //$NON-NLS-1$
+ String UNINSTALL_WIZARD = PREFIX + "uinstall_wizard_context"; //$NON-NLS-1$
- public static final String UNINSTALL_WIZARD = PREFIX + "uinstall_wizard_context"; //$NON-NLS-1$
+ String UPDATE_WIZARD = PREFIX + "update_wizard_context"; //$NON-NLS-1$
- public static final String UPDATE_WIZARD = PREFIX + "update_wizard_context"; //$NON-NLS-1$
+ String ADD_REPOSITORY_DIALOG = PREFIX + "add_repository_dialog_context"; //$NON-NLS-1$
- public static final String ADD_REPOSITORY_DIALOG = PREFIX + "add_repository_dialog_context"; //$NON-NLS-1$
+ String INSTALL_WIZARD = PREFIX + "install_wizard_context"; //$NON-NLS-1$
- public static final String INSTALL_WIZARD = PREFIX + "install_wizard_context"; //$NON-NLS-1$
+ String REPOSITORY_MANIPULATION_DIALOG = PREFIX + "repository_manipulation_dialog_context"; //$NON-NLS-1$
- public static final String REPOSITORY_MANIPULATION_DIALOG = PREFIX + "repository_manipulation_dialog_context"; //$NON-NLS-1$
+ String INSTALLED_SOFTWARE = PREFIX + "installed_software_context"; //$NON-NLS-1$
- public static final String INSTALLED_SOFTWARE = PREFIX + "installed_software_context"; //$NON-NLS-1$
+ String AVAILABLE_SOFTWARE = PREFIX + "available_software_context"; //$NON-NLS-1$
- public static final String AVAILABLE_SOFTWARE = PREFIX + "available_software_context"; //$NON-NLS-1$
+ String TRUST_DIALOG = PREFIX + "trust_dialog_context"; //$NON-NLS-1$
}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java
new file mode 100644
index 000000000..1134dbb56
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.bouncycastle.openpgp.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPPublicKeyStore;
+import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.repository.artifact.*;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.ui.internal.about.AboutBundleData;
+import org.eclipse.ui.internal.about.AboutPluginsPage;
+import org.osgi.framework.Bundle;
+
+/**
+ * A factory used by the {@link AboutPluginsPage} to provide extended signing
+ * information, in particular information about PGP signing.
+ *
+ * @since 2.7.400
+ */
+public class KeySigningInfoFactory implements IAdapterFactory {
+
+ private static final Class<?>[] CLASSES = new Class[] { AboutBundleData.ExtendedSigningInfo.class };
+
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == AboutBundleData.ExtendedSigningInfo.class) {
+ return adapterType.cast(new AboutBundleData.ExtendedSigningInfo() {
+ private final Map<File, Map<PGPSignature, PGPPublicKey>> bundlePoolArtficactSigningDetails = getBundlePoolArtficactPGPSigningDetails();
+
+ @Override
+ public boolean isSigned(Bundle bundle) {
+ return getDetails(bundle) != null;
+ }
+
+ @Override
+ public String getSigningType(Bundle bundle) {
+ return ProvUIMessages.KeySigningInfoFactory_PGPSigningType;
+ }
+
+ @Override
+ public String getSigningDetails(Bundle bundle) {
+ Map<PGPSignature, PGPPublicKey> details = getDetails(bundle);
+ if (details != null) {
+ PGPPublicKeyService keyService = getKeyService();
+ List<String> lines = new ArrayList<>();
+ for (PGPPublicKey key : details.values()) {
+ if (keyService != null) {
+ // Be sure to normalize/enhance the key so we properly don't show
+ // self-signatures.
+ key = keyService.addKey(key);
+ }
+ if (!lines.isEmpty()) {
+ lines.add(""); //$NON-NLS-1$
+ }
+ addDetails(key, lines, ""); //$NON-NLS-1$
+ if (keyService != null) {
+ Set<PGPPublicKey> verifiedCertifications = keyService.getVerifiedCertifications(key);
+ boolean first = true;
+ for (PGPPublicKey verifyingKey : verifiedCertifications) {
+ /// Don't show self-signatures.
+ if (!verifyingKey.equals(key)) {
+ if (first) {
+ lines.add(" " + ProvUIMessages.KeySigningInfoFactory_KeySignersSection); //$NON-NLS-1$
+ first = false;
+ }
+ addDetails(verifyingKey, lines, " "); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return String.join("\n", lines); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ @Override
+ public Date getSigningTime(Bundle bundle) {
+ Map<PGPSignature, PGPPublicKey> details = getDetails(bundle);
+ return details == null ? null : details.keySet().iterator().next().getCreationTime();
+ }
+
+ private void addDetails(PGPPublicKey key, List<String> lines, String indentation) {
+ lines.add(indentation + ProvUIMessages.KeySigningInfoFactory_FingerprintItem
+ + PGPPublicKeyService.toHexFingerprint(key));
+ for (Iterator<String> userIDs = key.getUserIDs(); userIDs.hasNext();) {
+ lines.add(indentation + ProvUIMessages.KeySigningInfoFactory_UserIDItem + userIDs.next());
+ }
+ }
+
+ private PGPPublicKeyService getKeyService() {
+ IProvisioningAgent agent = org.eclipse.equinox.internal.p2.extensionlocation.Activator
+ .getCurrentAgent();
+ return agent == null ? null : agent.getService(PGPPublicKeyService.class);
+ }
+
+ private Map<PGPSignature, PGPPublicKey> getDetails(Bundle bundle) {
+ try {
+ File bundleFile = FileLocator.getBundleFile(bundle).getCanonicalFile();
+ Map<PGPSignature, PGPPublicKey> details = bundlePoolArtficactSigningDetails.get(bundleFile);
+ return details;
+ } catch (IOException | RuntimeException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ return null;
+ }
+ }
+ });
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return CLASSES;
+ }
+
+ /**
+ * Returns a map from artifact files to the PGP signature/key pairs that were
+ * used to {@link PGPSignatureVerifier#close() verify} the artifact while it was
+ * being downloaded.
+ *
+ * @return a map of all the PGP signed artifact files to their signature/key
+ * pairs.
+ */
+ private static Map<File, Map<PGPSignature, PGPPublicKey>> getBundlePoolArtficactPGPSigningDetails() {
+ Map<File, Map<PGPSignature, PGPPublicKey>> result = new LinkedHashMap<>();
+ try {
+ // Look up artifact metadata for all the bundle pool repository of the
+ // installation.
+ IFileArtifactRepository bundlePoolRepository = org.eclipse.equinox.internal.p2.extensionlocation.Activator
+ .getBundlePoolRepository();
+ IQueryResult<IArtifactKey> allArtifactKeys = bundlePoolRepository.query(ArtifactKeyQuery.ALL_KEYS,
+ new NullProgressMonitor());
+ for (IArtifactKey key : allArtifactKeys) {
+ for (IArtifactDescriptor descriptor : bundlePoolRepository.getArtifactDescriptors(key)) {
+ File file = bundlePoolRepository.getArtifactFile(descriptor);
+ if (file != null) {
+ try {
+ Collection<PGPSignature> signatures = PGPSignatureVerifier.getSignatures(descriptor);
+ if (!signatures.isEmpty()) {
+ Map<PGPSignature, PGPPublicKey> details = new LinkedHashMap<>();
+ PGPPublicKeyStore keys = PGPSignatureVerifier.getKeys(descriptor);
+ for (PGPSignature signature : signatures) {
+ Collection<PGPPublicKey> signingKeys = keys.getKeys(signature.getKeyID());
+ if (!signingKeys.isEmpty()) {
+ // There is vanishingly small chance that two keys with colliding key IDs were
+ // used on two different signatures on the same artifact.
+ details.put(signature, signingKeys.iterator().next());
+ }
+ }
+ if (!details.isEmpty()) {
+ result.put(file.getCanonicalFile(), details);
+ }
+ }
+ } catch (IOException | PGPException | RuntimeException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ }
+ }
+ }
+ }
+ } catch (RuntimeException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
index bcee1d0ef..f79aacc0b 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
@@ -78,6 +78,7 @@ public class ProvUIMessages extends NLS {
public static String IUGeneralInfoPropertyPage_VersionLabel;
public static String IULicensePropertyPage_NoLicense;
public static String IULicensePropertyPage_ViewLicenseLabel;
+ public static String PGPPublicKeyViewDialog_Title;
public static String ProfileModificationAction_InvalidSelections;
public static String ProfileModificationWizardPage_DetailsLabel;
public static String ProfileSnapshots_Label;
@@ -247,6 +248,10 @@ public class ProvUIMessages extends NLS {
public static String SelectableIUsPage_Deselect_All;
public static String InstallRemediationPage_Title;
public static String InstallRemediationPage_Description;
+ public static String KeySigningInfoFactory_FingerprintItem;
+ public static String KeySigningInfoFactory_KeySignersSection;
+ public static String KeySigningInfoFactory_PGPSigningType;
+ public static String KeySigningInfoFactory_UserIDItem;
public static String UpdateRemediationPage_Title;
public static String UpdateRemediationPage_Description;
public static String RemediationPage_SubDescription;
@@ -274,12 +279,35 @@ public class ProvUIMessages extends NLS {
public static String TrustCertificateDialog_Export;
public static String TrustCertificateDialog_Title;
public static String TrustCertificateDialog_Message;
+ public static String TrustCertificateDialog_MessageUnsigned;
+ public static String TrustCertificateDialog_MessageNameWarning;
+ public static String TrustCertificateDialog_MessagePGP;
public static String TrustCertificateDialog_AcceptSelectedButtonLabel;
+ public static String TrustCertificateDialog_AlwaysTrust;
+ public static String TrustCertificateDialog_AlwaysTrustConfirmationMessage;
+ public static String TrustCertificateDialog_AlwaysTrustConfirmationTitle;
+ public static String TrustCertificateDialog_AlwaysTrustNo;
+ public static String TrustCertificateDialog_AlwaysTrustYes;
+ public static String TrustCertificateDialog_ArtifactId;
public static String TrustCertificateDialog_SelectAll;
public static String TrustCertificateDialog_DeselectAll;
public static String TrustCertificateDialog_ObjectType;
public static String TrustCertificateDialog_Id;
public static String TrustCertificateDialog_Name;
+ public static String TrustCertificateDialog_Classifier;
+ public static String TrustCertificateDialog_CopyFingerprint;
+ public static String TrustCertificateDialog_dates;
+ public static String TrustCertificateDialog_NotApplicable;
+ public static String TrustCertificateDialog_NotYetValidStartDate;
+ public static String TrustCertificateDialog_expiredSince;
+ public static String TrustCertificateDialog_validExpires;
+ public static String TrustCertificateDialog_valid;
+ public static String TrustCertificateDialog_expired;
+ public static String TrustCertificateDialog_notYetValid;
+ public static String TrustCertificateDialog_RememberSigners;
+ public static String TrustCertificateDialog_Unknown;
+ public static String TrustCertificateDialog_Unsigned;
+ public static String TrustCertificateDialog_Version;
// Operations
public static String UpdateManagerCompatibility_ExportSitesTitle;
public static String UpdateManagerCompatibility_ImportSitesTitle;
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ServiceUIComponent.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ServiceUIComponent.java
index fcea5da5a..cad8f35b9 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ServiceUIComponent.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ServiceUIComponent.java
@@ -13,9 +13,8 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui;
-import org.eclipse.equinox.p2.core.UIServices;
-
import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.UIServices;
import org.eclipse.equinox.p2.core.spi.IAgentServiceFactory;
/**
@@ -26,7 +25,7 @@ public class ServiceUIComponent implements IAgentServiceFactory {
@Override
public Object createService(IProvisioningAgent agent) {
- return new ValidationDialogServiceUI();
+ return new ValidationDialogServiceUI(agent);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
index 482fe4844..ae451f4c7 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ValidationDialogServiceUI.java
@@ -14,19 +14,29 @@
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui;
+import java.io.File;
import java.net.URL;
import java.security.cert.Certificate;
import java.util.*;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.internal.p2.ui.dialogs.TrustCertificateDialog;
import org.eclipse.equinox.internal.p2.ui.dialogs.UserValidationDialog;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.UIServices;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.repository.artifact.spi.IArtifactUIServices;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.viewers.TreeNode;
+import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
@@ -40,16 +50,45 @@ import org.eclipse.ui.PlatformUI;
* declaration is made in the serviceui_component.xml file.
*
*/
-public class ValidationDialogServiceUI extends UIServices {
+public class ValidationDialogServiceUI extends UIServices implements IArtifactUIServices {
+
+ private final IProvisioningAgent agent;
+
+ private Display display;
+
+ private Consumer<String> linkHandler = link -> {
+ if (PlatformUI.isWorkbenchRunning()) {
+ try {
+ URL url = new URL(link);
+ PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url);
+ } catch (Exception x) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, x.getMessage(), x));
+ }
+ }
+ };
+
+ private IShellProvider shellProvider = () -> ProvUI.getDefaultParentShell();
+
+ public ValidationDialogServiceUI() {
+ this(null);
+ }
+
+ public ValidationDialogServiceUI(IProvisioningAgent agent) {
+ this.agent = agent;
+ }
static final class MessageDialogWithLink extends MessageDialog {
private final String linkText;
+ private final Consumer<String> linkOpener;
MessageDialogWithLink(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage,
- int dialogImageType, String[] dialogButtonLabels, int defaultIndex, String linkText) {
+ int dialogImageType, String[] dialogButtonLabels, int defaultIndex, String linkText,
+ Consumer<String> linkOpener) {
super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels,
defaultIndex);
this.linkText = linkText;
+ this.linkOpener = linkOpener;
}
@Override
@@ -60,13 +99,7 @@ public class ValidationDialogServiceUI extends UIServices {
Link link = new Link(parent, SWT.NONE);
link.setText(linkText);
link.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
- try {
- URL url = new URL(e.text);
- PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser().openURL(url);
- } catch (Exception x) {
- ProvUIActivator.getDefault().getLog().log(//
- new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, x.getMessage(), x));
- }
+ linkOpener.accept(e.text);
}));
return link;
}
@@ -96,8 +129,8 @@ public class ValidationDialogServiceUI extends UIServices {
final AuthenticationInfo[] result = new AuthenticationInfo[1];
if (!suppressAuthentication() && !isHeadless()) {
- PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
- Shell shell = ProvUI.getDefaultParentShell();
+ getDisplay().syncExec(() -> {
+ Shell shell = shellProvider.getShell();
String message = NLS.bind(ProvUIMessages.ServiceUI_LoginDetails, location);
UserValidationDialog dialog = new UserValidationDialog(shell, ProvUIMessages.ServiceUI_LoginRequired,
null, message);
@@ -141,10 +174,10 @@ public class ValidationDialogServiceUI extends UIServices {
// detail should be trusted
if (!isHeadless() && unsignedDetail != null && unsignedDetail.length > 0) {
final boolean[] result = new boolean[] { false };
- PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ getDisplay().syncExec(new Runnable() {
@Override
public void run() {
- Shell shell = ProvUI.getDefaultParentShell();
+ Shell shell = shellProvider.getShell();
OkCancelErrorDialog dialog = new OkCancelErrorDialog(shell, ProvUIMessages.ServiceUI_warning_title,
null, createStatus(), IStatus.WARNING);
result[0] = dialog.open() == IDialogConstants.OK_ID;
@@ -169,17 +202,46 @@ public class ValidationDialogServiceUI extends UIServices {
// We've established trust for unsigned content, now examine the untrusted
// chains
if (!isHeadless() && (untrustedChains.length > 0 || !untrustedPublicKeys.isEmpty())) {
- final TrustCertificateDialog[] dialog = new TrustCertificateDialog[1];
- final TreeNode[] input = createTreeNodes(untrustedChains, untrustedPublicKeys);
- PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
- Shell shell = ProvUI.getDefaultParentShell();
- TrustCertificateDialog trustCertificateDialog = new TrustCertificateDialog(shell, input);
- dialog[0] = trustCertificateDialog;
- trustCertificateDialog.open();
- });
- persistTrust = true;
- if (dialog[0].getResult() != null) {
- for (Object o : dialog[0].getResult()) {
+ return getTrustInfo(
+ Arrays.stream(untrustedChains).collect(
+ Collectors.toMap(Arrays::asList, it -> Set.of(), (e1, e2) -> e1, LinkedHashMap::new)),
+ untrustedPublicKeys.stream().collect(
+ Collectors.toMap(Function.identity(), it -> Set.of(), (e1, e2) -> e1, LinkedHashMap::new)),
+ null, null);
+
+ }
+
+ return new TrustInfo(trustedCertificates, trustedKeys, persistTrust, trustUnsigned);
+ }
+
+ @Override
+ public TrustInfo getTrustInfo(Map<List<Certificate>, Set<IArtifactKey>> untrustedCertificates,
+ Map<PGPPublicKey, Set<IArtifactKey>> untrustedPGPKeys, //
+ Set<IArtifactKey> unsignedArtifacts, //
+ Map<IArtifactKey, File> artifacts) {
+ boolean trustUnsigned = true;
+ AtomicBoolean persistTrust = new AtomicBoolean();
+ AtomicBoolean trustAlways = new AtomicBoolean();
+ List<Certificate> trustedCertificates = new ArrayList<>();
+ List<PGPPublicKey> trustedKeys = new ArrayList<>();
+ if (!isHeadless()) {
+ TreeNode[] input = createTreeNodes(untrustedCertificates, untrustedPGPKeys, unsignedArtifacts, artifacts);
+ if (input.length != 0) {
+ trustUnsigned = unsignedArtifacts == null || unsignedArtifacts.isEmpty();
+ List<Object> result = new ArrayList<>();
+ getDisplay().syncExec(() -> {
+ Shell shell = shellProvider.getShell();
+ TrustCertificateDialog trustCertificateDialog = new TrustCertificateDialog(shell, input);
+ if (trustCertificateDialog.open() == Window.OK) {
+ Object[] dialogResult = trustCertificateDialog.getResult();
+ if (dialogResult != null) {
+ result.addAll(Arrays.asList(dialogResult));
+ }
+ persistTrust.set(trustCertificateDialog.isRememberSelectedSigners());
+ trustAlways.set(trustCertificateDialog.isTrustAlways());
+ }
+ });
+ for (Object o : result) {
if (o instanceof TreeNode) {
o = ((TreeNode) o).getValue();
}
@@ -187,40 +249,93 @@ public class ValidationDialogServiceUI extends UIServices {
trustedCertificates.add((Certificate) o);
} else if (o instanceof PGPPublicKey) {
trustedKeys.add((PGPPublicKey) o);
+ } else if (o == null) {
+ trustUnsigned = true;
}
}
}
}
- return new TrustInfo(trustedCertificates, trustedKeys, persistTrust, trustUnsigned);
+
+ return new TrustInfo(trustedCertificates, trustedKeys, persistTrust.get(), trustUnsigned, trustAlways.get());
}
- private TreeNode[] createTreeNodes(Certificate[][] certificates, Collection<PGPPublicKey> untrustedPublicKeys) {
- TreeNode[] children = new TreeNode[certificates.length + untrustedPublicKeys.size()];
- int i = 0;
- for (i = 0; i < certificates.length; i++) {
- TreeNode head = new TreeNode(certificates[i][0]);
- TreeNode parent = head;
- children[i] = head;
- for (int j = 0; j < certificates[i].length; j++) {
- TreeNode node = new TreeNode(certificates[i][j]);
- node.setParent(parent);
- parent.setChildren(new TreeNode[] { node });
- parent = node;
+ private TreeNode[] createTreeNodes(Map<List<Certificate>, Set<IArtifactKey>> untrustedCertificates,
+ Map<PGPPublicKey, Set<IArtifactKey>> untrustedPGPKeys, //
+ Set<IArtifactKey> unsignedArtifacts, //
+ Map<IArtifactKey, File> artifacts) {
+
+ List<ExtendedTreeNode> children = new ArrayList<>();
+ if (untrustedCertificates != null && !untrustedCertificates.isEmpty()) {
+ for (Map.Entry<List<Certificate>, Set<IArtifactKey>> entry : untrustedCertificates.entrySet()) {
+ ExtendedTreeNode parent = null;
+ List<Certificate> key = entry.getKey();
+ Set<IArtifactKey> associatedArtifacts = entry.getValue();
+ for (Certificate certificate : key) {
+ ExtendedTreeNode node = new ExtendedTreeNode(certificate, associatedArtifacts);
+ if (parent == null) {
+ children.add(node);
+ } else {
+ node.setParent(parent);
+ parent.setChildren(new TreeNode[] { node });
+ }
+ parent = node;
+ }
+ }
+ }
+
+ if (untrustedPGPKeys != null && !untrustedPGPKeys.isEmpty()) {
+ PGPPublicKeyService keyService = agent == null ? null : agent.getService(PGPPublicKeyService.class);
+ for (Map.Entry<PGPPublicKey, Set<IArtifactKey>> entry : untrustedPGPKeys.entrySet()) {
+ PGPPublicKey key = entry.getKey();
+ Set<IArtifactKey> associatedArtifacts = entry.getValue();
+ ExtendedTreeNode node = new ExtendedTreeNode(key, associatedArtifacts);
+ children.add(node);
+ expandChildren(node, key, keyService, new HashSet<>(), Integer.getInteger("p2.pgp.trust.depth", 3)); //$NON-NLS-1$
}
}
- for (PGPPublicKey key : untrustedPublicKeys) {
- children[i] = new TreeNode(key);
- i++;
+
+ if (unsignedArtifacts != null && !unsignedArtifacts.isEmpty()) {
+ ExtendedTreeNode node = new ExtendedTreeNode(null, unsignedArtifacts);
+ children.add(node);
+
+ }
+
+ return children.toArray(TreeNode[]::new);
+ }
+
+ private void expandChildren(TreeNode result, PGPPublicKey key, PGPPublicKeyService keyService,
+ Set<PGPPublicKey> visited, int remainingDepth) {
+ if (keyService != null && remainingDepth > 0 && visited.add(key)) {
+ Set<PGPPublicKey> certifications = keyService.getVerifiedCertifications(key);
+ if (certifications != null && !certifications.isEmpty()) {
+ List<TreeNode> children = new ArrayList<>();
+ for (PGPPublicKey certifyingKey : certifications) {
+ if (visited.add(certifyingKey)) {
+ TreeNode treeNode = new TreeNode(certifyingKey);
+ children.add(treeNode);
+ }
+ }
+
+ if (!children.isEmpty()) {
+ result.setChildren(children.toArray(TreeNode[]::new));
+ children.forEach(child -> {
+ child.setParent(result);
+ PGPPublicKey certifyingKey = (PGPPublicKey) child.getValue();
+ visited.remove(certifyingKey);
+ expandChildren(child, certifyingKey, keyService, visited, remainingDepth - 1);
+ visited.add(certifyingKey);
+ });
+ }
+ }
}
- return children;
}
@Override
public AuthenticationInfo getUsernamePassword(final String location, final AuthenticationInfo previousInfo) {
final AuthenticationInfo[] result = new AuthenticationInfo[1];
if (!suppressAuthentication() && !isHeadless()) {
- PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
- Shell shell = ProvUI.getDefaultParentShell();
+ getDisplay().syncExec(() -> {
+ Shell shell = shellProvider.getShell();
String message = null;
if (previousInfo.saveResult())
message = NLS.bind(ProvUIMessages.ProvUIMessages_SavedNotAccepted_EnterFor_0, location);
@@ -246,18 +361,131 @@ public class ValidationDialogServiceUI extends UIServices {
super.showInformationMessage(title, text, linkText);
return;
}
- PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
- MessageDialog dialog = new MessageDialogWithLink(ProvUI.getDefaultParentShell(), title, null, text,
- MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0, linkText);
+ getDisplay().syncExec(() -> {
+ MessageDialog dialog = new MessageDialogWithLink(shellProvider.getShell(), title, null, text,
+ MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0, linkText, linkHandler);
dialog.open();
});
}
+ /**
+ * Returns a handler (used by
+ * {@link #showInformationMessage(String, String, String)}) to open a link in an
+ * external browser.
+ *
+ * @return a handler to open a link in an external browser.
+ *
+ * @since 2.7.400
+ */
+ public Consumer<String> getLinkHandler() {
+ return linkHandler;
+ }
+
+ /**
+ * Sets the handler used by
+ * {@link #showInformationMessage(String, String, String)} to open a link in an
+ * external browser.
+ *
+ * @param linkHandler the handler for opening links in an external browser.
+ *
+ * @since 2.7.400
+ */
+ public void setLinkHandler(Consumer<String> linkHandler) {
+ this.linkHandler = linkHandler;
+ }
+
+ /**
+ * Returns a shell that is appropriate to use as the parent for a modal dialog
+ * about to be opened.
+ *
+ * @return a shell that is appropriate to use as the parent for a modal dialog
+ * about to be opened.
+ *
+ * @see ProvUI#getDefaultParentShell()
+ *
+ * @since 2.7.400
+ */
+ public IShellProvider getShellProvider() {
+ return shellProvider;
+ }
+
+ /**
+ * Set the provider that yields a shell that is appropriate to use as the parent
+ * for a modal dialog about to be opened.
+ *
+ * @param shellProvider the provider of a shell that is appropriate to use as
+ * the parent for a modal dialog about to be opened.
+ */
+ public void setShellProvider(IShellProvider shellProvider) {
+ this.shellProvider = shellProvider;
+ }
+
+ /**
+ * Returns the display of the workbench or the display set by
+ * {@link #setDisplay(Display)} in a non-workbench application.
+ *
+ * @since 2.7.400
+ */
+ public Display getDisplay() {
+ if (display == null && PlatformUI.isWorkbenchRunning()) {
+ display = PlatformUI.getWorkbench().getDisplay();
+ }
+ return display;
+ }
+
+ /**
+ * Can be called once to set the display in a non-workbench application.
+ *
+ * @throws IllegalStateException if there is a workbench running or the display
+ * has already been set differently.
+ *
+ * @since 2.7.400
+ */
+ public void setDisplay(Display display) {
+ if (this.display != null && this.display != display) {
+ throw new IllegalStateException("Cannot change the display"); //$NON-NLS-1$
+ }
+ this.display = display;
+ }
+
private boolean isHeadless() {
// If there is no UI available and we are still the IServiceUI,
// assume that the operation should proceed. See
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291049
- return !PlatformUI.isWorkbenchRunning();
+ //
+ // But we shouldn't just assume that no workbench mean no display and no head.
+ // It should be possible to reuse this class in an application without a
+ // workbench, e.g., the Eclipse Installer.
+ return getDisplay() == null;
+ }
+
+ private static class ExtendedTreeNode extends TreeNode implements IAdaptable {
+ private final Set<IArtifactKey> artifacts;
+
+ public ExtendedTreeNode(Object value) {
+ super(value);
+ artifacts = null;
+ }
+
+ public ExtendedTreeNode(Object value, Set<IArtifactKey> artifacts) {
+ super(value);
+ this.artifacts = artifacts;
+ }
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ if (adapter.isInstance(this)) {
+ return adapter.cast(this);
+ }
+ if (adapter.isInstance(getValue())) {
+ return adapter.cast(value);
+ }
+ if (adapter == IArtifactKey[].class && artifacts != null) {
+ return adapter.cast(artifacts.toArray(IArtifactKey[]::new));
+ }
+
+ return null;
+ }
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PGPPublicKeyViewDialog.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PGPPublicKeyViewDialog.java
new file mode 100644
index 000000000..a6cbf3be1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/PGPPublicKeyViewDialog.java
@@ -0,0 +1,248 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.dialogs;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.List;
+import org.bouncycastle.bcpg.*;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Presents information about a key in a format similar to what key servers
+ * display.
+ *
+ * @since 1.2.4
+ */
+public class PGPPublicKeyViewDialog extends TitleAreaDialog {
+
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); //$NON-NLS-1$
+
+ final private PGPPublicKey originalKey;
+
+ final private PGPPublicKeyService keyService;
+
+ private StyledText styledText;
+
+ public PGPPublicKeyViewDialog(Shell parentShell, PGPPublicKey key, PGPPublicKeyService keyService) {
+ super(parentShell);
+ this.originalKey = key;
+ this.keyService = keyService;
+ DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(ProvUIMessages.PGPPublicKeyViewDialog_Title);
+ if (keyService != null) {
+ computeVerifiedCertifications(newShell);
+ }
+ }
+
+ @Override
+ protected void setShellStyle(int newShellStyle) {
+ super.setShellStyle(newShellStyle | SWT.RESIZE | SWT.DIALOG_TRIM);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ composite.setLayoutData(data);
+
+ styledText = new StyledText(composite, SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // Create a sightly smaller text (mono-space) font.
+ FontData[] fontData = JFaceResources.getTextFont().getFontData();
+ for (FontData fontDataElement : fontData) {
+ fontDataElement.setHeight(fontDataElement.getHeight() - 1);
+ }
+ Font font = new Font(styledText.getDisplay(), fontData);
+ styledText.setFont(font);
+ styledText.addDisposeListener(e -> font.dispose());
+
+ GC gc = new GC(styledText);
+ gc.setFont(font);
+ data.widthHint = convertWidthInCharsToPixels(gc.getFontMetrics(), 110);
+ gc.dispose();
+
+ update(originalKey, Set.of());
+ return composite;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CLOSE_LABEL, true).setFocus();
+ }
+
+ @SuppressWarnings("nls")
+ protected void update(PGPPublicKey key, Set<PGPPublicKey> verifiedCertifications) {
+ StyledString content = new StyledString();
+ String fingerprint = PGPPublicKeyService.toHexFingerprint(key);
+
+ PublicKeyPacket publicKeyPacket = key.getPublicKeyPacket();
+ publicKeyPacket.getAlgorithm();
+ content.append(" ");
+ content.append(publicKeyPacket instanceof PublicSubkeyPacket ? "sub" : "pub", StyledString.QUALIFIER_STYLER);
+ content.append(" ");
+
+ int algorithm = publicKeyPacket.getAlgorithm();
+ switch (algorithm) {
+ case PublicKeyAlgorithmTags.RSA_GENERAL:
+ case PublicKeyAlgorithmTags.RSA_ENCRYPT:
+ case PublicKeyAlgorithmTags.RSA_SIGN: {
+ content.append("rsa");
+ break;
+ }
+ case PublicKeyAlgorithmTags.DSA: {
+ content.append("dsa");
+ break;
+ }
+ case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT:
+ case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: {
+ content.append("elgamal");
+ break;
+ }
+ default: {
+ content.append("[");
+ content.append(Integer.toString(algorithm));
+ content.append("]");
+ break;
+ }
+
+ }
+ int bitStrength = key.getBitStrength();
+ content.append(Integer.toString(bitStrength));
+ content.append("/");
+ content.append(fingerprint);
+
+ content.append(" ");
+ content.append(DATE_FORMAT.format(key.getCreationTime()));
+
+ content.append(" ");
+ content.append("\n");
+
+ List<String> users = new ArrayList<>();
+ key.getUserIDs().forEachRemaining(users::add);
+ if (!users.isEmpty()) {
+ for (String user : users) {
+ content.append(" ");
+ content.append("uid", StyledString.QUALIFIER_STYLER);
+ content.append(" ");
+ content.append(user, StyledString.COUNTER_STYLER);
+ content.append("\n");
+ }
+ }
+
+ Long subKeyOf = null;
+
+ for (Iterator<PGPSignature> signatures = key.getSignatures(); signatures.hasNext();) {
+ PGPSignature signature = signatures.next();
+ long keyID = signature.getKeyID();
+
+ if (signature.getSignatureType() == PGPSignature.SUBKEY_BINDING) {
+ subKeyOf = keyID;
+ }
+
+ content.append(" ");
+ content.append("sig", StyledString.QUALIFIER_STYLER);
+ content.append(" ");
+ content.append(PGPPublicKeyService.toHex(keyID));
+ content.append(" ");
+ Date creationTime = signature.getCreationTime();
+ String formattedCreationTime = DATE_FORMAT.format(creationTime);
+ content.append(formattedCreationTime);
+ long signatureExpirationTime = signature.getHashedSubPackets().getSignatureExpirationTime();
+ content.append(" ");
+ content.append(signatureExpirationTime == 0 ? formattedCreationTime.replaceAll(".", "_")
+ : DATE_FORMAT.format(new Date(creationTime.getTime() + 1000 * signatureExpirationTime)));
+
+ content.append(" ");
+ Optional<PGPPublicKey> resolvedKey = verifiedCertifications.stream().filter(k -> k.getKeyID() == keyID)
+ .findFirst();
+
+ long keyExpirationTime = signature.getHashedSubPackets().getKeyExpirationTime();
+ content.append(keyExpirationTime == 0 || resolvedKey == null || !resolvedKey.isPresent()
+ ? formattedCreationTime.replaceAll(".", "_")
+ : DATE_FORMAT.format(
+ new Date(resolvedKey.get().getCreationTime().getTime() + 1000 * keyExpirationTime)));
+
+ if (resolvedKey != null && resolvedKey.isPresent()) {
+ content.append(" ");
+ content.append(getLabel(resolvedKey.get()), StyledString.COUNTER_STYLER);
+ }
+
+ content.append("\n");
+ }
+
+ styledText.setText(content.getString());
+ styledText.setStyleRanges(content.getStyleRanges());
+
+ List<String> title = new ArrayList<>();
+ if (subKeyOf != null) {
+ long keyID = subKeyOf;
+ verifiedCertifications.stream().filter(k -> k.getKeyID() == keyID).findFirst()
+ .ifPresentOrElse(k -> title.add(getLabel(k)), () -> title.add(PGPPublicKeyService.toHex(keyID)));
+ }
+ title.add((subKeyOf == null ? "" : "sub ") + (users.isEmpty() ? fingerprint : users.get(0)));
+
+ setTitle(String.join("\n", title));
+ }
+
+ private String getLabel(PGPPublicKey key) {
+ Iterator<String> userIDs = key.getUserIDs();
+ if (userIDs.hasNext()) {
+ return userIDs.next();
+
+ }
+ return PGPPublicKeyService.toHexFingerprint(key);
+ }
+
+ private void computeVerifiedCertifications(Shell shell) {
+ Display display = shell.getDisplay();
+ new Job(PGPPublicKeyViewDialog.class.getName()) {
+ {
+ setSystem(true);
+ setPriority(Job.SHORT);
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ synchronized (keyService) {
+ PGPPublicKey enhancedKey = keyService.addKey(originalKey);
+ Set<PGPPublicKey> verifiedCertifications = keyService.getVerifiedCertifications(originalKey);
+ display.asyncExec(() -> {
+ if (!shell.isDisposed()) {
+ update(enhancedKey, verifiedCertifications);
+ }
+ });
+ }
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java
index 71479559e..47901c652 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/ProvisioningOperationWizard.java
@@ -204,7 +204,7 @@ public abstract class ProvisioningOperationWizard extends Wizard {
if (!operation.hasResolved()) {
operation.resolveModal(monitor);
}
- if (operation.hasResolved()) {
+ if (operation.getProfileChangeRequest() != null) {
this.localJRECheckPlan = ProvUI.toCompabilityWithCurrentJREProvisioningPlan(operation, null);
if (!compatibleWithCurrentEE()) {
couldNotResolveStatus = localJRECheckPlan.getStatus();
@@ -215,6 +215,10 @@ public abstract class ProvisioningOperationWizard extends Wizard {
return false;
}
}
+ if (localJRECheckPlan == null) {
+ return true;
+ }
+
IStatus currentEEPlanStatus = localJRECheckPlan.getStatus();
if (currentEEPlanStatus.getSeverity() != IStatus.ERROR) {
return true;
@@ -337,7 +341,8 @@ public abstract class ProvisioningOperationWizard extends Wizard {
try {
runnableContext.run(true, true, monitor -> {
operation.resolveModal(monitor);
- if (getPolicy().getCheckAgainstCurrentExecutionEnvironment()) {
+ if (operation.getProfileChangeRequest() != null
+ && getPolicy().getCheckAgainstCurrentExecutionEnvironment()) {
this.localJRECheckPlan = ProvUI.toCompabilityWithCurrentJREProvisioningPlan(operation, monitor);
if (!compatibleWithCurrentEE()) {
couldNotResolveStatus = localJRECheckPlan.getStatus();
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/TrustCertificateDialog.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/TrustCertificateDialog.java
index 4c4fc386e..2d6cc8237 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/TrustCertificateDialog.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/dialogs/TrustCertificateDialog.java
@@ -17,111 +17,181 @@ package org.eclipse.equinox.internal.p2.ui.dialogs;
import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
import java.io.*;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Iterator;
+import java.security.cert.*;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+import java.util.List;
import java.util.function.Function;
+import java.util.stream.Collectors;
import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.openpgp.PGPPublicKey;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
-import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.ui.*;
import org.eclipse.equinox.internal.p2.ui.viewers.CertificateLabelProvider;
import org.eclipse.equinox.internal.provisional.security.ui.X500PrincipalHelper;
-import org.eclipse.equinox.internal.provisional.security.ui.X509CertificateViewDialog;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.util.Policy;
import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.widgets.LabelFactory;
+import org.eclipse.jface.widgets.WidgetFactory;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionDialog;
/**
* A dialog that displays a certificate chain and asks the user if they trust
- * the certificate providers.
+ * the certificate providers. It also supports prompting about unsigned content.
*/
public class TrustCertificateDialog extends SelectionDialog {
+ private static final String EXPORT_FILTER_PATH = "exportFilterPath"; //$NON-NLS-1$
- private Object inputElement;
- private IStructuredContentProvider contentProvider;
+ private CheckboxTableViewer certifcateViewer;
- private static final int SIZING_SELECTION_WIDGET_HEIGHT = 250;
- private static final int SIZING_SELECTION_WIDGET_WIDTH = 300;
+ private TreeViewer certificateChainViewer;
- CheckboxTableViewer listViewer;
+ private CheckboxTableViewer artifactViewer;
- private TreeViewer certificateChainViewer;
- protected TreeNode parentElement;
- protected Object selectedCertificate;
private Button detailsButton;
+ private Button exportButton;
+
+ private boolean rememberSelectedSigners = true;
+
+ private boolean trustAlways;
+
+ private final Map<TreeNode, List<IArtifactKey>> artifactMap = new LinkedHashMap<>();
+
public TrustCertificateDialog(Shell parentShell, Object input) {
super(parentShell);
- inputElement = input;
- this.contentProvider = new TreeNodeContentProvider();
+
+ setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.RESIZE | SWT.MAX | getDefaultOrientation());
+
+ if (input instanceof TreeNode[]) {
+ for (TreeNode node : (TreeNode[]) input) {
+ IArtifactKey[] associatedArtifacts = null;
+ if (node instanceof IAdaptable) {
+ associatedArtifacts = ((IAdaptable) node).getAdapter(IArtifactKey[].class);
+ }
+ artifactMap.put(node, associatedArtifacts == null ? List.of() : Arrays.asList(associatedArtifacts));
+ }
+ }
+
setTitle(ProvUIMessages.TrustCertificateDialog_Title);
- setMessage(ProvUIMessages.TrustCertificateDialog_Message);
- setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | SWT.RESIZE | getDefaultOrientation());
- }
- private static class PGPOrX509ColumnLabelProvider extends ColumnLabelProvider {
- private Function<PGPPublicKey, String> pgpMap;
- private Function<X509Certificate, String> x509map;
+ boolean unsignedContent = artifactMap.keySet().stream().map(TreeNode::getValue).anyMatch(Objects::isNull);
+ boolean pgpContent = containsInstance(input, PGPPublicKey.class);
+ boolean certifcateContent = containsInstance(input, Certificate.class);
- public PGPOrX509ColumnLabelProvider(Function<PGPPublicKey, String> pgpMap,
- Function<X509Certificate, String> x509map) {
- this.pgpMap = pgpMap;
- this.x509map = x509map;
+ List<String> messages = new ArrayList<>();
+ if (certifcateContent || pgpContent) {
+ messages.add(ProvUIMessages.TrustCertificateDialog_Message);
+ }
+ if (unsignedContent) {
+ messages.add(ProvUIMessages.TrustCertificateDialog_MessageUnsigned);
+ }
+ if (certifcateContent || pgpContent) {
+ messages.add(ProvUIMessages.TrustCertificateDialog_MessageNameWarning);
+ }
+ if (pgpContent) {
+ messages.add(ProvUIMessages.TrustCertificateDialog_MessagePGP);
}
+ setMessage(String.join(" ", messages)); //$NON-NLS-1$
- @Override
- public String getText(Object element) {
- if (element instanceof TreeNode) {
- element = ((TreeNode) element).getValue();
- }
- if (element instanceof PGPPublicKey) {
- return pgpMap.apply((PGPPublicKey) element);
- }
- if (element instanceof X509Certificate) {
- return x509map.apply((X509Certificate) element);
- }
- return super.getText(element);
+ if (PlatformUI.isWorkbenchRunning()) {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(parentShell, IProvHelpContextIds.TRUST_DIALOG);
+ }
+ }
+
+ public boolean isRememberSelectedSigners() {
+ return rememberSelectedSigners;
+ }
+
+ public boolean isTrustAlways() {
+ return trustAlways;
+ }
+
+ @Override
+ protected Label createMessageArea(Composite composite) {
+ // Ensure that the message supports wrapping for a long text message.
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ data.widthHint = convertWidthInCharsToPixels(120);
+ LabelFactory factory = WidgetFactory.label(SWT.WRAP).font(composite.getFont()).layoutData(data);
+ if (getMessage() != null) {
+ factory.text(getMessage());
}
+ return factory.create(composite);
}
@Override
protected Control createDialogArea(Composite parent) {
- Composite composite = createUpperDialogArea(parent);
- certificateChainViewer = new TreeViewer(composite, SWT.BORDER);
- GridLayout layout = new GridLayout();
- certificateChainViewer.getTree().setLayout(layout);
- GridData data = new GridData(GridData.FILL_BOTH);
- data.grabExcessHorizontalSpace = true;
- certificateChainViewer.getTree().setLayoutData(data);
- certificateChainViewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
- certificateChainViewer.setContentProvider(new TreeNodeContentProvider());
- certificateChainViewer.setLabelProvider(new CertificateLabelProvider());
- certificateChainViewer.addSelectionChangedListener(getChainSelectionListener());
- if (inputElement instanceof Object[]) {
- ISelection selection = null;
- Object[] nodes = (Object[]) inputElement;
- if (nodes.length > 0) {
- selection = new StructuredSelection(nodes[0]);
- certificateChainViewer.setInput(new TreeNode[] { (TreeNode) nodes[0] });
- selectedCertificate = nodes[0];
- }
- listViewer.setSelection(selection);
+ Composite mainComposite = (Composite) super.createDialogArea(parent);
+ Dialog.applyDialogFont(mainComposite);
+ initializeDialogUnits(mainComposite);
+
+ createMessageArea(mainComposite);
+
+ SashForm sashForm = new SashForm(mainComposite, SWT.VERTICAL);
+ sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ createCertificateViewerArea(createSashFormArea(sashForm));
+
+ // Create this area only if we have keys or certificates.
+ boolean containsCertificates = containsInstance(artifactMap.keySet(), PGPPublicKey.class)
+ || containsInstance(artifactMap.keySet(), Certificate.class);
+ if (containsCertificates) {
+ createCertficateChainViewerArea(createSashFormArea(sashForm));
}
- listViewer.addDoubleClickListener(getDoubleClickListener());
- listViewer.addSelectionChangedListener(getParentSelectionListener());
- createButtons(composite);
- detailsButton.setEnabled(selectedCertificate instanceof X509Certificate);
- return composite;
+
+ // Sort the set of all artifacts and create the lower area only if there are
+ // artifacts.
+ Comparator<Object> comparator = Policy.getComparator();
+ Set<IArtifactKey> artifacts = artifactMap.values().stream().flatMap(Collection::stream)
+ .collect(Collectors.toCollection(() -> new TreeSet<>((a1, a2) -> {
+ int result = comparator.compare(a1.getId(), a2.getId());
+ if (result == 0) {
+ result = a1.getVersion().compareTo(a2.getVersion());
+ if (result == 0) {
+ result = a1.getClassifier().compareTo(a2.getClassifier());
+ }
+ }
+ return result;
+ })));
+ if (!artifacts.isEmpty()) {
+ crreateArtifactViewerArea(createSashFormArea(sashForm), artifacts);
+ }
+
+ // Set weights based on the children's preferred size.
+ Control[] children = sashForm.getChildren();
+ int[] weights = new int[children.length];
+ for (int i = 0; i < children.length; ++i) {
+ weights[i] = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, false).y;
+ }
+ sashForm.setWeights(weights);
+
+ if (!getInitialElementSelections().isEmpty()) {
+ checkInitialSelections();
+ }
+
+ if (!artifactMap.isEmpty()) {
+ certifcateViewer.setSelection(new StructuredSelection(artifactMap.keySet().iterator().next()));
+ }
+
+ return mainComposite;
}
@Override
@@ -129,26 +199,21 @@ public class TrustCertificateDialog extends SelectionDialog {
createButton(parent, IDialogConstants.OK_ID, ProvUIMessages.TrustCertificateDialog_AcceptSelectedButtonLabel,
true);
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
- super.getOkButton().setEnabled(false);
+ updateOkButton();
}
private void createButtons(Composite composite) {
Composite buttonComposite = new Composite(composite, SWT.NONE);
buttonComposite.setLayout(new RowLayout());
- // Details button to view certificate chain
+
detailsButton = new Button(buttonComposite, SWT.NONE);
detailsButton.setText(ProvUIMessages.TrustCertificateDialog_Details);
detailsButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
- Object o = selectedCertificate;
- if (selectedCertificate instanceof TreeNode) {
- o = ((TreeNode) selectedCertificate).getValue();
- }
- if (o instanceof X509Certificate) {
- X509Certificate cert = (X509Certificate) o;
- X509CertificateViewDialog certificateDialog = new X509CertificateViewDialog(getShell(), cert);
- certificateDialog.open();
+ X509Certificate cert = getInstance(certificateChainViewer.getSelection(), X509Certificate.class);
+ if (cert != null) {
+ CertificateLabelProvider.openDialog(getShell(), cert);
}
}
@@ -158,46 +223,48 @@ public class TrustCertificateDialog extends SelectionDialog {
}
});
- Button exportButton = new Button(buttonComposite, SWT.NONE);
+ exportButton = new Button(buttonComposite, SWT.NONE);
exportButton.setText(ProvUIMessages.TrustCertificateDialog_Export);
exportButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
- Object o = selectedCertificate;
- if (selectedCertificate instanceof TreeNode) {
- o = ((TreeNode) selectedCertificate).getValue();
- }
- FileDialog destination = new FileDialog(detailsButton.getShell(), SWT.SAVE);
- destination.setText(ProvUIMessages.TrustCertificateDialog_Export);
- if (o instanceof X509Certificate) {
- X509Certificate cert = (X509Certificate) o;
- destination.setFilterExtensions(new String[] { "*.der" }); //$NON-NLS-1$
- destination.setFileName(cert.getSerialNumber().toString() + ".der"); //$NON-NLS-1$
- String path = destination.open();
- if (path == null) {
- return;
- }
- File destinationFile = new File(path);
- try (FileOutputStream output = new FileOutputStream(destinationFile)) {
- output.write(cert.getEncoded());
- } catch (IOException | CertificateEncodingException ex) {
- ProvUIActivator.getDefault().getLog()
- .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
- }
- } else if (o instanceof PGPPublicKey) {
- PGPPublicKey key = (PGPPublicKey) o;
- destination.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$
- destination.setFileName(Long.toHexString(key.getKeyID()) + ".asc"); //$NON-NLS-1$
- String path = destination.open();
- if (path == null) {
- return;
- }
- File destinationFile = new File(path);
- try (OutputStream output = new ArmoredOutputStream(new FileOutputStream(destinationFile))) {
- output.write(key.getEncoded());
- } catch (IOException ex) {
- ProvUIActivator.getDefault().getLog()
- .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ ISelection selection = certificateChainViewer.getSelection();
+ X509Certificate cert = getInstance(selection, X509Certificate.class);
+ PGPPublicKey key = getInstance(selection, PGPPublicKey.class);
+ if (cert != null || key != null) {
+ FileDialog destination = new FileDialog(exportButton.getShell(), SWT.SAVE);
+ destination.setFilterPath(getFilterPath(EXPORT_FILTER_PATH));
+ destination.setText(ProvUIMessages.TrustCertificateDialog_Export);
+ if (cert != null) {
+ destination.setFilterExtensions(new String[] { "*.der" }); //$NON-NLS-1$
+ destination.setFileName(cert.getSerialNumber().toString() + ".der"); //$NON-NLS-1$
+ String path = destination.open();
+ setFilterPath(EXPORT_FILTER_PATH, destination.getFilterPath());
+ if (path == null) {
+ return;
+ }
+ File destinationFile = new File(path);
+ try (FileOutputStream output = new FileOutputStream(destinationFile)) {
+ output.write(cert.getEncoded());
+ } catch (IOException | CertificateEncodingException ex) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ }
+ } else {
+ destination.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$
+ destination.setFileName(userFriendlyFingerPrint(key) + ".asc"); //$NON-NLS-1$
+ String path = destination.open();
+ setFilterPath(EXPORT_FILTER_PATH, destination.getFilterPath());
+ if (path == null) {
+ return;
+ }
+ File destinationFile = new File(path);
+ try (OutputStream output = new ArmoredOutputStream(new FileOutputStream(destinationFile))) {
+ key.encode(output);
+ } catch (IOException ex) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex));
+ }
}
}
}
@@ -206,56 +273,277 @@ public class TrustCertificateDialog extends SelectionDialog {
public void widgetSelected(SelectionEvent e) {
widgetDefaultSelected(e);
}
-
});
}
- private Composite createUpperDialogArea(Composite parent) {
- Composite composite = (Composite) super.createDialogArea(parent);
- initializeDialogUnits(composite);
- createMessageArea(composite);
+ private Composite createSashFormArea(SashForm sashForm) {
+ Composite composite = new Composite(sashForm, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+ layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+ composite.setLayout(layout);
+ return composite;
+ }
+
+ private void createCertificateViewerArea(Composite composite) {
+
+ TableColumnLayout tableColumnLayout = new TableColumnLayout(true);
+ Composite tableComposite = WidgetFactory.composite(SWT.NONE)
+ .layoutData(new GridData(SWT.FILL, SWT.FILL, true, true)).layout(tableColumnLayout).create(composite);
+ Table table = WidgetFactory
+ .table(SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK)
+ .headerVisible(true).linesVisible(true).font(composite.getFont()).create(tableComposite);
+ certifcateViewer = new CheckboxTableViewer(table);
+ certifcateViewer.setContentProvider(new TreeNodeContentProvider());
- listViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
GridData data = new GridData(GridData.FILL_BOTH);
- data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
- data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
- listViewer.getTable().setLayoutData(data);
-
- listViewer.setContentProvider(contentProvider);
- TableViewerColumn typeColumn = new TableViewerColumn(listViewer, SWT.NONE);
- typeColumn.getColumn().setWidth(80);
- typeColumn.getColumn().setText(ProvUIMessages.TrustCertificateDialog_ObjectType);
- typeColumn.setLabelProvider(new PGPOrX509ColumnLabelProvider(key -> "PGP", cert -> "x509")); //$NON-NLS-1$ //$NON-NLS-2$
- TableViewerColumn idColumn = new TableViewerColumn(listViewer, SWT.NONE);
- idColumn.getColumn().setWidth(200);
- idColumn.getColumn().setText(ProvUIMessages.TrustCertificateDialog_Id);
- idColumn.setLabelProvider(new PGPOrX509ColumnLabelProvider(key -> Long.toHexString(key.getKeyID()),
- cert -> cert.getSerialNumber().toString()));
- TableViewerColumn signerColumn = new TableViewerColumn(listViewer, SWT.NONE);
- signerColumn.getColumn().setText(ProvUIMessages.TrustCertificateDialog_Name);
- signerColumn.getColumn().setWidth(400);
- signerColumn.setLabelProvider(new PGPOrX509ColumnLabelProvider(pgp -> {
- java.util.List<String> users = new ArrayList<>();
- pgp.getUserIDs().forEachRemaining(users::add);
- return String.join(",", users); //$NON-NLS-1$
- }, x509 -> {
- X500PrincipalHelper principalHelper = new X500PrincipalHelper(x509.getSubjectX500Principal());
- return principalHelper.getCN() + "; " + principalHelper.getOU() + "; " //$NON-NLS-1$ //$NON-NLS-2$
- + principalHelper.getO();
- }));
- listViewer.getTable().setHeaderVisible(true);
+ data.heightHint = convertHeightInCharsToPixels(Math.min(artifactMap.keySet().size() + 1, 6)) * 3 / 2;
+ data.widthHint = convertWidthInCharsToPixels(120);
+ tableComposite.setLayoutData(data);
+
+ // This column is packed later.
+ TableViewerColumn typeColumn = createColumn(certifcateViewer, ProvUIMessages.TrustCertificateDialog_ObjectType,
+ new PGPOrX509ColumnLabelProvider(key -> "PGP", cert -> "x509", //$NON-NLS-1$ //$NON-NLS-2$
+ ProvUIMessages.TrustCertificateDialog_Unsigned),
+ tableColumnLayout, 1);
+
+ createColumn(certifcateViewer, ProvUIMessages.TrustCertificateDialog_Id,
+ new PGPOrX509ColumnLabelProvider(TrustCertificateDialog::userFriendlyFingerPrint,
+ cert -> cert.getSerialNumber().toString(), ProvUIMessages.TrustCertificateDialog_NotApplicable),
+ tableColumnLayout, 10);
+
+ createColumn(certifcateViewer, ProvUIMessages.TrustCertificateDialog_Name,
+ new PGPOrX509ColumnLabelProvider(pgp -> {
+ java.util.List<String> users = new ArrayList<>();
+ pgp.getUserIDs().forEachRemaining(users::add);
+ return String.join(", ", users); //$NON-NLS-1$
+ }, x509 -> {
+ X500PrincipalHelper principalHelper = new X500PrincipalHelper(x509.getSubjectX500Principal());
+ return principalHelper.getCN() + "; " + principalHelper.getOU() + "; " //$NON-NLS-1$ //$NON-NLS-2$
+ + principalHelper.getO();
+ }, ProvUIMessages.TrustCertificateDialog_Unknown), tableColumnLayout, 15);
+
+ createColumn(certifcateViewer, ProvUIMessages.TrustCertificateDialog_dates,
+ new PGPOrX509ColumnLabelProvider(pgp -> {
+ if (pgp.getCreationTime().after(Date.from(Instant.now()))) {
+ return NLS.bind(ProvUIMessages.TrustCertificateDialog_NotYetValidStartDate,
+ pgp.getCreationTime());
+ }
+ long validSeconds = pgp.getValidSeconds();
+ if (validSeconds == 0) {
+ return ProvUIMessages.TrustCertificateDialog_valid;
+ }
+ Instant expires = pgp.getCreationTime().toInstant().plus(validSeconds, ChronoUnit.SECONDS);
+ return expires.isBefore(Instant.now())
+ ? NLS.bind(ProvUIMessages.TrustCertificateDialog_expiredSince, expires)
+ : NLS.bind(ProvUIMessages.TrustCertificateDialog_validExpires, expires);
+ }, x509 -> {
+ try {
+ x509.checkValidity();
+ return ProvUIMessages.TrustCertificateDialog_valid;
+ } catch (CertificateExpiredException expired) {
+ return ProvUIMessages.TrustCertificateDialog_expired;
+ } catch (CertificateNotYetValidException notYetValid) {
+ return ProvUIMessages.TrustCertificateDialog_notYetValid;
+ }
+ }, ProvUIMessages.TrustCertificateDialog_NotApplicable), tableColumnLayout, 10);
+
+ createMenu(certifcateViewer);
addSelectionButtons(composite);
- listViewer.setInput(inputElement);
+ certifcateViewer.addDoubleClickListener(e -> {
+ StructuredSelection selection = (StructuredSelection) e.getSelection();
+ X509Certificate cert = getInstance(selection, X509Certificate.class);
+ if (cert != null) {
+ // create and open dialog for certificate chain
+ CertificateLabelProvider.openDialog(getShell(), cert);
+ }
+ });
- if (!getInitialElementSelections().isEmpty()) {
- checkInitialSelections();
+ certifcateViewer.addSelectionChangedListener(e -> {
+ if (certificateChainViewer != null) {
+ TreeNode treeNode = getInstance(e.getSelection(), TreeNode.class);
+ if (treeNode != null) {
+ certificateChainViewer.setInput(new TreeNode[] { treeNode });
+ certificateChainViewer.setSelection(new StructuredSelection(treeNode));
+ } else {
+ certificateChainViewer.setInput(new TreeNode[] {});
+ }
+ }
+
+ updateOkButton();
+ });
+
+ certifcateViewer.setInput(artifactMap.keySet().toArray(TreeNode[]::new));
+
+ typeColumn.getColumn().pack();
+ }
+
+ private void createCertficateChainViewerArea(Composite composite) {
+ certificateChainViewer = new TreeViewer(composite, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ int treeSize = artifactMap.keySet().stream().map(TrustCertificateDialog::computeTreeSize)
+ .max(Integer::compareTo).orElse(0);
+ data.heightHint = convertHeightInCharsToPixels(Math.min(treeSize, 5));
+ data.widthHint = convertWidthInCharsToPixels(120);
+ certificateChainViewer.getTree().setLayoutData(data);
+
+ certificateChainViewer.setAutoExpandLevel(3);
+ certificateChainViewer.setContentProvider(new TreeNodeContentProvider());
+ certificateChainViewer.setLabelProvider(new CertificateLabelProvider() {
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TreeNode) {
+ Object o = ((TreeNode) element).getValue();
+ if (o instanceof PGPPublicKey) {
+ PGPPublicKey key = (PGPPublicKey) o;
+ String userFriendlyFingerPrint = userFriendlyFingerPrint(key);
+ java.util.List<String> users = new ArrayList<>();
+ key.getUserIDs().forEachRemaining(users::add);
+ String userIDs = String.join(", ", users); //$NON-NLS-1$
+ if (!userIDs.isEmpty()) {
+ return userFriendlyFingerPrint + " [" + userIDs + "]"; //$NON-NLS-1$//$NON-NLS-2$
+ }
+ return userFriendlyFingerPrint;
+ } else if (o == null) {
+ return ProvUIMessages.TrustCertificateDialog_Unsigned;
+ }
+ }
+
+ return super.getText(element);
+ }
+ });
+
+ certificateChainViewer.addSelectionChangedListener(event -> {
+ ISelection selection = event.getSelection();
+ boolean containsCertificate = containsInstance(selection, X509Certificate.class);
+ detailsButton.setEnabled(containsCertificate);
+ exportButton.setEnabled(containsCertificate || containsInstance(selection, PGPPublicKey.class));
+ });
+
+ createMenu(certificateChainViewer);
+
+ createButtons(composite);
+ }
+
+ private void crreateArtifactViewerArea(Composite composite, Set<IArtifactKey> artifacts) {
+ TableColumnLayout tableColumnLayout = new TableColumnLayout(true);
+ Composite tableComposite = WidgetFactory.composite(SWT.NONE)
+ .layoutData(new GridData(SWT.FILL, SWT.FILL, true, true)).layout(tableColumnLayout).create(composite);
+ Table table = WidgetFactory.table(SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION)
+ .headerVisible(true).linesVisible(true).font(composite.getFont()).create(tableComposite);
+ artifactViewer = new CheckboxTableViewer(table);
+ artifactViewer.setContentProvider(ArrayContentProvider.getInstance());
+
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = convertHeightInCharsToPixels(Math.min(artifacts.size() + 1, 10)) * 3 / 2;
+ data.widthHint = convertWidthInCharsToPixels(120);
+ tableComposite.setLayoutData(data);
+
+ Font font = table.getFont();
+ FontData[] fontDatas = font.getFontData();
+ for (FontData fontData : fontDatas) {
+ fontData.setStyle(fontData.getStyle() | SWT.BOLD);
}
+ Font boldFont = new Font(table.getDisplay(), fontDatas);
+ composite.addDisposeListener(e -> boldFont.dispose());
+
+ Function<IArtifactKey, Font> fontProvider = e -> {
+ for (Object object : certifcateViewer.getCheckedElements()) {
+ List<IArtifactKey> list = artifactMap.get(object);
+ if (list != null && list.contains(e)) {
+ return boldFont;
+ }
+ }
+ return null;
+ };
- Dialog.applyDialogFont(composite);
+ certifcateViewer.addCheckStateListener(e -> artifactViewer.refresh(true));
+
+ artifactViewer.addPostSelectionChangedListener(e -> {
+ if (table.isFocusControl()) {
+ List<?> selection = e.getStructuredSelection().toList();
+ List<TreeNode> newSelection = new ArrayList<>();
+ LOOP: for (Map.Entry<TreeNode, List<IArtifactKey>> entry : artifactMap.entrySet()) {
+ List<IArtifactKey> value = entry.getValue();
+ if (value != null) {
+ for (IArtifactKey key : value) {
+ if (selection.contains(key)) {
+ newSelection.add(entry.getKey());
+ continue LOOP;
+ }
+ }
+ }
+ }
- return composite;
+ certifcateViewer.setSelection(new StructuredSelection(newSelection), true);
+ }
+ });
+
+ certifcateViewer.addPostSelectionChangedListener(e -> {
+ if (!table.isFocusControl()) {
+ Set<IArtifactKey> associatedArtifacts = new LinkedHashSet<>();
+ for (Object object : e.getStructuredSelection()) {
+ List<IArtifactKey> list = artifactMap.get(object);
+ if (list != null) {
+ associatedArtifacts.addAll(list);
+ }
+ }
+
+ artifactViewer.setSelection(new StructuredSelection(associatedArtifacts.toArray()), true);
+
+ // Reorder the artifacts so that the selected ones are first.
+ LinkedHashSet<IArtifactKey> newInput = new LinkedHashSet<>(artifacts);
+ newInput.retainAll(associatedArtifacts);
+ newInput.addAll(artifacts);
+ artifactViewer.setInput(newInput);
+
+ artifactViewer.setSelection(new StructuredSelection(associatedArtifacts.toArray()), true);
+ }
+ });
+
+ TableViewerColumn classifierColumn = createColumn(artifactViewer,
+ ProvUIMessages.TrustCertificateDialog_Classifier,
+ new ArtifactLabelProvider(a -> a.getClassifier(), fontProvider), tableColumnLayout, 1);
+ createColumn(artifactViewer, ProvUIMessages.TrustCertificateDialog_ArtifactId,
+ new ArtifactLabelProvider(a -> a.getId(), fontProvider), tableColumnLayout, 10);
+ createColumn(artifactViewer, ProvUIMessages.TrustCertificateDialog_Version,
+ new ArtifactLabelProvider(a -> a.getVersion().toString(), fontProvider), tableColumnLayout, 10);
+
+ artifactViewer.setInput(artifacts);
+
+ classifierColumn.getColumn().pack();
+ }
+
+ private void createMenu(StructuredViewer viewer) {
+ Control control = viewer.getControl();
+ Menu menu = new Menu(control);
+ control.setMenu(menu);
+ MenuItem item = new MenuItem(menu, SWT.PUSH);
+ item.setText(ProvUIMessages.TrustCertificateDialog_CopyFingerprint);
+ item.addSelectionListener(widgetSelectedAdapter(e -> {
+ PGPPublicKey key = getInstance(viewer.getSelection(), PGPPublicKey.class);
+ if (key != null) {
+ Clipboard clipboard = new Clipboard(getShell().getDisplay());
+ clipboard.setContents(new Object[] { userFriendlyFingerPrint(key) },
+ new Transfer[] { TextTransfer.getInstance() });
+ clipboard.dispose();
+ }
+ }));
+ viewer.addSelectionChangedListener(
+ e -> item.setEnabled(containsInstance(e.getSelection(), PGPPublicKey.class)));
+ }
+
+ private TableViewerColumn createColumn(TableViewer tableViewer, String text, ColumnLabelProvider labelProvider,
+ TableColumnLayout tableColumnLayout, int columnWeight) {
+ TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE);
+ column.getColumn().setText(text);
+ column.setLabelProvider(labelProvider);
+ tableColumnLayout.setColumnData(column.getColumn(), new ColumnWeightData(columnWeight));
+ return column;
}
/**
@@ -265,7 +553,10 @@ public class TrustCertificateDialog extends SelectionDialog {
private void checkInitialSelections() {
Iterator<?> itemsToCheck = getInitialElementSelections().iterator();
while (itemsToCheck.hasNext()) {
- listViewer.setChecked(itemsToCheck.next(), true);
+ certifcateViewer.setChecked(itemsToCheck.next(), true);
+ if (artifactViewer != null) {
+ artifactViewer.refresh(true);
+ }
}
}
@@ -275,93 +566,239 @@ public class TrustCertificateDialog extends SelectionDialog {
* @param composite org.eclipse.swt.widgets.Composite
*/
private void addSelectionButtons(Composite composite) {
- Composite buttonComposite = new Composite(composite, SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.numColumns = 0;
- layout.marginWidth = 0;
- layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
- buttonComposite.setLayout(layout);
- buttonComposite.setLayoutData(new GridData(SWT.END, SWT.TOP, true, false));
+ int horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+
+ Composite buttonArea = new Composite(composite, SWT.NONE);
+ GridLayout buttonAreaLayout = new GridLayout();
+ buttonAreaLayout.numColumns = 2;
+ buttonAreaLayout.marginWidth = 0;
+ buttonAreaLayout.horizontalSpacing = horizontalSpacing;
+ buttonArea.setLayout(buttonAreaLayout);
+ buttonArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ Composite leftButtonArea = new Composite(buttonArea, SWT.NONE);
+ GridLayout leftButtonAreaLayout = new GridLayout();
+ leftButtonAreaLayout.numColumns = 0;
+ leftButtonAreaLayout.marginWidth = 0;
+ leftButtonAreaLayout.horizontalSpacing = horizontalSpacing;
+ leftButtonArea.setLayout(leftButtonAreaLayout);
+ leftButtonArea.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));
+
+ if (containsInstance(artifactMap.keySet(), PGPPublicKey.class)
+ || containsInstance(artifactMap.keySet(), Certificate.class)) {
+ Button rememberSelectionButton = createCheckButton(leftButtonArea,
+ ProvUIMessages.TrustCertificateDialog_RememberSigners);
+ rememberSelectionButton.setSelection(rememberSelectedSigners);
+ rememberSelectionButton.addSelectionListener(widgetSelectedAdapter(e -> {
+ rememberSelectedSigners = rememberSelectionButton.getSelection();
+ }));
+ }
- Button selectButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID,
- ProvUIMessages.TrustCertificateDialog_SelectAll, false);
+ Button trustAlwaysButton = createCheckButton(leftButtonArea, ProvUIMessages.TrustCertificateDialog_AlwaysTrust);
+ trustAlwaysButton.addSelectionListener(widgetSelectedAdapter(e -> {
+ if (trustAlwaysButton.getSelection()) {
+ // Prompt the user to ensure they really understand what they've chosen, the
+ // risk, and where the preference is stored if they wish to change it in the
+ // future. Also ensure that the default button is no so that they must
+ // explicitly click the yes button, not just hit enter.
+ MessageDialog messageDialog = new MessageDialog(getShell(),
+ ProvUIMessages.TrustCertificateDialog_AlwaysTrustConfirmationTitle, null,
+ ProvUIMessages.TrustCertificateDialog_AlwaysTrustConfirmationMessage, MessageDialog.QUESTION,
+ new String[] { ProvUIMessages.TrustCertificateDialog_AlwaysTrustYes,
+ ProvUIMessages.TrustCertificateDialog_AlwaysTrustNo },
+ 1) {
+ @Override
+ public Image getImage() {
+ return getWarningImage();
+ }
+ };
+ int result = messageDialog.open();
+ if (result != Window.OK) {
+ // Restore the checkbox state.
+ trustAlwaysButton.setSelection(false);
+ } else {
+ certifcateViewer.setAllChecked(true);
+ if (artifactViewer != null) {
+ artifactViewer.refresh(true);
+ }
+ updateOkButton();
+ }
+ }
+ trustAlways = trustAlwaysButton.getSelection();
+ }));
- SelectionListener listener = widgetSelectedAdapter(e -> {
- listViewer.setAllChecked(true);
- getOkButton().setEnabled(true);
- });
- selectButton.addSelectionListener(listener);
+ Composite rightButtonArea = new Composite(buttonArea, SWT.NONE);
+ GridLayout rightButtonAreaLayout = new GridLayout();
+ rightButtonAreaLayout.numColumns = 0;
+ rightButtonAreaLayout.marginWidth = 0;
+ rightButtonAreaLayout.horizontalSpacing = horizontalSpacing;
+ rightButtonArea.setLayout(rightButtonAreaLayout);
+ rightButtonArea.setLayoutData(new GridData(SWT.END, SWT.TOP, true, false));
- Button deselectButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID,
- ProvUIMessages.TrustCertificateDialog_DeselectAll, false);
+ Button selectButton = createButton(rightButtonArea, IDialogConstants.SELECT_ALL_ID,
+ ProvUIMessages.TrustCertificateDialog_SelectAll, false);
+ selectButton.addSelectionListener(widgetSelectedAdapter(e -> {
+ certifcateViewer.setAllChecked(true);
+ if (artifactViewer != null) {
+ artifactViewer.refresh(true);
+ }
+ updateOkButton();
+ }));
- listener = widgetSelectedAdapter(e -> {
- listViewer.setAllChecked(false);
- getOkButton().setEnabled(false);
- });
- deselectButton.addSelectionListener(listener);
+ Button deselectButton = createButton(rightButtonArea, IDialogConstants.DESELECT_ALL_ID,
+ ProvUIMessages.TrustCertificateDialog_DeselectAll, false);
+ deselectButton.addSelectionListener(widgetSelectedAdapter(e -> {
+ certifcateViewer.setAllChecked(false);
+ if (artifactViewer != null) {
+ artifactViewer.refresh(true);
+ }
+ updateOkButton();
+ }));
}
- private ISelectionChangedListener getChainSelectionListener() {
- return event -> {
- ISelection selection = event.getSelection();
- if (selection instanceof StructuredSelection) {
- selectedCertificate = ((StructuredSelection) selection).getFirstElement();
- detailsButton.setEnabled(selectedCertificate instanceof X509Certificate);
- }
- };
+ protected Button createCheckButton(Composite parent, String label) {
+ ((GridLayout) parent.getLayout()).numColumns++;
+ Button button = WidgetFactory.button(SWT.CHECK).text(label).font(JFaceResources.getDialogFont()).create(parent);
+ setButtonLayoutData(button);
+ return button;
}
- public TreeViewer getCertificateChainViewer() {
- return certificateChainViewer;
+ private String getFilterPath(String key) {
+ IDialogSettings dialogSettings = DialogSettings
+ .getOrCreateSection(ProvUIActivator.getDefault().getDialogSettings(), getClass().getName());
+ String filterPath = dialogSettings.get(key);
+ if (filterPath == null) {
+ filterPath = System.getProperty("user.home"); //$NON-NLS-1$
+ }
+ return filterPath;
}
- private IDoubleClickListener getDoubleClickListener() {
- return event -> {
- StructuredSelection selection = (StructuredSelection) event.getSelection();
- Object selectedElement = selection.getFirstElement();
- if (selectedElement instanceof TreeNode) {
- TreeNode treeNode = (TreeNode) selectedElement;
- // create and open dialog for certificate chain
- X509CertificateViewDialog certificateViewDialog = new X509CertificateViewDialog(getShell(),
- (X509Certificate) treeNode.getValue());
- certificateViewDialog.open();
- }
- };
+ private void setFilterPath(String key, String filterPath) {
+ if (filterPath != null) {
+ IDialogSettings dialogSettings = DialogSettings
+ .getOrCreateSection(ProvUIActivator.getDefault().getDialogSettings(), getClass().getName());
+ dialogSettings.put(key, filterPath);
+ }
}
- private ISelectionChangedListener getParentSelectionListener() {
- return event -> {
- ISelection selection = event.getSelection();
- if (selection instanceof StructuredSelection) {
- TreeNode firstElement = (TreeNode) ((StructuredSelection) selection).getFirstElement();
- getCertificateChainViewer().setInput(new TreeNode[] { firstElement });
- getOkButton().setEnabled(listViewer.getChecked(firstElement));
- getCertificateChainViewer().refresh();
+ private void updateOkButton() {
+ Button okButton = getOkButton();
+ if (okButton != null) {
+ certifcateViewer.getCheckedElements();
+ Object[] checkedElements = certifcateViewer.getCheckedElements();
+ Set<IArtifactKey> artifacts = artifactMap.values().stream().flatMap(Collection::stream)
+ .collect(Collectors.toSet());
+ if (artifacts.isEmpty()) {
+ okButton.setEnabled(checkedElements.length > 0);
+ } else {
+ for (Object checkElement : checkedElements) {
+ artifacts.removeAll(artifactMap.get(checkElement));
+ }
+ okButton.setEnabled(artifacts.isEmpty());
}
- };
+ }
}
- /**
- * The <code>ListSelectionDialog</code> implementation of this
- * <code>Dialog</code> method builds a list of the selected elements for later
- * retrieval by the client and closes this dialog.
- */
@Override
protected void okPressed() {
- // Get the input children.
- Object[] children = contentProvider.getElements(inputElement);
+ setResult(Arrays.asList(certifcateViewer.getCheckedElements()));
+ super.okPressed();
+ }
+
+ private static class PGPOrX509ColumnLabelProvider extends ColumnLabelProvider {
+ private Function<PGPPublicKey, String> pgpMap;
+ private Function<X509Certificate, String> x509map;
+ private String unsignedValue;
+
+ public PGPOrX509ColumnLabelProvider(Function<PGPPublicKey, String> pgpMap,
+ Function<X509Certificate, String> x509map, String unsignedValue) {
+ this.pgpMap = pgpMap;
+ this.x509map = x509map;
+ this.unsignedValue = unsignedValue;
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof TreeNode) {
+ element = ((TreeNode) element).getValue();
+ }
+ if (element instanceof PGPPublicKey) {
+ return pgpMap.apply((PGPPublicKey) element);
+ }
+ if (element instanceof X509Certificate) {
+ return x509map.apply((X509Certificate) element);
+ }
- // Build a list of selected children.
+ if (element == null) {
+ return unsignedValue;
+ }
+ return super.getText(element);
+ }
+ }
+
+ private static class ArtifactLabelProvider extends ColumnLabelProvider {
+ private Function<IArtifactKey, String> labelProvider;
+ private Function<IArtifactKey, Font> fontProvider;
+
+ public ArtifactLabelProvider(Function<IArtifactKey, String> labelProvider,
+ Function<IArtifactKey, Font> fontProvider) {
+ this.labelProvider = labelProvider;
+ this.fontProvider = fontProvider;
+ }
+
+ @Override
+ public String getText(Object element) {
+ return labelProvider.apply((IArtifactKey) element);
+ }
+
+ @Override
+ public Font getFont(Object element) {
+ return fontProvider.apply((IArtifactKey) element);
+ }
+ }
+
+ private static int computeTreeSize(TreeNode node) {
+ int count = 1;
+ TreeNode[] children = node.getChildren();
if (children != null) {
- ArrayList<Object> list = new ArrayList<>();
- for (Object element : children) {
- if (listViewer.getChecked(element)) {
- list.add(element);
+ for (TreeNode child : children) {
+ count += computeTreeSize(child);
+ }
+ }
+ return count;
+ }
+
+ private static <T> T getInstance(Object element, Class<T> type) {
+ if (type.isInstance(element)) {
+ return type.cast(element);
+ } else if (element instanceof Iterable) {
+ for (Object object : ((Iterable<?>) element)) {
+ T instance = getInstance(object, type);
+ if (instance != null) {
+ return instance;
+ }
+ }
+ } else if (element instanceof TreeNode) {
+ return getInstance(((TreeNode) element).getValue(), type);
+ } else if (element instanceof TreeNode[]) {
+ for (TreeNode child : (TreeNode[]) element) {
+ T instance = getInstance(child, type);
+ if (instance != null) {
+ return instance;
}
}
- setResult(list);
}
- super.okPressed();
+ return null;
+ }
+
+ private static boolean containsInstance(Object element, Class<?> type) {
+ return getInstance(element, type) != null;
+ }
+
+ private static String userFriendlyFingerPrint(PGPPublicKey key) {
+ if (key == null) {
+ return null;
+ }
+ return PGPPublicKeyService.toHexFingerprint(key);
}
}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
index 561551af2..1d574dc40 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
@@ -12,6 +12,7 @@
# IBM Corporation - initial API and implementation
###############################################################################
+PGPPublicKeyViewDialog_Title=PGP Public Key Properties
ProfileModificationAction_InvalidSelections=Problem determining user request. Profile id: {0}, Selection count: {1}
ProfileModificationWizardPage_DetailsLabel=Details
ProfileSnapshots_Label=Installation History
@@ -257,6 +258,10 @@ RepositoryElement_NotFound=This repository is currently not available.
RepositoryTracker_DuplicateLocation=Duplicate location
MetadataRepositoryElement_RepositoryLoadError=Error loading repository {0}
IUViewQueryContext_NoCategorizedItemsDescription=You can uncheck the 'Group items by category' check box to see items without categories.
+KeySigningInfoFactory_FingerprintItem=Fingerprint=
+KeySigningInfoFactory_KeySignersSection=Key Signers:
+KeySigningInfoFactory_PGPSigningType=PGP Public Key
+KeySigningInfoFactory_UserIDItem=UserID=
QueriedElementWrapper_NoCategorizedItemsExplanation=There are no categorized items
QueriedElementWrapper_NoItemsExplanation=There are no items available
QueriedElementWrapper_SiteNotFound=Could not find {0}
@@ -276,13 +281,38 @@ RevertDialog_CancelButtonLabel=Cancel
RollbackProfileElement_CurrentInstallation=Current Installation
-TrustCertificateDialog_Details=\uD83D\uDD0D &Details...
+TrustCertificateDialog_Details=\uD83D\uDD0D D&etails...
TrustCertificateDialog_Export=\uD83D\uDCE5 E&xport...
TrustCertificateDialog_Title=Trust
TrustCertificateDialog_Message=Do you trust these signers?
-TrustCertificateDialog_AcceptSelectedButtonLabel=&Trust selected
+TrustCertificateDialog_MessageUnsigned=\u26A0\uFE0F\u00A0Do you trust unsigned content of unknown origin?
+TrustCertificateDialog_MessageNameWarning=\u26A0\uFE0F\u00A0The displayed originator names are not necessarily a reliable certification of origin.
+TrustCertificateDialog_MessagePGP=For PG keys, verification is typically achieved by querying the key\'s fingerprint against a trusted key server.
+TrustCertificateDialog_AcceptSelectedButtonLabel=&Trust Selected
+TrustCertificateDialog_AlwaysTrust=Always trust all content
+TrustCertificateDialog_AlwaysTrustConfirmationMessage=Are you certain you wish to accept all content, including unsigned content of unknown origin, with no further confirmation now and for all future operations?\n\n\
+Use the 'Select All' button to trust all content just for this operation.\n\n\
+This preference choice will be stored on the 'Install/Update > Trust' preference page.
+TrustCertificateDialog_AlwaysTrustConfirmationTitle=Always Trust Everything Confirmation
+TrustCertificateDialog_AlwaysTrustNo=No, Prompt Me Instead
+TrustCertificateDialog_AlwaysTrustYes=Yes, I Accept the Risk
+TrustCertificateDialog_ArtifactId=Id
TrustCertificateDialog_SelectAll=&Select All
TrustCertificateDialog_DeselectAll=&Deselect All
TrustCertificateDialog_ObjectType=Type
-TrustCertificateDialog_Id=Id
+TrustCertificateDialog_Id=Id/Fingerprint
TrustCertificateDialog_Name=Name
+TrustCertificateDialog_Classifier=Classifier
+TrustCertificateDialog_CopyFingerprint=Copy Fingerprint
+TrustCertificateDialog_dates=Validity Dates
+TrustCertificateDialog_NotApplicable=n/a
+TrustCertificateDialog_NotYetValidStartDate=\u274C Not yet valid, starts {0}
+TrustCertificateDialog_expiredSince=\u274C Expired since {0}
+TrustCertificateDialog_validExpires=\u2714\uFE0F Valid, expires {0}
+TrustCertificateDialog_valid=\u2714\uFE0F Valid
+TrustCertificateDialog_expired=\u274C Expired
+TrustCertificateDialog_notYetValid=\u274C Not yet valid
+TrustCertificateDialog_RememberSigners=Remember selected signers
+TrustCertificateDialog_Unknown=Unknown
+TrustCertificateDialog_Unsigned=Unsigned
+TrustCertificateDialog_Version=Version
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/viewers/CertificateLabelProvider.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/viewers/CertificateLabelProvider.java
index 9eb67d01e..39cc991d8 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/viewers/CertificateLabelProvider.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/viewers/CertificateLabelProvider.java
@@ -14,10 +14,11 @@
package org.eclipse.equinox.internal.p2.ui.viewers;
import java.security.cert.X509Certificate;
-import org.bouncycastle.openpgp.PGPPublicKey;
import org.eclipse.equinox.internal.provisional.security.ui.X500PrincipalHelper;
+import org.eclipse.equinox.internal.provisional.security.ui.X509CertificateViewDialog;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
/**
* A label provider that displays X509 certificates.
@@ -35,33 +36,12 @@ public class CertificateLabelProvider implements ILabelProvider {
Object o = ((TreeNode) element).getValue();
if (o instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) o;
- X500PrincipalHelper principalHelper = new X500PrincipalHelper(cert.getSubjectX500Principal());
- return principalHelper.getCN() + "; " + principalHelper.getOU() + "; " //$NON-NLS-1$ //$NON-NLS-2$
- + principalHelper.getO();
- } else if (o instanceof PGPPublicKey) {
- return userFriendlyFingerPrint((PGPPublicKey) o);
+ return getText(cert);
}
}
return ""; //$NON-NLS-1$
}
- private String userFriendlyFingerPrint(PGPPublicKey key) {
- if (key == null) {
- return null;
- }
- StringBuilder builder = new StringBuilder();
- boolean spaceSuffix = false;
- for (byte b : key.getFingerprint()) {
- builder.append(String.format("%02X", Byte.toUnsignedInt(b))); //$NON-NLS-1$
- if (spaceSuffix) {
- builder.append(' ');
- }
- spaceSuffix = !spaceSuffix;
- }
- builder.deleteCharAt(builder.length() - 1);
- return builder.toString();
- }
-
@Override
public void addListener(ILabelProviderListener listener) {
// do nothing
@@ -82,4 +62,23 @@ public class CertificateLabelProvider implements ILabelProvider {
// do nothing
}
+ /**
+ * Returns a string that can be used as readable label for a certificate. This
+ * hides the internal implementation classes needed to produce this label.
+ */
+ public static String getText(X509Certificate cert) {
+ X500PrincipalHelper principalHelper = new X500PrincipalHelper(cert.getSubjectX500Principal());
+ return principalHelper.getCN() + "; " + principalHelper.getOU() + "; " //$NON-NLS-1$ //$NON-NLS-2$
+ + principalHelper.getO();
+ }
+
+ /**
+ * Opens a dialog to present detailed information about a certificate. This
+ * hides the internal implementation classes needed open this dialog.
+ */
+ public static void openDialog(Shell shell, X509Certificate cert) {
+ // create and open dialog for certificate chain
+ X509CertificateViewDialog certificateViewDialog = new X509CertificateViewDialog(shell, cert);
+ certificateViewDialog.open();
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.updatechecker/pom.xml b/bundles/org.eclipse.equinox.p2.updatechecker/pom.xml
index da2f37456..49d08db7f 100644
--- a/bundles/org.eclipse.equinox.p2.updatechecker/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.updatechecker/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/pom.xml b/bundles/org.eclipse.equinox.p2.updatesite/pom.xml
index 6f21a2913..1f7c8c962 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.updatesite/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.simpleconfigurator.manipulator/pom.xml b/bundles/org.eclipse.equinox.simpleconfigurator.manipulator/pom.xml
index ee6dc888a..43581bbeb 100644
--- a/bundles/org.eclipse.equinox.simpleconfigurator.manipulator/pom.xml
+++ b/bundles/org.eclipse.equinox.simpleconfigurator.manipulator/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml b/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml
index 4f5b876cf..5a9a88217 100644
--- a/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml
+++ b/bundles/org.eclipse.equinox.simpleconfigurator/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/META-INF/MANIFEST.MF b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/META-INF/MANIFEST.MF
index 2e13bd54c..9dffe88be 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/META-INF/MANIFEST.MF
@@ -26,8 +26,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.6.0",
org.eclipse.equinox.p2.discovery;bundle-version="1.0.0",
org.eclipse.equinox.p2.discovery.compatibility;bundle-version="1.0.0",
org.eclipse.equinox.p2.ui.discovery;bundle-version="1.0.0",
- org.apache.httpcomponents.httpclient;bundle-version="4.2.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45;bundle-version="1.0.0"
+ org.apache.httpcomponents.client5.httpclient5;bundle-version="5.0.2",
+ org.eclipse.ecf.provider.filetransfer.httpclient5;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
Automatic-Module-Name: org.eclipse.equinox.p2.examples.rcp.cloud
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/cloud.product b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/cloud.product
index 0f39834a8..b7668e6ae 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/cloud.product
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/cloud.product
@@ -46,8 +46,8 @@
<plugin id="org.apache.commons.jxpath"/>
<plugin id="org.apache.commons.logging"/>
<plugin id="org.apache.felix.scr"/>
- <plugin id="org.apache.httpcomponents.httpclient"/>
- <plugin id="org.apache.httpcomponents.httpcore"/>
+ <plugin id="org.apache.httpcomponents.client5.httpclient5"/>
+ <plugin id="org.apache.httpcomponents.core5.httpcore5"/>
<plugin id="org.apache.xmlgraphics"/>
<plugin id="org.eclipse.core.commands"/>
<plugin id="org.eclipse.core.contenttype"/>
@@ -85,7 +85,7 @@
<plugin id="org.eclipse.ecf.provider.filetransfer"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.httpclient"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.httpclient.ssl" fragment="true"/>
- <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient45"/>
+ <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient5"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.ssl" fragment="true"/>
<plugin id="org.eclipse.ecf.ssl" fragment="true"/>
<plugin id="org.eclipse.emf.common"/>
@@ -126,7 +126,7 @@
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.security.ui"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
<plugin id="org.eclipse.equinox.simpleconfigurator.manipulator"/>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/plugin.xml b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/plugin.xml
index bff2bb0e7..ee5676d55 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/plugin.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/plugin.xml
@@ -178,7 +178,7 @@
<overview
screenshot="icons/mail-screenshot.png"
summary="In computing, the Post Office Protocol (POP) is an application-layer Internet standard protocol used by local e-mail clients to retrieve e-mail from a remote server over a TCP/IP connection. POP and IMAP (Internet Message Access Protocol) are the two most prevalent Internet standard protocols for e-mail retrieval. Virtually all modern e-mail clients and servers support both. The POP protocol has been developed through several versions, with version 3 (POP3) being the current standard."
- url="http://en.wikipedia.org/wiki/Post_Office_Protocol">
+ url="https://en.wikipedia.org/wiki/Post_Office_Protocol">
</overview>
<icon
image32="icons/mail.png">
@@ -197,11 +197,11 @@
license="EPL"
name="Eclipse Marketplace Client"
provider="Eclipse Packaging Project"
- siteUrl="http://download.eclipse.org/releases/staging">
+ siteUrl="https://download.eclipse.org/releases/staging">
<overview
screenshot="icons/mpc-screenshot.png"
summary="Marketplace Client is a rich client solution for installing solutions listed on Eclipse Marketplace directly from an Eclipse Installation.&#x0A;&#x0A;The Eclipse community has hundreds, if not thousands, of third-party plugins that users can add to their Eclipse installation. Unfortunately, there is not easy way to discover and install these solutions from within Eclipse.&#x0A;&#x0A;The Eclipse Foundation has recently launched a new website, called Eclipse Marketplace, that provides a listing of Eclipse-based solutions. The listings allow each solution provider to specify a P2 repository for their solution. Eclipse users now have a central catalog to find Eclipse solutions but the install process is still not tightly integrated with the Eclipse workspace.&#x0A;&#x0A;MPC provides the tight install integration between the Eclipse workspace and Eclipse Marketplace, plus other third party solution listings. MPC is included in many of the EPP packages."
- url="http://eclipse.org/mpc/"></overview>
+ url="https://eclipse.org/mpc/"></overview>
<icon
image32="icons/mpc.png">
</icon>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/pom.xml b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/pom.xml
index 563b6bbf0..a833132fc 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.discovery/pom.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.discovery/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/META-INF/MANIFEST.MF b/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/META-INF/MANIFEST.MF
index 5207540c5..724d0234c 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/META-INF/MANIFEST.MF
@@ -13,7 +13,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ecf.filetransfer;bundle-version="3.0.0",
org.eclipse.ecf.identity;bundle-version="3.0.0",
org.eclipse.ecf.provider.filetransfer;bundle-version="3.0.0",
- org.apache.httpcomponents.httpclient;bundle-version="4.2.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45;bundle-version="1.0.0"
+ org.apache.httpcomponents.client5.httpclient5;bundle-version="5.0.2",
+ org.eclipse.ecf.provider.filetransfer.httpclient5;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-11
Automatic-Module-Name: org.eclipse.equinox.p2.examples.rcp.prestartupdate
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/pom.xml b/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/pom.xml
index d686e45f7..9f13161d5 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/pom.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.prestartupdate/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.equinox.p2.examples.rcp.prestartupdate</artifactId>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/META-INF/MANIFEST.MF b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/META-INF/MANIFEST.MF
index bb82130a5..e2b034a24 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/META-INF/MANIFEST.MF
@@ -22,8 +22,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.6.0",
org.eclipse.ecf.filetransfer;bundle-version="3.0.0",
org.eclipse.ecf.identity;bundle-version="3.0.0",
org.eclipse.ecf.provider.filetransfer;bundle-version="3.0.0",
- org.apache.httpcomponents.httpclient;bundle-version="4.2.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45;bundle-version="1.0.0"
+ org.apache.httpcomponents.client5.httpclient5;bundle-version="5.0.2",
+ org.eclipse.ecf.provider.filetransfer.httpclient5;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
Service-Component: OSGI-INF/policy_component.xml
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/pom.xml b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/pom.xml
index 1a3bc6f1e..7bd7d3088 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/pom.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility</artifactId>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/sdkbundlevisibility.product b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/sdkbundlevisibility.product
index 730d77684..a1e4fc5dc 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/sdkbundlevisibility.product
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdkbundlevisibility/sdkbundlevisibility.product
@@ -46,8 +46,8 @@
<plugin id="org.apache.commons.jxpath"/>
<plugin id="org.apache.commons.logging"/>
<plugin id="org.apache.felix.scr"/>
- <plugin id="org.apache.httpcomponents.httpclient"/>
- <plugin id="org.apache.httpcomponents.httpcore"/>
+ <plugin id="org.apache.httpcomponents.client5.httpclient5"/>
+ <plugin id="org.apache.httpcomponents.core5.httpcore5"/>
<plugin id="org.apache.xmlgraphics"/>
<plugin id="org.eclipse.core.commands"/>
<plugin id="org.eclipse.core.contenttype"/>
@@ -83,7 +83,7 @@
<plugin id="org.eclipse.ecf.filetransfer"/>
<plugin id="org.eclipse.ecf.identity"/>
<plugin id="org.eclipse.ecf.provider.filetransfer"/>
- <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient45"/>
+ <plugin id="org.eclipse.ecf.provider.filetransfer.httpclient5"/>
<plugin id="org.eclipse.ecf.provider.filetransfer.ssl" fragment="true"/>
<plugin id="org.eclipse.ecf.ssl" fragment="true"/>
<plugin id="org.eclipse.emf.common"/>
@@ -119,7 +119,7 @@
<plugin id="org.eclipse.equinox.preferences"/>
<plugin id="org.eclipse.equinox.registry"/>
<plugin id="org.eclipse.equinox.security"/>
- <plugin id="org.eclipse.equinox.security.linux.x86_64" fragment="true"/>
+ <plugin id="org.eclipse.equinox.security.linux" fragment="true"/>
<plugin id="org.eclipse.equinox.security.macosx" fragment="true"/>
<plugin id="org.eclipse.equinox.security.ui"/>
<plugin id="org.eclipse.equinox.simpleconfigurator"/>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/META-INF/MANIFEST.MF b/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/META-INF/MANIFEST.MF
index 0ef9f7e8b..297dee540 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/META-INF/MANIFEST.MF
@@ -19,8 +19,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ecf.filetransfer;bundle-version="3.0.0",
org.eclipse.ecf.identity;bundle-version="3.0.0",
org.eclipse.ecf.provider.filetransfer;bundle-version="3.0.0",
- org.apache.httpcomponents.httpclient;bundle-version="4.2.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45;bundle-version="1.0.0",
+ org.apache.httpcomponents.client5.httpclient5;bundle-version="5.0.2",
+ org.eclipse.ecf.provider.filetransfer.httpclient5;bundle-version="1.0.0",
org.eclipse.equinox.p2.ui.sdk;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/pom.xml b/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/pom.xml
index 588aa759e..024bb1e41 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/pom.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdknoautoupdates/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/META-INF/MANIFEST.MF b/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/META-INF/MANIFEST.MF
index 8c0d5cd5b..417b58720 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/META-INF/MANIFEST.MF
@@ -21,8 +21,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ecf.provider.filetransfer;bundle-version="3.0.0",
org.eclipse.equinox.p2.ui.sdk;bundle-version="1.0.0",
org.eclipse.equinox.p2.ui.sdk.scheduler;bundle-version="1.0.0",
- org.apache.httpcomponents.httpclient;bundle-version="4.2.0",
- org.eclipse.ecf.provider.filetransfer.httpclient45;bundle-version="1.0.0"
+ org.apache.httpcomponents.client5.httpclient5;bundle-version="5.0.2",
+ org.eclipse.ecf.provider.filetransfer.httpclient5;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
Automatic-Module-Name: org.eclipse.equinox.p2.examples.rcp.sdkui
diff --git a/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/pom.xml b/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/pom.xml
index e6352ad05..409e36705 100644
--- a/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/pom.xml
+++ b/examples/org.eclipse.equinox.p2.examples.rcp.sdkui/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
diff --git a/examples/pom.xml b/examples/pom.xml
index 4e10490f9..10e519663 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -4,7 +4,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.equinox.p2.examples</artifactId>
diff --git a/features/org.eclipse.equinox.p2.core.feature/feature.xml b/features/org.eclipse.equinox.p2.core.feature/feature.xml
index f8cffb089..4b7c6ff2b 100644
--- a/features/org.eclipse.equinox.p2.core.feature/feature.xml
+++ b/features/org.eclipse.equinox.p2.core.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.core.feature"
label="%featureName"
- version="1.6.1300.qualifier"
+ version="1.6.1400.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
@@ -23,7 +23,7 @@
<import feature="org.eclipse.ecf.core.feature" version="1.4.0" match="compatible"/>
<import feature="org.eclipse.ecf.core.ssl.feature" version="1.1.0" match="compatible"/>
<import feature="org.eclipse.ecf.filetransfer.feature" version="3.13.7" match="compatible"/>
- <import feature="org.eclipse.ecf.filetransfer.httpclient45.feature" version="1.0.0" match="compatible"/>
+ <import feature="org.eclipse.ecf.filetransfer.httpclient5.feature" version="1.0.0" match="compatible"/>
<import feature="org.eclipse.ecf.filetransfer.ssl.feature" version="1.1.0" match="compatible"/>
</requires>
@@ -184,7 +184,7 @@
unpack="false"/>
<plugin
- id="org.eclipse.equinox.security.linux.x86_64"
+ id="org.eclipse.equinox.security.linux"
os="linux"
arch="x86_64"
download-size="0"
diff --git a/features/org.eclipse.equinox.p2.core.feature/forceQualifierUpdate.txt b/features/org.eclipse.equinox.p2.core.feature/forceQualifierUpdate.txt
index 69401c095..55820793c 100644
--- a/features/org.eclipse.equinox.p2.core.feature/forceQualifierUpdate.txt
+++ b/features/org.eclipse.equinox.p2.core.feature/forceQualifierUpdate.txt
@@ -22,4 +22,5 @@ Bug 553238 - Unanticipated comparator errors in I20191119-1800
Bug 477007 - Do not use whitespace in XML
Bug 574602 - Eclipse 4.21 prerequisites: Orbit
Bug 574602 - Eclipse 4.21 prerequisites: Orbit
-Bug 576389 - Touch bundle for org.bouncycastle.bcprov version update \ No newline at end of file
+Bug 576389 - Touch bundle for org.bouncycastle.bcprov version update
+Bug 578120 - Update to latest Orbit - bouncycastle and mina sshd updates \ No newline at end of file
diff --git a/features/org.eclipse.equinox.p2.core.feature/pom.xml b/features/org.eclipse.equinox.p2.core.feature/pom.xml
index 1420cd178..ebb4950cb 100644
--- a/features/org.eclipse.equinox.p2.core.feature/pom.xml
+++ b/features/org.eclipse.equinox.p2.core.feature/pom.xml
@@ -15,12 +15,12 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.core.feature</artifactId>
- <version>1.6.1300-SNAPSHOT</version>
+ <version>1.6.1400-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
diff --git a/features/org.eclipse.equinox.p2.discovery.feature/feature.xml b/features/org.eclipse.equinox.p2.discovery.feature/feature.xml
index 5a831e43e..49c7f0d02 100644
--- a/features/org.eclipse.equinox.p2.discovery.feature/feature.xml
+++ b/features/org.eclipse.equinox.p2.discovery.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.discovery.feature"
label="%featureName"
- version="1.2.1000.qualifier"
+ version="1.2.1100.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
diff --git a/features/org.eclipse.equinox.p2.discovery.feature/pom.xml b/features/org.eclipse.equinox.p2.discovery.feature/pom.xml
index 0a7060712..f63571e19 100644
--- a/features/org.eclipse.equinox.p2.discovery.feature/pom.xml
+++ b/features/org.eclipse.equinox.p2.discovery.feature/pom.xml
@@ -14,12 +14,12 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.discovery.feature</artifactId>
- <version>1.2.1000-SNAPSHOT</version>
+ <version>1.2.1100-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
diff --git a/features/org.eclipse.equinox.p2.extras.feature/feature.xml b/features/org.eclipse.equinox.p2.extras.feature/feature.xml
index ac67f7b30..8989b7e84 100644
--- a/features/org.eclipse.equinox.p2.extras.feature/feature.xml
+++ b/features/org.eclipse.equinox.p2.extras.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.extras.feature"
label="%featureName"
- version="1.4.1500.qualifier"
+ version="1.4.1600.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
diff --git a/features/org.eclipse.equinox.p2.extras.feature/pom.xml b/features/org.eclipse.equinox.p2.extras.feature/pom.xml
index 200e682ad..97e83185a 100644
--- a/features/org.eclipse.equinox.p2.extras.feature/pom.xml
+++ b/features/org.eclipse.equinox.p2.extras.feature/pom.xml
@@ -14,12 +14,12 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.extras.feature</artifactId>
- <version>1.4.1500-SNAPSHOT</version>
+ <version>1.4.1600-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
diff --git a/features/org.eclipse.equinox.p2.rcp.feature/feature.xml b/features/org.eclipse.equinox.p2.rcp.feature/feature.xml
index f07c42fa7..1fc40357a 100644
--- a/features/org.eclipse.equinox.p2.rcp.feature/feature.xml
+++ b/features/org.eclipse.equinox.p2.rcp.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.rcp.feature"
label="%featureName"
- version="1.4.1500.qualifier"
+ version="1.4.1600.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
diff --git a/features/org.eclipse.equinox.p2.rcp.feature/pom.xml b/features/org.eclipse.equinox.p2.rcp.feature/pom.xml
index 7abade620..c25b7dafe 100644
--- a/features/org.eclipse.equinox.p2.rcp.feature/pom.xml
+++ b/features/org.eclipse.equinox.p2.rcp.feature/pom.xml
@@ -14,13 +14,13 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.rcp.feature</artifactId>
- <version>1.4.1500-SNAPSHOT</version>
+ <version>1.4.1600-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
diff --git a/features/org.eclipse.equinox.p2.sdk/feature.xml b/features/org.eclipse.equinox.p2.sdk/feature.xml
index 3f87a10f4..837fb5ea1 100644
--- a/features/org.eclipse.equinox.p2.sdk/feature.xml
+++ b/features/org.eclipse.equinox.p2.sdk/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.sdk"
label="%featureName"
- version="3.11.1500.qualifier"
+ version="3.11.1600.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
@@ -31,7 +31,7 @@
<import feature="org.eclipse.ecf.core.feature.source" version="1.4.0" match="compatible"/>
<import feature="org.eclipse.ecf.core.ssl.feature.source" version="1.1.0" match="compatible"/>
<import feature="org.eclipse.ecf.filetransfer.feature.source" version="3.13.7" match="compatible"/>
- <import feature="org.eclipse.ecf.filetransfer.httpclient45.feature.source" version="1.0.0" match="compatible"/>
+ <import feature="org.eclipse.ecf.filetransfer.httpclient5.feature.source" version="1.0.0" match="compatible"/>
<import feature="org.eclipse.ecf.filetransfer.ssl.feature.source" version="1.1.0" match="compatible"/>
</requires>
diff --git a/features/org.eclipse.equinox.p2.sdk/pom.xml b/features/org.eclipse.equinox.p2.sdk/pom.xml
index ce34c2cd4..6e36baf37 100644
--- a/features/org.eclipse.equinox.p2.sdk/pom.xml
+++ b/features/org.eclipse.equinox.p2.sdk/pom.xml
@@ -15,11 +15,11 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.sdk</artifactId>
- <version>3.11.1500-SNAPSHOT</version>
+ <version>3.11.1600-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
</project>
diff --git a/features/org.eclipse.equinox.p2.user.ui/feature.xml b/features/org.eclipse.equinox.p2.user.ui/feature.xml
index 415f30d94..8e7849ace 100644
--- a/features/org.eclipse.equinox.p2.user.ui/feature.xml
+++ b/features/org.eclipse.equinox.p2.user.ui/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.equinox.p2.user.ui"
label="%featureName"
- version="2.4.1500.qualifier"
+ version="2.4.1600.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
diff --git a/features/org.eclipse.equinox.p2.user.ui/pom.xml b/features/org.eclipse.equinox.p2.user.ui/pom.xml
index 7840daa87..e05ba4722 100644
--- a/features/org.eclipse.equinox.p2.user.ui/pom.xml
+++ b/features/org.eclipse.equinox.p2.user.ui/pom.xml
@@ -14,13 +14,13 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.user.ui</artifactId>
- <version>2.4.1500-SNAPSHOT</version>
+ <version>2.4.1600-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
diff --git a/org.eclipse.equinox.p2.releng/default.target b/org.eclipse.equinox.p2.releng/default.target
index d3e8fe8bc..5139a8a19 100644
--- a/org.eclipse.equinox.p2.releng/default.target
+++ b/org.eclipse.equinox.p2.releng/default.target
@@ -6,7 +6,7 @@
<unit id="org.eclipse.platform.sdk" version="0.0.0"/>
<unit id="org.eclipse.core.tests.harness" version="0.0.0"/>
<unit id="org.eclipse.test.feature.group" version="0.0.0"/>
-<repository location="https://download.eclipse.org/eclipse/updates/4.23-I-builds"/>
+<repository location="https://download.eclipse.org/eclipse/updates/4.24-I-builds"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.bouncycastle.bcprov" version="0.0.0"/>
diff --git a/org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent/pom.xml b/org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent/pom.xml
index f0b5aaf3c..d2d0472a3 100644
--- a/org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent/pom.xml
+++ b/org.eclipse.equinox.p2.releng/org.eclipse.equinox.p2.tests-parent/pom.xml
@@ -14,7 +14,7 @@
<parent>
<groupId>org.eclipse.equinox.p2</groupId>
<artifactId>rt.equinox.p2</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<groupId>org.eclipse</groupId>
diff --git a/pom.xml b/pom.xml
index 260585a37..46880ac6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,7 @@
<parent>
<groupId>org.eclipse</groupId>
<artifactId>eclipse-platform-parent</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../eclipse-platform-parent</relativePath>
</parent>

Back to the top