Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Reckord2014-04-03 10:31:19 +0000
committerCarsten Reckord2014-04-16 10:18:14 +0000
commit3a32f6c8b907a77a778ce90c507c28b7a514f5c7 (patch)
tree888d8e31e021c10f81d993a52ff842a0168e239d
parent1cfe332fd8b1e74f24f99520d0b39d34e81a4c26 (diff)
downloadorg.eclipse.epp.mpc-3a32f6c8b907a77a778ce90c507c28b7a514f5c7.tar.gz
org.eclipse.epp.mpc-3a32f6c8b907a77a778ce90c507c28b7a514f5c7.tar.xz
org.eclipse.epp.mpc-3a32f6c8b907a77a778ce90c507c28b7a514f5c7.zip
432803: Public API for the Marketplace Client
- extracted core API data model - extracted core API services as OSGi services - defined UI API services and extracted relevant UI models to public API - additional SWTBot tests for UI services Bug: 432803 Change-Id: Ie4fedd26c24b6cee06572781ca44ceea72984a91 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=432803
-rw-r--r--org.eclipse.epp.mpc-target/kepler.target9
-rw-r--r--org.eclipse.epp.mpc-target/luna.target9
-rw-r--r--org.eclipse.epp.mpc-target/maintenance.target9
-rw-r--r--org.eclipse.epp.mpc-target/staging.target9
-rw-r--r--org.eclipse.epp.mpc.core/.project5
-rw-r--r--org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF10
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml17
-rw-r--r--org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml17
-rw-r--r--org.eclipse.epp.mpc.core/build.properties15
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java62
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java74
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java244
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java76
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalog.java12
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogBranding.java11
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogService.java8
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalogs.java7
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Categories.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Category.java25
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultCatalogService.java27
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java257
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Identifiable.java85
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Ius.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Market.java22
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceService.java3
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java78
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/News.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Node.java11
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/NotFoundException.java3
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Platforms.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/RemoteMarketplaceService.java93
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/SearchResult.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/ServiceUnavailableException.java8
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tag.java10
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tags.java5
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ITransport.java14
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/Messages.java2
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java93
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java73
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/messages.properties3
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalog.java69
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogBranding.java41
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogs.java28
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategories.java28
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategory.java44
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIdentifiable.java68
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIus.java28
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IMarket.java31
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INews.java40
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INode.java157
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IPlatforms.java24
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ISearchResult.java41
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITag.java24
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITags.java29
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ICatalogService.java35
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java163
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceServiceLocator.java84
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceUnmarshaller.java38
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransport.java29
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransportFactory.java25
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/QueryHelper.java109
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java50
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceUnavailableException.java29
-rw-r--r--org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/UnmarshalException.java28
-rw-r--r--org.eclipse.epp.mpc.tests/META-INF/MANIFEST.MF9
-rw-r--r--org.eclipse.epp.mpc.tests/pom.xml1
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/AllTests.java22
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/BotTests.java27
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UISuite.java52
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UITests.java43
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/CatalogServiceTest.java62
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/DefaultMarketplaceServiceTest.java56
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/ServiceLocatorTest.java45
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/xml/UnmarshallerTest.java76
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/MarketplaceClientUiTest.java8
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/CatalogDescriptorTest.java6
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceCatalogTest.java19
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceInfoTest.java6
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceClientServiceTest.java289
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceDiscoveryStrategyTest.java22
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceUrlHandlerTest.java19
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/SelectionModelStateSerializerTest.java20
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/matcher/NodeMatcher.java135
-rw-r--r--org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java50
-rw-r--r--org.eclipse.epp.mpc.ui/.project5
-rw-r--r--org.eclipse.epp.mpc.ui/.settings/.api_filters21
-rw-r--r--org.eclipse.epp.mpc.ui/META-INF/MANIFEST.MF7
-rw-r--r--org.eclipse.epp.mpc.ui/OSGI-INF/services/marketplace-client.xml7
-rw-r--r--org.eclipse.epp.mpc.ui/build.properties2
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/CatalogRegistry.java34
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUi.java17
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUiPlugin.java16
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/AbstractResourceRunnable.java4
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalog.java26
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalogSource.java9
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCategory.java13
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java211
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceInfo.java14
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceNodeCatalogItem.java36
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java10
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties5
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/commands/MarketplaceWizardCommand.java95
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/Messages.java2
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/ProfileChangeOperationComputer.java28
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/messages.properties1
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/BrowseCatalogItem.java10
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/DiscoveryItem.java54
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/FeatureSelectionWizardPage.java7
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/IDiscoveryItemFactory.java21
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ItemButtonController.java10
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceBrowserIntegration.java6
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceCatalogConfiguration.java53
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceClientService.java112
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceDropAdapter.java4
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplacePage.java108
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceUrlHandler.java377
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceViewer.java123
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java271
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Messages.java6
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsUrlHandler.java27
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsViewer.java9
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Operation.java90
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java61
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModel.java75
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModelStateSerializer.java48
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ShareSolutionLink.java5
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/messages.properties3
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/CatalogDescriptor.java46
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientConfiguration.java79
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientService.java108
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceClient.java33
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceUrlHandler.java441
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Messages.java34
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Operation.java33
-rw-r--r--org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/messages.properties15
135 files changed, 5238 insertions, 1234 deletions
diff --git a/org.eclipse.epp.mpc-target/kepler.target b/org.eclipse.epp.mpc-target/kepler.target
index 9faaf50c..016108dc 100644
--- a/org.eclipse.epp.mpc-target/kepler.target
+++ b/org.eclipse.epp.mpc-target/kepler.target
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
-<target name="Kepler" sequenceNumber="10">
+<target name="MPC Target Platform - Kepler" sequenceNumber="10">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.platform.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.rcp.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/releases/kepler"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.license.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/cbi/updates/license"/>
</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.generator.feature.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="0.0.0"/>
+<repository location="http://download.eclipse.org/technology/swtbot/releases/latest"/>
+</location>
</locations>
</target>
diff --git a/org.eclipse.epp.mpc-target/luna.target b/org.eclipse.epp.mpc-target/luna.target
index c0ef1087..dfa45803 100644
--- a/org.eclipse.epp.mpc-target/luna.target
+++ b/org.eclipse.epp.mpc-target/luna.target
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
-<target name="luna" sequenceNumber="0">
+<target name="MPC Target Platform - Luna" sequenceNumber="1">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.platform.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.rcp.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/releases/luna"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.license.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/cbi/updates/license"/>
</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.generator.feature.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="0.0.0"/>
+<repository location="http://download.eclipse.org/technology/swtbot/releases/latest"/>
+</location>
</locations>
</target>
diff --git a/org.eclipse.epp.mpc-target/maintenance.target b/org.eclipse.epp.mpc-target/maintenance.target
index ba8fe6c1..03a917a9 100644
--- a/org.eclipse.epp.mpc-target/maintenance.target
+++ b/org.eclipse.epp.mpc-target/maintenance.target
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
-<target name="Maintenance" sequenceNumber="10">
+<target name="MPC Target Platform - Maintenance" sequenceNumber="10">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.platform.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.rcp.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/releases/maintenance"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.license.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/cbi/updates/license"/>
</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.generator.feature.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="0.0.0"/>
+<repository location="http://download.eclipse.org/technology/swtbot/releases/latest"/>
+</location>
</locations>
</target>
diff --git a/org.eclipse.epp.mpc-target/staging.target b/org.eclipse.epp.mpc-target/staging.target
index 1c57d109..23b598a9 100644
--- a/org.eclipse.epp.mpc-target/staging.target
+++ b/org.eclipse.epp.mpc-target/staging.target
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
-<target name="Staging" sequenceNumber="0">
+<target name="MPC Target Platform - Staging" sequenceNumber="0">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.equinox.sdk.feature.group" version="0.0.0"/>
<unit id="org.eclipse.equinox.p2.discovery.feature.feature.group" version="0.0.0"/>
<unit id="org.eclipse.sdk.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.platform.feature.group" version="0.0.0"/>
-<unit id="org.eclipse.rcp.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/releases/staging"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.license.feature.group" version="0.0.0"/>
<repository location="http://download.eclipse.org/cbi/updates/license"/>
</location>
+<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.generator.feature.feature.group" version="0.0.0"/>
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="0.0.0"/>
+<repository location="http://download.eclipse.org/technology/swtbot/releases/latest"/>
+</location>
</locations>
</target>
diff --git a/org.eclipse.epp.mpc.core/.project b/org.eclipse.epp.mpc.core/.project
index 59bf97d2..be79398e 100644
--- a/org.eclipse.epp.mpc.core/.project
+++ b/org.eclipse.epp.mpc.core/.project
@@ -25,6 +25,11 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
diff --git a/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF b/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
index e1638eea..435dfdc5 100644
--- a/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.epp.mpc.core/META-INF/MANIFEST.MF
@@ -9,11 +9,16 @@ Require-Bundle: org.eclipse.osgi;bundle-version="3.6.0",
org.eclipse.core.runtime;bundle-version="3.6.0",
org.apache.commons.logging;bundle-version="1.0.4",
org.eclipse.equinox.p2.repository;bundle-version="2.0.0",
- org.eclipse.core.net;bundle-version="1.2.100"
+ org.eclipse.core.net;bundle-version="1.2.100",
+ org.eclipse.equinox.ds;bundle-version="1.4.200",
+ org.eclipse.osgi.services;bundle-version="3.4.0",
+ org.eclipse.equinox.util;bundle-version="1.0.500"
Export-Package: org.eclipse.epp.internal.mpc.core;x-friends:="org.eclipse.epp.mpc.ui",
org.eclipse.epp.internal.mpc.core.service;x-friends:="org.eclipse.epp.mpc.ui",
org.eclipse.epp.internal.mpc.core.service.xml;x-internal:=true,
- org.eclipse.epp.internal.mpc.core.util;x-friends:="org.eclipse.epp.mpc.ui"
+ org.eclipse.epp.internal.mpc.core.util;x-friends:="org.eclipse.epp.mpc.ui",
+ org.eclipse.epp.mpc.core.model,
+ org.eclipse.epp.mpc.core.service
Import-Package: org.apache.http;version="4.1.0",
org.apache.http.auth;version="4.1.0",
org.apache.http.client;version="4.1.0",
@@ -27,3 +32,4 @@ Import-Package: org.apache.http;version="4.1.0",
org.eclipse.equinox.p2.core;version="2.0.0"
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin
+Service-Component: OSGI-INF/services/*.xml
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml
new file mode 100644
index 00000000..5510b761
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/service-locator.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 The Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ The Eclipse Foundation - initial API and implementation
+ -->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.servicelocator">
+ <implementation class="org.eclipse.epp.internal.mpc.core.ServiceLocator"/>
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator"/>
+ </service>
+</scr:component>
diff --git a/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml b/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml
new file mode 100644
index 00000000..afe06578
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/OSGI-INF/services/unmarshaller.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 The Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ The Eclipse Foundation - initial API and implementation
+ -->
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.core.unmarshaller">
+ <implementation class="org.eclipse.epp.internal.mpc.core.service.MarketplaceUnmarshaller"/>
+ <service>
+ <provide interface="org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller"/>
+ </service>
+</scr:component>
diff --git a/org.eclipse.epp.mpc.core/build.properties b/org.eclipse.epp.mpc.core/build.properties
index ef479b0c..1c6dd1ff 100644
--- a/org.eclipse.epp.mpc.core/build.properties
+++ b/org.eclipse.epp.mpc.core/build.properties
@@ -1,18 +1,9 @@
-###############################################################################
-# Copyright (c) 2010 The Eclipse Foundation and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-# The Eclipse Foundation - initial API and implementation
-###############################################################################
-source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
OSGI-INF/,\
- OSGI-INF/l10n/
+ OSGI-INF/l10n/,\
+ OSGI-INF/services/
src.includes = about.html
+source.. = src/
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
index 30e91b5f..154527c9 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/MarketplaceClientCorePlugin.java
@@ -7,29 +7,85 @@
*
* Contributors:
* Yatta Solutions - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
import org.eclipse.epp.internal.mpc.core.util.ProxyHelper;
+import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
+import org.eclipse.epp.mpc.core.service.ITransportFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
public class MarketplaceClientCorePlugin implements BundleActivator {
- private static Bundle bundle;
+ private static MarketplaceClientCorePlugin instance;
+
+ private Bundle bundle;
+
+ private List<ServiceRegistration<?>> serviceRegistrations;
+
+ private ServiceHelperImpl serviceHelper;
public void start(BundleContext context) throws Exception {
bundle = context.getBundle();
+ instance = this;
ProxyHelper.acquireProxyService();
+ registerServices(context);
+ serviceHelper = new ServiceHelperImpl();
+ serviceHelper.startTracking(context);
}
public void stop(BundleContext context) throws Exception {
+ serviceHelper.stopTracking(context);
+ serviceHelper = null;
+ unregisterServices();
ProxyHelper.releaseProxyService();
- bundle = null;
+ instance = null;
+ }
+
+ private void registerServices(BundleContext context) {
+ List<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>();
+ this.serviceRegistrations = serviceRegistrations;
+
+ List<ITransportFactory> factories = TransportFactory.listAvailableFactories();//highest-prio factory comes first
+ int prio = 100 * factories.size();//prio counts down from highest value to 0 in steps of 100
+ for (ITransportFactory factory : factories) {
+ prio -= 100;
+ Hashtable<String, Object> properties = new Hashtable<String, Object>();
+ properties.put(Constants.SERVICE_RANKING, prio);
+ ServiceRegistration<ITransportFactory> registration = context.registerService(ITransportFactory.class,
+ factory, properties);
+ serviceRegistrations.add(registration);
+ }
+ }
+
+ private void unregisterServices() {
+ List<ServiceRegistration<?>> serviceRegistrations = this.serviceRegistrations;
+ this.serviceRegistrations = null;
+ if (serviceRegistrations != null) {
+ for (ServiceRegistration<?> serviceRegistration : serviceRegistrations) {
+ serviceRegistration.unregister();
+ }
+ }
+ }
+
+ public ServiceHelperImpl getServiceHelper() {
+ return serviceHelper;
+ }
+
+ public static MarketplaceClientCorePlugin getDefault() {
+ return instance;
}
public static Bundle getBundle() {
- return bundle;
+ return instance == null ? null : instance.bundle;
}
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java
new file mode 100644
index 00000000..6397300d
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceHelperImpl.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core;
+
+import org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator;
+import org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller;
+import org.eclipse.epp.mpc.core.service.ITransportFactory;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * @author Carsten Reckord
+ */
+class ServiceHelperImpl extends ServiceHelper {
+
+ private ServiceTracker<IMarketplaceServiceLocator, IMarketplaceServiceLocator> locatorServiceTracker;
+
+ private ServiceTracker<ITransportFactory, ITransportFactory> transportFactoryTracker;
+
+ private ServiceTracker<IMarketplaceUnmarshaller, IMarketplaceUnmarshaller> unmarshallerTracker;
+
+ void startTracking(BundleContext context) {
+ locatorServiceTracker = new ServiceTracker<IMarketplaceServiceLocator, IMarketplaceServiceLocator>(context,
+ IMarketplaceServiceLocator.class, null);
+ locatorServiceTracker.open(true);
+
+ transportFactoryTracker = new ServiceTracker<ITransportFactory, ITransportFactory>(context,
+ ITransportFactory.class, null);
+ transportFactoryTracker.open(true);
+
+ unmarshallerTracker = new ServiceTracker<IMarketplaceUnmarshaller, IMarketplaceUnmarshaller>(context,
+ IMarketplaceUnmarshaller.class, null);
+ unmarshallerTracker.open(true);
+ }
+
+ void stopTracking(BundleContext context) {
+ if (locatorServiceTracker != null) {
+ locatorServiceTracker.close();
+ locatorServiceTracker = null;
+ }
+ if (transportFactoryTracker != null) {
+ transportFactoryTracker.close();
+ transportFactoryTracker = null;
+ }
+ if (unmarshallerTracker != null) {
+ unmarshallerTracker.close();
+ unmarshallerTracker = null;
+ }
+ }
+
+ @Override
+ protected IMarketplaceServiceLocator doGetMarketplaceServiceLocator() {
+ return locatorServiceTracker == null ? null : locatorServiceTracker.getService();
+ }
+
+ @Override
+ protected IMarketplaceUnmarshaller doGetMarketplaceUnmarshaller() {
+ return unmarshallerTracker == null ? null : unmarshallerTracker.getService();
+ }
+
+ @Override
+ protected ITransportFactory doGetTransportFactory() {
+ return transportFactoryTracker == null ? null : transportFactoryTracker.getService();
+ }
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
index 615fb013..89781a84 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/ServiceLocator.java
@@ -7,43 +7,261 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core;
-import org.eclipse.epp.internal.mpc.core.service.CatalogService;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.epp.internal.mpc.core.service.CachingMarketplaceService;
import org.eclipse.epp.internal.mpc.core.service.DefaultCatalogService;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.MarketplaceService;
+import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
/**
- * A service locator for obtaining {@link MarketplaceService} instances.
- *
+ * A service locator for obtaining {@link IMarketplaceService} instances.
+ *
* @author David Green
+ * @author Carsten Reckord
*/
-public class ServiceLocator {
+public class ServiceLocator implements IMarketplaceServiceLocator {
+
+ private static ServiceLocator instance;
+
+ private Map<String, IMarketplaceService> marketplaceServices;
+
+ private ICatalogService catalogService;
+
+ private ServiceTracker<IMarketplaceService, IMarketplaceService> marketplaceServiceTracker;
+
+ private ServiceTracker<ICatalogService, ICatalogService> catalogServiceTracker;
+
+ private URL defaultCatalogUrl;
- private static ServiceLocator instance = new ServiceLocator();
+ private URL defaultMarketplaceUrl;
- public MarketplaceService getMarketplaceService() {
- return new DefaultMarketplaceService();
+ public ServiceLocator() {
+ defaultMarketplaceUrl = DefaultMarketplaceService.DEFAULT_SERVICE_URL;
+ defaultCatalogUrl = DefaultCatalogService.DEFAULT_CATALOG_SERVICE_URL;
}
- public CatalogService getCatalogService() {
- return new DefaultCatalogService();
+ /**
+ * @deprecated use {@link #getDefaultMarketplaceService()} or {@link #getMarketplaceService(String)} instead
+ */
+ @Deprecated
+ public IMarketplaceService getMarketplaceService() {
+ return getDefaultMarketplaceService();
+ }
+
+ public IMarketplaceService getDefaultMarketplaceService() {
+ return getMarketplaceService(defaultMarketplaceUrl.toExternalForm());
+ }
+
+ public synchronized IMarketplaceService getMarketplaceService(String baseUrl) {
+ IMarketplaceService service;
+ if (marketplaceServiceTracker != null) {
+ ServiceReference<IMarketplaceService>[] serviceReferences = marketplaceServiceTracker.getServiceReferences();
+ if (serviceReferences != null) {
+ for (ServiceReference<IMarketplaceService> serviceReference : serviceReferences) {
+ Object serviceBaseUrl = serviceReference.getProperty(IMarketplaceService.BASE_URL);
+ if (baseUrl.equals(serviceBaseUrl)) {
+ service = marketplaceServiceTracker.getService(serviceReference);
+ //we don't cache this on our own, since it might become invalid
+ if (service != null) {
+ return service;
+ }
+ }
+ }
+ }
+ }
+ if (marketplaceServices != null) {
+ service = marketplaceServices.get(baseUrl);
+ if (service != null) {
+ return service;
+ }
+ }
+ service = createMarketplaceService(baseUrl);
+
+ if (marketplaceServices != null) {
+ marketplaceServices.put(baseUrl, service);
+ }
+ return service;
+ }
+
+ protected IMarketplaceService createMarketplaceService(String baseUrl) {
+ IMarketplaceService service;
+ URL base;
+ try {
+ base = new URL(baseUrl);
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException(e);
+ }
+ DefaultMarketplaceService defaultService = new DefaultMarketplaceService(base);
+ Map<String, String> requestMetaParameters = computeDefaultRequestMetaParameters();
+ defaultService.setRequestMetaParameters(requestMetaParameters);
+ service = new CachingMarketplaceService(defaultService);
+ return service;
+ }
+
+ /**
+ * OSGi service activation method. Activation will cause the locator to start managing individual marketplace
+ * services and return the same instances per base url on subsequent calls to {@link #getMarketplaceService(String)}
+ * .
+ */
+ public synchronized void activate(BundleContext context, Map<?, ?> properties) {
+ URL baseUrl = ServiceUtil.getUrl(properties, DEFAULT_URL, null);
+
+ URL catalogUrl = ServiceUtil.getUrl(properties, CATALOG_URL, baseUrl);
+ if (catalogUrl != null) {
+ this.defaultCatalogUrl = catalogUrl;
+ } //else the default value from the constructor is used
+
+ URL marketplaceUrl = ServiceUtil.getUrl(properties, DEFAULT_MARKETPLACE_URL, baseUrl);
+ if (marketplaceUrl != null) {
+ this.defaultMarketplaceUrl = marketplaceUrl;
+ } //else the default value from the constructor is used
+
+ if (marketplaceServices == null) {
+ marketplaceServices = new HashMap<String, IMarketplaceService>();
+ }
+
+ marketplaceServiceTracker = new ServiceTracker<IMarketplaceService, IMarketplaceService>(context,
+ IMarketplaceService.class, null);
+ marketplaceServiceTracker.open(true);
+
+ catalogServiceTracker = new ServiceTracker<ICatalogService, ICatalogService>(context,
+ ICatalogService.class, null);
+ catalogServiceTracker.open(true);
+ }
+
+ /**
+ * OSGi service activation method. Deactivation will cause the locator to stop managing individual marketplace
+ * services. Multiple calls to {@link #getMarketplaceService(String)} will return a new instance every time.
+ */
+ public synchronized void deactivate() {
+ if (marketplaceServiceTracker != null) {
+ marketplaceServiceTracker.close();
+ marketplaceServiceTracker = null;
+ }
+ if (catalogServiceTracker != null) {
+ catalogServiceTracker.close();
+ catalogServiceTracker = null;
+ }
+ marketplaceServices = null;
+ catalogService = null;
+ }
+
+ public synchronized ICatalogService getCatalogService() {
+ if (catalogServiceTracker != null) {
+ ICatalogService registeredService = catalogServiceTracker.getService();
+ if (registeredService != null) {
+ //we don't cache this on our own, since it might become invalid
+ return registeredService;
+ }
+ }
+ if (catalogService != null) {
+ return catalogService;
+ }
+ ICatalogService catalogService = new DefaultCatalogService(defaultCatalogUrl);
+ if (marketplaceServices != null) {//used as an indicator to cache value
+ this.catalogService = catalogService;
+ }
+ return catalogService;
}
/**
* for testing purposes
+ *
+ * @deprecated don't call this outside of tests
*/
+ @Deprecated
public static synchronized void setInstance(ServiceLocator instance) {
- if (instance == null) {
- throw new IllegalArgumentException();
- }
ServiceLocator.instance = instance;
}
+ /**
+ * @deprecated acquire the registered {@link IMarketplaceServiceLocator} OSGi service instead.
+ */
+ @Deprecated
public static synchronized ServiceLocator getInstance() {
+ if (instance != null) {
+ return instance;
+ }
+ IMarketplaceServiceLocator locator = getCompatibilityLocator();
+ if (locator != null) {
+ if (locator instanceof ServiceLocator) {
+ //don't remember service instance, it might get deregistered
+ return (ServiceLocator) locator;
+ }
+ }
+ //remember new default instance
+ instance = new ServiceLocator();
return instance;
}
+ /**
+ * This method is not intended to be referenced by clients. Acquire the registered
+ * {@link IMarketplaceServiceLocator} OSGi service instead.
+ * <p>
+ * This method provides legacy compatibility with the ServiceLocator singleton for internal use only. It will return
+ * the ServiceLocator singleton if it has been set explicitly. Otherwise it will return the registered default
+ * {@link IMarketplaceServiceLocator} OSGi service.
+ *
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public static synchronized IMarketplaceServiceLocator getCompatibilityLocator() {
+ if (instance != null) {
+ return instance;
+ }
+ IMarketplaceServiceLocator locator = ServiceHelper.getMarketplaceServiceLocator();
+ if (locator == null) {
+ //remember new default instance
+ instance = new ServiceLocator();
+ locator = instance;
+ }
+ return locator;
+ }
+
+ public static Map<String, String> computeDefaultRequestMetaParameters() {
+ Map<String, String> requestMetaParameters = new HashMap<String, String>();
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_CLIENT, MarketplaceClientCore.BUNDLE_ID);
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_OS, Platform.getOS());
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_WS, Platform.getWS());
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_NL, Platform.getNL());
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_JAVA_VERSION, System.getProperty("java.version")); //$NON-NLS-1$
+ IProduct product = Platform.getProduct();
+ if (product != null) {
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PRODUCT, product.getId());
+ Bundle productBundle = product.getDefiningBundle();
+ if (productBundle != null) {
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PRODUCT_VERSION,
+ productBundle.getVersion().toString());
+ }
+ }
+ Bundle runtimeBundle = Platform.getBundle("org.eclipse.core.runtime"); //$NON-NLS-1$
+ if (runtimeBundle != null) {
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_RUNTIME_VERSION, runtimeBundle.getVersion()
+ .toString());
+ }
+ // also send the platform version to distinguish between 3.x and 4.x platforms using the same runtime
+ Bundle platformBundle = Platform.getBundle("org.eclipse.platform"); //$NON-NLS-1$
+ if (platformBundle != null) {
+ requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PLATFORM_VERSION,
+ platformBundle.getVersion().toString());
+ }
+ return requestMetaParameters;
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
index 5096f5cd..d35839aa 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CachingMarketplaceService.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
@@ -20,10 +21,16 @@ import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
-public class CachingMarketplaceService implements MarketplaceService {
+public class CachingMarketplaceService implements IMarketplaceService {
- private final MarketplaceService delegate;
+ private final IMarketplaceService delegate;
private int maxCacheSize = 30;
@@ -36,7 +43,7 @@ public class CachingMarketplaceService implements MarketplaceService {
}
};
- public CachingMarketplaceService(MarketplaceService delegate) {
+ public CachingMarketplaceService(IMarketplaceService delegate) {
if (delegate == null) {
throw new IllegalArgumentException();
}
@@ -51,21 +58,21 @@ public class CachingMarketplaceService implements MarketplaceService {
this.maxCacheSize = maxCacheSize;
}
- public List<Market> listMarkets(IProgressMonitor monitor) throws CoreException {
+ public List<? extends IMarket> listMarkets(IProgressMonitor monitor) throws CoreException {
return delegate.listMarkets(monitor);
}
- public Market getMarket(Market market, IProgressMonitor monitor) throws CoreException {
+ public IMarket getMarket(IMarket market, IProgressMonitor monitor) throws CoreException {
return delegate.getMarket(market, monitor);
}
- public Category getCategory(Category category, IProgressMonitor monitor) throws CoreException {
+ public ICategory getCategory(ICategory category, IProgressMonitor monitor) throws CoreException {
return delegate.getCategory(category, monitor);
}
- public Node getNode(Node node, IProgressMonitor monitor) throws CoreException {
+ public INode getNode(INode node, IProgressMonitor monitor) throws CoreException {
String nodeKey = computeNodeKey(node);
- Node nodeResult = null;
+ INode nodeResult = null;
if (nodeKey != null) {
synchronized (cache) {
Reference<Object> reference = cache.get(nodeKey);
@@ -85,7 +92,7 @@ public class CachingMarketplaceService implements MarketplaceService {
return nodeResult;
}
- private String computeNodeKey(Node node) {
+ private String computeNodeKey(INode node) {
if (node.getId() != null) {
return "Node:" + node.getId(); //$NON-NLS-1$
}
@@ -93,27 +100,27 @@ public class CachingMarketplaceService implements MarketplaceService {
}
private interface SearchOperation {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException;
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException;
}
- public SearchResult search(final Market market, final Category category, final String queryText,
+ public ISearchResult search(final IMarket market, final ICategory category, final String queryText,
IProgressMonitor monitor) throws CoreException {
String key = computeSearchKey("search", market, category, queryText); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
return delegate.search(market, category, queryText, monitor);
}
});
}
- private SearchResult performSearch(IProgressMonitor monitor, String key, SearchOperation searchOperation)
+ private ISearchResult performSearch(IProgressMonitor monitor, String key, SearchOperation searchOperation)
throws CoreException {
- SearchResult result = null;
+ ISearchResult result = null;
synchronized (cache) {
Reference<Object> reference = cache.get(key);
if (reference != null) {
- result = (SearchResult) reference.get();
+ result = (ISearchResult) reference.get();
}
}
if (result == null) {
@@ -121,7 +128,7 @@ public class CachingMarketplaceService implements MarketplaceService {
if (result != null) {
synchronized (cache) {
cache.put(key, new SoftReference<Object>(result));
- for (Node node : result.getNodes()) {
+ for (INode node : result.getNodes()) {
cache.put(computeNodeKey(node), new SoftReference<Object>(node));
}
}
@@ -130,69 +137,78 @@ public class CachingMarketplaceService implements MarketplaceService {
return result;
}
- private String computeSearchKey(String prefix, Market market, Category category, String queryText) {
+ private String computeSearchKey(String prefix, IMarket market, ICategory category, String queryText) {
return prefix
+ ":" + (market == null ? "" : market.getId()) + ":" + (category == null ? "" : category.getId()) + ":" + (queryText == null ? "" : queryText.trim()); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$ //$NON-NLS-6$
}
- public SearchResult featured(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult featured(IProgressMonitor monitor) throws CoreException {
String key = computeSearchKey("featured", null, null, null); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
return delegate.featured(monitor);
}
});
}
- public SearchResult featured(IProgressMonitor monitor, final Market market, final Category category)
+ public ISearchResult featured(final IMarket market, final ICategory category, IProgressMonitor monitor)
throws CoreException {
String key = computeSearchKey("featured", market, category, null); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
- return delegate.featured(monitor, market, category);
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ return delegate.featured(market, category, monitor);
}
});
}
- public SearchResult recent(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult recent(IProgressMonitor monitor) throws CoreException {
String key = computeSearchKey("recent", null, null, null); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
return delegate.recent(monitor);
}
});
}
- public SearchResult favorites(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult favorites(IProgressMonitor monitor) throws CoreException {
String key = computeSearchKey("favorites", null, null, null); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
return delegate.favorites(monitor);
}
});
}
- public SearchResult popular(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult popular(IProgressMonitor monitor) throws CoreException {
String key = computeSearchKey("popular", null, null, null); //$NON-NLS-1$
return performSearch(monitor, key, new SearchOperation() {
- public SearchResult doSearch(IProgressMonitor monitor) throws CoreException {
+ public ISearchResult doSearch(IProgressMonitor monitor) throws CoreException {
return delegate.popular(monitor);
}
});
}
- public News news(IProgressMonitor monitor) throws CoreException {
+ public INews news(IProgressMonitor monitor) throws CoreException {
return delegate.news(monitor);
}
public void reportInstallError(IProgressMonitor monitor, IStatus result, Set<Node> nodes,
Set<String> iuIdsAndVersions, String resolutionDetails) throws CoreException {
- delegate.reportInstallError(monitor, result, nodes, iuIdsAndVersions, resolutionDetails);
+ reportInstallError(result, nodes, iuIdsAndVersions, resolutionDetails, monitor);
+ }
+
+ public void reportInstallError(IStatus result, Set<? extends INode> nodes, Set<String> iuIdsAndVersions,
+ String resolutionDetails, IProgressMonitor monitor) throws CoreException {
+ delegate.reportInstallError(result, nodes, iuIdsAndVersions, resolutionDetails, monitor);
+ }
+
+ public void reportInstallSuccess(INode node, IProgressMonitor monitor) {
+ delegate.reportInstallSuccess(node, monitor);
}
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalog.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalog.java
index dab50ffc..44722e71 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalog.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalog.java
@@ -4,17 +4,20 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+
/**
* @author Benjamin Muskalla
*/
-public class Catalog extends Identifiable {
+public class Catalog extends Identifiable implements ICatalog {
private boolean selfContained;
@@ -78,4 +81,9 @@ public class Catalog extends Identifiable {
public void setNews(News news) {
this.news = news;
}
+
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof ICatalog;
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogBranding.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogBranding.java
index bdb7ebfb..26d22129 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogBranding.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogBranding.java
@@ -4,17 +4,20 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ICatalogBranding;
+
/**
* @author Benjamin Muskalla
*/
-public class CatalogBranding extends Identifiable {
+public class CatalogBranding extends Identifiable implements ICatalogBranding {
private String wizardIcon;
@@ -96,4 +99,8 @@ public class CatalogBranding extends Identifiable {
this.wizardTitle = wizardTitle;
}
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof ICatalogBranding;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogService.java
index 3f2d0e88..fa488dc4 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/CatalogService.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
@@ -14,8 +15,13 @@ import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
-public interface CatalogService {
+/**
+ * @deprecated Use {@link org.eclipse.epp.mpc.core.service.ICatalogService} instead.
+ */
+@Deprecated
+public interface CatalogService extends ICatalogService {
public List<Catalog> listCatalogs(IProgressMonitor monitor) throws CoreException;
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalogs.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalogs.java
index 0a9e8c07..1f1ba23f 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalogs.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Catalogs.java
@@ -4,16 +4,19 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ICatalogs;
+
/**
* @author Benjamin Muskalla
*/
-public class Catalogs {
+public class Catalogs implements ICatalogs {
protected java.util.List<Catalog> catalogs = new java.util.ArrayList<Catalog>();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Categories.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Categories.java
index 64c9f09d..f7461def 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Categories.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Categories.java
@@ -7,14 +7,17 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ICategories;
+
/**
* @author David Green
*/
-public class Categories {
+public class Categories implements ICategories {
protected java.util.List<Category> category = new java.util.ArrayList<Category>();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Category.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Category.java
index 42012487..0fadf19a 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Category.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Category.java
@@ -4,38 +4,45 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ICategory;
+
/**
* @author David Green
*/
-public class Category extends Identifiable {
-
+public class Category extends Identifiable implements ICategory {
+
protected Integer count;
protected java.util.List<Node> node = new java.util.ArrayList<Node>();
-
+
public Category() {
}
-
+
public Integer getCount() {
return count;
}
-
+
public void setCount(Integer count) {
this.count = count;
}
-
+
public java.util.List<Node> getNode() {
return node;
}
-
+
public void setNode(java.util.List<Node> node) {
this.node = node;
}
-
+
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof Category;
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultCatalogService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultCatalogService.java
index e57d8679..3343cdaa 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultCatalogService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultCatalogService.java
@@ -7,32 +7,39 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
-import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
-public class DefaultCatalogService extends RemoteMarketplaceService<Catalogs> implements CatalogService {
+public class DefaultCatalogService extends RemoteMarketplaceService<Catalogs> implements ICatalogService {
public static final String DEFAULT_CATALOG_SERVICE_LOCATION = System.getProperty(DefaultCatalogService.class.getName()
+ ".url", "http://marketplace.eclipse.org"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final URL DEFAULT_CATALOG_SERVICE_URL;
+
+ static {
+ DEFAULT_CATALOG_SERVICE_URL = ServiceUtil.parseUrl(DEFAULT_CATALOG_SERVICE_LOCATION);
+ }
+
public DefaultCatalogService() {
- try {
- baseUrl = new URL(DEFAULT_CATALOG_SERVICE_LOCATION);
- } catch (MalformedURLException e) {
- MarketplaceClientCore.error(e);
- baseUrl = null;
- }
+ this(null);
+ }
+
+ public DefaultCatalogService(URL baseUrl) {
+ this.baseUrl = baseUrl == null ? DEFAULT_CATALOG_SERVICE_URL : baseUrl;
}
- public List<Catalog> listCatalogs(IProgressMonitor monitor) throws CoreException {
+ public List<? extends ICatalog> listCatalogs(IProgressMonitor monitor) throws CoreException {
Catalogs result = processRequest("catalogs/" + API_URI_SUFFIX, monitor); //$NON-NLS-1$
return result.getCatalogs();
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
index 09ad4ae1..0a6cc1f7 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/DefaultMarketplaceService.java
@@ -7,17 +7,17 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - bug 397004, bug 385936
+ * Yatta Solutions - bug 397004, bug 385936, bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
-import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -31,15 +31,24 @@ import org.apache.http.message.BasicNameValuePair;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.epp.internal.mpc.core.util.HttpUtil;
+import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IIdentifiable;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
import org.eclipse.osgi.util.NLS;
/**
* @author David Green
* @author Carsten Reckord
*/
-public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketplace> implements MarketplaceService {
+@SuppressWarnings("deprecation")
+public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketplace> implements IMarketplaceService,
+MarketplaceService {
// This provisional API will be identified by /api/p at the end of most urls.
//
@@ -81,44 +90,46 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
public static final String DEFAULT_SERVICE_LOCATION = System.getProperty(MarketplaceService.class.getName()
+ ".url", "http://marketplace.eclipse.org"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final URL DEFAULT_SERVICE_URL;
+
/**
* parameter identifying client
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_CLIENT = "client"; //$NON-NLS-1$
/**
* parameter identifying windowing system as reported by {@link org.eclipse.core.runtime.Platform#getWS()}
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_WS = "ws"; //$NON-NLS-1$
/**
* parameter identifying operating system as reported by {@link org.eclipse.core.runtime.Platform#getOS()}
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_OS = "os"; //$NON-NLS-1$
/**
* parameter identifying the current local as reported by {@link org.eclipse.core.runtime.Platform#getNL()}
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_NL = "nl"; //$NON-NLS-1$
/**
* parameter identifying Java version
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_JAVA_VERSION = "java.version"; //$NON-NLS-1$
/**
* parameter identifying the Eclipse runtime version (the version of the org.eclipse.core.runtime bundle)
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_RUNTIME_VERSION = "runtime.version"; //$NON-NLS-1$
@@ -127,36 +138,35 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
* parameter identifying the Eclipse platform version (the version of the org.eclipse.platform bundle) This
* parameter is optional and only sent if the platform bundle is present. It is used to identify the actual running
* platform's version (esp. where different platforms share the same runtime, like the parallel 3.x/4.x versions)
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_PLATFORM_VERSION = "platform.version"; //$NON-NLS-1$
/**
* parameter identifying the Eclipse product version
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_PRODUCT_VERSION = "product.version"; //$NON-NLS-1$
/**
* parameter identifying the product id, as provided by <code>Platform.getProduct().getId()</code>
- *
+ *
* @see {@link #setRequestMetaParameters(Map)}
*/
public static final String META_PARAM_PRODUCT = "product"; //$NON-NLS-1$
+ static {
+ DEFAULT_SERVICE_URL = ServiceUtil.parseUrl(DEFAULT_SERVICE_LOCATION);
+ }
+
public DefaultMarketplaceService(URL baseUrl) {
- this.baseUrl = baseUrl;
+ this.baseUrl = baseUrl == null ? DEFAULT_SERVICE_URL : baseUrl;
}
public DefaultMarketplaceService() {
- try {
- baseUrl = new URL(DEFAULT_SERVICE_LOCATION);
- } catch (MalformedURLException e) {
- MarketplaceClientCore.error(e);
- baseUrl = null;
- }
+ this(null);
}
public List<Market> listMarkets(IProgressMonitor monitor) throws CoreException {
@@ -164,17 +174,55 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
return marketplace.getMarket();
}
- public Market getMarket(Market market, IProgressMonitor monitor) throws CoreException {
- Marketplace marketplace = processRequest(market.getUrl(), API_URI_SUFFIX, monitor);
- if (marketplace.getMarket().isEmpty()) {
- throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_marketNotFound, null));
- } else if (marketplace.getMarket().size() > 1) {
- throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_unexpectedResponse, null));
+ public Market getMarket(IMarket market, IProgressMonitor monitor) throws CoreException {
+ if (market.getId() == null && market.getUrl() != null) {
+ throw new IllegalArgumentException();
+ }
+ List<Market> markets = listMarkets(monitor);
+ if (market.getId() != null) {
+ String marketId = market.getId();
+ for (Market aMarket : markets) {
+ if (marketId.equals(aMarket.getId())) {
+ return aMarket;
+ }
+ }
+ } else if (market.getUrl() != null) {
+ String marketUrl = market.getUrl();
+ for (Market aMarket : markets) {
+ if (marketUrl.equals(aMarket.getUrl())) {
+ return aMarket;
+ }
+ }
}
- return marketplace.getMarket().get(0);
+ throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_marketNotFound, null));
}
- public Category getCategory(Category category, IProgressMonitor monitor) throws CoreException {
+ public Market getMarket(Market market, IProgressMonitor monitor) throws CoreException {
+ return getMarket((IMarket) market, monitor);
+ }
+
+ public Category getCategory(ICategory category, IProgressMonitor monitor) throws CoreException {
+ if (category.getId() != null && category.getUrl() == null) {
+ SubMonitor progress = SubMonitor.convert(monitor, 100);
+ List<Market> markets = listMarkets(progress.newChild(50));
+ ICategory resolvedCategory = null;
+ outer: for (Market market : markets) {
+ List<Category> categories = market.getCategory();
+ for (Category aCategory : categories) {
+ if (aCategory.equalsId(category)) {
+ resolvedCategory = aCategory;
+ break outer;
+ }
+ }
+ }
+ if (progress.isCanceled()) {
+ throw new OperationCanceledException();
+ } else if (resolvedCategory == null) {
+ throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_categoryNotFound, null));
+ } else {
+ return getCategory(resolvedCategory, progress.newChild(50));
+ }
+ }
Marketplace marketplace = processRequest(category.getUrl(), API_URI_SUFFIX, monitor);
if (marketplace.getCategory().isEmpty()) {
throw new CoreException(createErrorStatus(Messages.DefaultMarketplaceService_categoryNotFound, null));
@@ -184,18 +232,16 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
return marketplace.getCategory().get(0);
}
- public Node getNode(Node node, IProgressMonitor monitor) throws CoreException {
+ public Category getCategory(Category category, IProgressMonitor monitor) throws CoreException {
+ return getCategory((ICategory) category, monitor);
+ }
+
+ public Node getNode(INode node, IProgressMonitor monitor) throws CoreException {
Marketplace marketplace;
if (node.getId() != null) {
// bug 304928: prefer the id method rather than the URL, since the id provides a stable URL and the
// URL is based on the name, which could change.
- String encodedId;
- try {
- encodedId = URLEncoder.encode(node.getId(), UTF_8);
- } catch (UnsupportedEncodingException e) {
- // should never happen
- throw new IllegalStateException(e);
- }
+ String encodedId = urlEncode(node.getId());
marketplace = processRequest(API_NODE_URI + '/' + encodedId + '/' + API_URI_SUFFIX, monitor);
} else {
marketplace = processRequest(node.getUrl(), API_URI_SUFFIX, monitor);
@@ -208,7 +254,11 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
return marketplace.getNode().get(0);
}
- public SearchResult search(Market market, Category category, String queryText, IProgressMonitor monitor)
+ public Node getNode(Node node, IProgressMonitor monitor) throws CoreException {
+ return getNode((INode) node, monitor);
+ }
+
+ public SearchResult search(IMarket market, ICategory category, String queryText, IProgressMonitor monitor)
throws CoreException {
SearchResult result = new SearchResult();
String relativeUrl = computeRelativeSearchUrl(market, category, queryText, true);
@@ -238,6 +288,11 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
return result;
}
+ public SearchResult search(Market market, Category category, String queryText, IProgressMonitor monitor)
+ throws CoreException {
+ return search((IMarket) market, (ICategory) category, queryText, monitor);
+ }
+
/**
* Creates the query URL for the Marketplace REST API.
* <p>
@@ -251,7 +306,7 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
* order.
* <p>
* If the query is empty and both category and market are null, the result is null
- *
+ *
* @param market
* the market to search or null
* @param category
@@ -264,71 +319,63 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
* <code>api/p/search/apachesolr_search/WikiText?filters=tid:38%20tid:31</code> or
* <code>taxonomy/term/38,31/api/p</code>
*/
- public String computeRelativeSearchUrl(Market market, Category category, String queryText, boolean api) {
+ public String computeRelativeSearchUrl(IMarket market, ICategory category, String queryText, boolean api) {
String relativeUrl;
- try {
- if (queryText != null && queryText.trim().length() > 0) {
- relativeUrl = (api ? API_SEARCH_URI_FULL : API_SEARCH_URI) + URLEncoder.encode(queryText.trim(), UTF_8);
- String queryString = ""; //$NON-NLS-1$
- if (market != null || category != null) {
- queryString += "filters="; //$NON-NLS-1$
- Identifiable first = api ? market : category;
- Identifiable second = api ? category : market;
- if (first != null) {
- queryString += "tid:" + URLEncoder.encode(first.getId(), UTF_8); //$NON-NLS-1$
- if (second != null) {
- queryString += "%20"; //$NON-NLS-1$
- }
- }
+ if (queryText != null && queryText.trim().length() > 0) {
+ relativeUrl = (api ? API_SEARCH_URI_FULL : API_SEARCH_URI) + urlEncode(queryText.trim());
+ String queryString = ""; //$NON-NLS-1$
+ if (market != null || category != null) {
+ queryString += "filters="; //$NON-NLS-1$
+ IIdentifiable first = api ? market : category;
+ IIdentifiable second = api ? category : market;
+ if (first != null) {
+ queryString += "tid:" + urlEncode(first.getId()); //$NON-NLS-1$
if (second != null) {
- queryString += "tid:" + URLEncoder.encode(second.getId(), UTF_8); //$NON-NLS-1$
+ queryString += "%20"; //$NON-NLS-1$
}
}
- if (queryString.length() > 0) {
- relativeUrl += '?' + queryString;
- }
- } else if (market != null || category != null) {
- // http://marketplace.eclipse.org/taxonomy/term/38,31
- relativeUrl = API_TAXONOMY_URI;
- if (category != null) {
- relativeUrl += URLEncoder.encode(category.getId(), UTF_8);
- if (market != null) {
- relativeUrl += ',';
- }
+ if (second != null) {
+ queryString += "tid:" + urlEncode(second.getId()); //$NON-NLS-1$
}
+ }
+ if (queryString.length() > 0) {
+ relativeUrl += '?' + queryString;
+ }
+ } else if (market != null || category != null) {
+ // http://marketplace.eclipse.org/taxonomy/term/38,31
+ relativeUrl = API_TAXONOMY_URI;
+ if (category != null) {
+ relativeUrl += urlEncode(category.getId());
if (market != null) {
- relativeUrl += URLEncoder.encode(market.getId(), UTF_8);
- }
- if (api) {
- relativeUrl += '/' + API_URI_SUFFIX;
+ relativeUrl += ',';
}
- } else {
- relativeUrl = null;
}
- } catch (UnsupportedEncodingException e) {
- throw new IllegalArgumentException(e);
+ if (market != null) {
+ relativeUrl += urlEncode(market.getId());
+ }
+ if (api) {
+ relativeUrl += '/' + API_URI_SUFFIX;
+ }
+ } else {
+ relativeUrl = null;
}
return relativeUrl;
}
public SearchResult featured(IProgressMonitor monitor) throws CoreException {
- return featured(monitor, null, null);
+ return featured(null, null, monitor);
}
- public SearchResult featured(IProgressMonitor monitor, Market market, Category category) throws CoreException {
+ public SearchResult featured(IMarket market, ICategory category, IProgressMonitor monitor) throws CoreException {
String nodePart = ""; //$NON-NLS-1$
- try {
- if (market != null) {
- nodePart += URLEncoder.encode(market.getId(), UTF_8);
- }
- if (category != null) {
- if (nodePart.length() > 0) {
- nodePart += ","; //$NON-NLS-1$
- }
- nodePart += URLEncoder.encode(category.getId(), UTF_8);
+ if (market != null) {
+ nodePart += urlEncode(market.getId());
+ }
+ if (category != null) {
+ if (nodePart.length() > 0) {
+ nodePart += ","; //$NON-NLS-1$
}
- } catch (UnsupportedEncodingException e) {
- throw new IllegalStateException();
+ nodePart += urlEncode(category.getId());
}
String uri = API_FEATURED_URI + '/';
if (nodePart.length() > 0) {
@@ -338,6 +385,10 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
return createSearchResult(marketplace.getFeatured());
}
+ public SearchResult featured(IProgressMonitor monitor, Market market, Category category) throws CoreException {
+ return featured(market, category, monitor);
+ }
+
public SearchResult recent(IProgressMonitor monitor) throws CoreException {
Marketplace marketplace = processRequest(API_RECENT_URI + '/' + API_URI_SUFFIX, monitor);
return createSearchResult(marketplace.getRecent());
@@ -377,8 +428,17 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
}
}
+ /**
+ * @deprecated use {@link #reportInstallError(IStatus, Set, Set, String, IProgressMonitor)} instead
+ */
+ @Deprecated
public void reportInstallError(IProgressMonitor monitor, IStatus result, Set<Node> nodes,
Set<String> iuIdsAndVersions, String resolutionDetails) throws CoreException {
+ reportInstallError(result, nodes, iuIdsAndVersions, resolutionDetails, monitor);
+ }
+
+ public void reportInstallError(IStatus result, Set<? extends INode> nodes, Set<String> iuIdsAndVersions,
+ String resolutionDetails, IProgressMonitor monitor) throws CoreException {
HttpClient client;
URL location;
HttpPost method;
@@ -404,7 +464,7 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
parameters.add(new BasicNameValuePair("status", Integer.toString(result.getSeverity()))); //$NON-NLS-1$
parameters.add(new BasicNameValuePair("statusMessage", result.getMessage())); //$NON-NLS-1$
- for (Node node : nodes) {
+ for (INode node : nodes) {
parameters.add(new BasicNameValuePair("node", node.getId())); //$NON-NLS-1$
}
if (iuIdsAndVersions != null && !iuIdsAndVersions.isEmpty()) {
@@ -427,4 +487,25 @@ public class DefaultMarketplaceService extends RemoteMarketplaceService<Marketpl
}
}
+ public void reportInstallSuccess(INode node, IProgressMonitor monitor) {
+ String url = node.getUrl();
+ if (!url.endsWith("/")) { //$NON-NLS-1$
+ url += "/"; //$NON-NLS-1$
+ }
+ url += "success"; //$NON-NLS-1$
+ url = addMetaParameters(url);
+ try {
+ InputStream stream = transport.stream(new URI(url), monitor);
+
+ try {
+ while (stream.read() != -1) {
+ // nothing to do
+ }
+ } finally {
+ stream.close();
+ }
+ } catch (Throwable e) {
+ //per bug 314028 logging this error is not useful.
+ }
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Identifiable.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Identifiable.java
index 45501111..da974aba 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Identifiable.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Identifiable.java
@@ -4,18 +4,21 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.IIdentifiable;
+
/**
* @author David Green
* @author Carsten Reckord
*/
-public abstract class Identifiable {
+public abstract class Identifiable implements IIdentifiable {
protected String id;
protected String name;
@@ -50,7 +53,7 @@ public abstract class Identifiable {
/**
* Check if the given object's type and id match.
- *
+ *
* @param obj
* the object to compare (can be null)
* @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getId() id} as this object
@@ -62,17 +65,85 @@ public abstract class Identifiable {
if (obj == null) {
return false;
}
- if (getClass() != obj.getClass()) {
+ if (!equalsType(obj)) {
return false;
}
- Identifiable other = (Identifiable) obj;
+ IIdentifiable other = (IIdentifiable) obj;
if (id == null) {
- if (other.id != null) {
+ if (other.getId() != null) {
+ return false;
+ }
+ } else if (!id.equals(other.getId())) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if the given object's type and url match.
+ *
+ * @param obj
+ * the object to compare (can be null)
+ * @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getUrl() url} as this object
+ */
+ public boolean equalsUrl(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!equalsType(obj)) {
+ return false;
+ }
+ IIdentifiable other = (IIdentifiable) obj;
+ if (url == null) {
+ if (other.getUrl() != null) {
+ return false;
+ }
+ } else if (!url.equals(other.getUrl())) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if the given object's type and url match.
+ *
+ * @param obj
+ * the object to compare (can be null)
+ * @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getUrl() url} as this object
+ */
+ public boolean equalsName(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!equalsType(obj)) {
+ return false;
+ }
+ IIdentifiable other = (IIdentifiable) obj;
+ if (name == null) {
+ if (other.getName() != null) {
return false;
}
- } else if (!id.equals(other.id)) {
+ } else if (!name.equals(other.getName())) {
+ return false;
+ }
+ return true;
+ }
+
+ protected boolean equalsType(Object obj) {
+ if (getClass() != obj.getClass()) {
return false;
}
return true;
}
+
+ public static boolean matches(IIdentifiable id1, IIdentifiable id2) {
+ return id2 == id1 || id2.equalsId(id1) || (id2.getId() == null && id2.equalsUrl(id1))
+ || (id2.getId() == null && id2.getUrl() == null && id2.equalsName(id1));
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Ius.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Ius.java
index 53bc5a21..f8e97404 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Ius.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Ius.java
@@ -7,14 +7,17 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.IIus;
+
/**
* @author David Green
*/
-public class Ius {
+public class Ius implements IIus {
protected java.util.List<String> iu = new java.util.ArrayList<String>();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Market.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Market.java
index 049b279e..b997d4fe 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Market.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Market.java
@@ -4,29 +4,37 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.IMarket;
+
/**
* @author David Green
*/
-public class Market extends Identifiable {
-
+public class Market extends Identifiable implements IMarket {
+
protected java.util.List<Category> category = new java.util.ArrayList<Category>();
-
+
public Market() {
}
-
+
public java.util.List<Category> getCategory() {
return category;
}
-
+
public void setCategory(java.util.List<Category> category) {
this.category = category;
}
-
+
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof IMarket;
+ }
+
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceService.java
index c169d98a..703ad86b 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceService.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
@@ -21,7 +22,9 @@ import org.eclipse.core.runtime.IStatus;
* a service that provides access to the marketplace.
*
* @author David Green
+ * @deprecated use {@link org.eclipse.epp.mpc.core.service.IMarketplaceService}
*/
+@Deprecated
public interface MarketplaceService {
/**
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java
new file mode 100644
index 00000000..18952a8f
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/MarketplaceUnmarshaller.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core.service;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.epp.internal.mpc.core.service.xml.Unmarshaller;
+import org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller;
+import org.eclipse.epp.mpc.core.service.UnmarshalException;
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * @author Carsten Reckord
+ */
+public class MarketplaceUnmarshaller implements IMarketplaceUnmarshaller {
+
+ public <T> T unmarshal(InputStream in, Class<T> type, IProgressMonitor monitor) throws IOException,
+ UnmarshalException {
+ final Unmarshaller unmarshaller = new Unmarshaller();
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ parserFactory.setNamespaceAware(true);
+ final XMLReader xmlReader;
+ try {
+ xmlReader = parserFactory.newSAXParser().getXMLReader();
+ } catch (Exception e1) {
+ throw new IllegalStateException(e1);
+ }
+ xmlReader.setContentHandler(unmarshaller);
+
+ // FIXME how can the charset be determined?
+ Reader reader = new InputStreamReader(new BufferedInputStream(in), RemoteMarketplaceService.UTF_8);
+ try {
+ xmlReader.parse(new InputSource(reader));
+ } catch (final SAXException e) {
+ throw new UnmarshalException(createErrorStatus(e.getMessage(), null));
+ }
+
+ Object model = unmarshaller.getModel();
+ if (model == null) {
+ // if we reach here this should never happen
+ throw new IllegalStateException();
+ } else {
+ try {
+ return type.cast(model);
+ } catch (Exception e) {
+ String message = NLS.bind(Messages.DefaultMarketplaceService_unexpectedResponseContent,
+ model.getClass().getSimpleName());
+ throw new UnmarshalException(createErrorStatus(message, null));
+ }
+ }
+ }
+
+ protected IStatus createErrorStatus(String message, Throwable t) {
+ return new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID, 0, message, t);
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/News.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/News.java
index ba8b5e26..8b410873 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/News.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/News.java
@@ -7,13 +7,16 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.INews;
+
/**
* @author Carsten Reckord
*/
-public class News {
+public class News implements INews {
private String url;
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Node.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Node.java
index 4900796f..a266462f 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Node.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Node.java
@@ -4,17 +4,20 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.INode;
+
/**
* @author David Green
* @author Benjamin Muskalla
*/
-public class Node extends Identifiable {
+public class Node extends Identifiable implements INode {
protected Integer favorited;
protected Integer installsTotal;
@@ -264,4 +267,8 @@ public class Node extends Identifiable {
this.platforms = platforms;
}
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof INode;
+ }
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/NotFoundException.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/NotFoundException.java
index 4ccd2b4a..1c5dec7b 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/NotFoundException.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/NotFoundException.java
@@ -7,12 +7,15 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
/**
* @author David Green
+ * @deprecated unused, will be removed in a future version
*/
+@Deprecated
@SuppressWarnings("serial")
public class NotFoundException extends Exception {
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Platforms.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Platforms.java
index 282e93fd..01ae8464 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Platforms.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Platforms.java
@@ -7,14 +7,17 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.IPlatforms;
+
/**
* @author David Green
*/
-public class Platforms {
+public class Platforms implements IPlatforms {
protected java.util.List<String> platform = new java.util.ArrayList<String>();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/RemoteMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/RemoteMarketplaceService.java
index 8e26c240..e57e03d4 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/RemoteMarketplaceService.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/RemoteMarketplaceService.java
@@ -7,14 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
-import java.io.BufferedInputStream;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -22,21 +19,20 @@ import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
-import javax.xml.parsers.SAXParserFactory;
-
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-import org.eclipse.epp.internal.mpc.core.service.xml.Unmarshaller;
-import org.eclipse.epp.internal.mpc.core.util.ITransport;
+import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceUnmarshaller;
+import org.eclipse.epp.mpc.core.service.ITransport;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
+import org.eclipse.epp.mpc.core.service.UnmarshalException;
import org.eclipse.osgi.util.NLS;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
public class RemoteMarketplaceService<T> {
@@ -46,10 +42,22 @@ public class RemoteMarketplaceService<T> {
protected static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
- private final ITransport transport = TransportFactory.instance().getTransport();
+ protected final ITransport transport;
+
+ protected final IMarketplaceUnmarshaller unmarshaller;
private Map<String, String> requestMetaParameters;
+ public RemoteMarketplaceService() {
+ this.transport = TransportFactory.createTransport();
+ IMarketplaceUnmarshaller unmarshaller = ServiceHelper.getMarketplaceUnmarshaller();
+ if (unmarshaller == null) {
+ //no unmarshaller registered, create a default instance
+ unmarshaller = new MarketplaceUnmarshaller();
+ }
+ this.unmarshaller = unmarshaller;
+ }
+
protected IStatus createErrorStatus(String message, Throwable t) {
return new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID, 0, message, t);
}
@@ -115,38 +123,23 @@ public class RemoteMarketplaceService<T> {
throw new CoreException(createErrorStatus(message, e));
}
- final Unmarshaller unmarshaller = new Unmarshaller();
monitor.beginTask(NLS.bind(Messages.DefaultMarketplaceService_retrievingDataFrom, baseUri), 100);
try {
- SAXParserFactory parserFactory = SAXParserFactory.newInstance();
- parserFactory.setNamespaceAware(true);
- final XMLReader xmlReader;
- try {
- xmlReader = parserFactory.newSAXParser().getXMLReader();
- } catch (Exception e1) {
- throw new IllegalStateException(e1);
- }
- xmlReader.setContentHandler(unmarshaller);
-
InputStream in = transport.stream(location, monitor);
try {
monitor.worked(30);
- // FIXME how can the charset be determined?
- Reader reader = new InputStreamReader(new BufferedInputStream(in), UTF_8);
- try {
- xmlReader.parse(new InputSource(reader));
- } catch (final SAXException e) {
- MarketplaceClientCore.error(
- NLS.bind(Messages.DefaultMarketplaceService_parseError, location.toString()), e);
- throw new IOException(e.getMessage());
- }
+ return (T) unmarshaller.unmarshal(in, Object.class, monitor);//FIXME having T.class available here would be great...
+ } catch (UnmarshalException e) {
+ MarketplaceClientCore.error(
+ NLS.bind(Messages.DefaultMarketplaceService_parseError, location.toString()), e);
+ throw e;
} finally {
if (in != null) {
in.close();
}
}
- } catch (IOException e) {
+ } catch (Exception e) {
if (e.getCause() instanceof OperationCanceledException) {
throw new CoreException(Status.CANCEL_STATUS);
}
@@ -156,20 +149,6 @@ public class RemoteMarketplaceService<T> {
} finally {
monitor.done();
}
-
- Object model = unmarshaller.getModel();
- if (model == null) {
- // if we reach here this should never happen
- throw new IllegalStateException();
- } else {
- try {
- return (T) model;
- } catch (Exception e) {
- String message = NLS.bind(Messages.DefaultMarketplaceService_unexpectedResponseContent,
- model.getClass().getSimpleName());
- throw new CoreException(createErrorStatus(message, null));
- }
- }
}
public String addMetaParameters(String uri) {
@@ -210,7 +189,7 @@ public class RemoteMarketplaceService<T> {
/**
* The meta-parameters to be included in API requests
- *
+ *
* @param requestMetaParameters
* the parameters or null if there should be none
*/
@@ -218,4 +197,22 @@ public class RemoteMarketplaceService<T> {
this.requestMetaParameters = requestMetaParameters;
}
+ protected static String urlEncode(String urlPart) {
+ try {
+ return URLEncoder.encode(urlPart, UTF_8);
+ } catch (UnsupportedEncodingException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public void activate(Map<?, ?> properties) {
+ if (properties != null) {
+ URL url = ServiceUtil.getUrl(properties, IMarketplaceService.BASE_URL, null);
+ if (url != null) {
+ setBaseUrl(url);
+ }
+ }
+ }
+
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/SearchResult.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/SearchResult.java
index 86d67b7e..53f30403 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/SearchResult.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/SearchResult.java
@@ -7,15 +7,18 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
import java.util.List;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
+
/**
* @author David Green
*/
-public class SearchResult {
+public class SearchResult implements ISearchResult {
private Integer matchCount;
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/ServiceUnavailableException.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/ServiceUnavailableException.java
index 31839e96..d33d7cbb 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/ServiceUnavailableException.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/ServiceUnavailableException.java
@@ -7,19 +7,21 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
/**
* Indicates that a service is temporarily unavailable, equivalent to HTTP status code 503
- *
+ *
* @author David Green
+ * @deprecated use {@link org.eclipse.epp.mpc.core.service.ServiceUnavailableException} instead
*/
+@Deprecated
@SuppressWarnings("serial")
-public class ServiceUnavailableException extends CoreException {
+public class ServiceUnavailableException extends org.eclipse.epp.mpc.core.service.ServiceUnavailableException {
public ServiceUnavailableException(IStatus status) {
super(status);
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tag.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tag.java
index 6f0fd8a8..8c98d049 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tag.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tag.java
@@ -7,15 +7,23 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ITag;
+
/**
* @author Benjamin Muskalla
*/
-public class Tag extends Identifiable {
+public class Tag extends Identifiable implements ITag {
public Tag() {
}
+ @Override
+ protected boolean equalsType(Object obj) {
+ return obj instanceof ITag;
+ }
+
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tags.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tags.java
index 9f898cca..6e3a3646 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tags.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/service/Tags.java
@@ -7,13 +7,16 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.service;
+import org.eclipse.epp.mpc.core.model.ITags;
+
/**
* @author Benjamin Muskalla
*/
-public class Tags {
+public class Tags implements ITags {
protected java.util.List<Tag> tags = new java.util.ArrayList<Tag>();
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ITransport.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ITransport.java
index 4b3f6618..b8694152 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ITransport.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ITransport.java
@@ -7,16 +7,14 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.util;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.net.URI;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-public interface ITransport {
- public InputStream stream(URI location, IProgressMonitor monitor) throws FileNotFoundException, CoreException;
+/**
+ * @deprecated moved to {@link org.eclipse.epp.mpc.core.service.ITransport}
+ */
+@Deprecated
+public interface ITransport extends org.eclipse.epp.mpc.core.service.ITransport {
}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/Messages.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/Messages.java
index b496bb08..9a74d9c5 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/Messages.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/Messages.java
@@ -20,6 +20,8 @@ class Messages extends NLS {
public static String DefaultMarketplaceService_serviceUnavailable503;
public static String ProxyHelper_replacingAuthenticator;
+
+ public static String ServiceUtil_ignoringIncompatibleServiceProperty;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java
new file mode 100644
index 00000000..d4c652ec
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/ServiceUtil.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.core.util;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Constants;
+
+/**
+ * @author Carsten Reckord
+ */
+public class ServiceUtil {
+
+ /**
+ * Set the provided priority on a dictionary for an OSGi service registration. If the dictionary is null,
+ * a new one will be created and returned.
+ *
+ * @param priority the service priority
+ * @param dict the dictionary to change or null
+ * @return the provided dictionary, or a new one if the provided was null, containing a service ranking entry
+ * @see Constants#SERVICE_RANKING
+ */
+ public static Dictionary<String, Object> serviceRanking(int priority, Dictionary<String, Object> dict) {
+ if (dict == null) {
+ dict = new Hashtable<String, Object>();
+ }
+ dict.put(Constants.SERVICE_RANKING, priority);
+ return dict;
+ }
+
+ /**
+ * Get a URL from a property map for the given key. If no entry exists for the key,
+ * or the value is not a string or it can't be parsed into an URL, the default value
+ * is returned.
+ *
+ * @param properties the map to extract a URL from
+ * @param key the key to search under
+ * @param defaultValue the default value returned if the entry does not exist or can't
+ * be converted to a URL
+ * @return an URL matching the string value found in the map under the given key, or the default value.
+ */
+ public static URL getUrl(Map<?, ?> properties, String key, URL defaultValue) {
+ if (properties != null) {
+ Object value = properties.get(key);
+ if (value instanceof String) {
+ try {
+ return new URL((String) value);
+ } catch (MalformedURLException e) {
+ MarketplaceClientCore.error(e);
+ }
+ } else if (value != null) {
+ //wrong type, ignore
+ MarketplaceClientCore.getLog().log(
+ new Status(IStatus.WARNING, MarketplaceClientCore.BUNDLE_ID, NLS.bind(
+ Messages.ServiceUtil_ignoringIncompatibleServiceProperty, value, key)));
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Parse the given string to an URL. If the string can't be parsed, an error is logged
+ * and null is returned
+ *
+ * @param url the url string to parse
+ * @return the value as an URL, or null if there was a parse error
+ */
+ public static URL parseUrl(String url) {
+ try {
+ return new URL(url);
+ } catch (MalformedURLException e) {
+ MarketplaceClientCore.error(e);
+ return null;
+ }
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
index 4165adcf..efbc4571 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/TransportFactory.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.util;
@@ -14,21 +15,29 @@ import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
import org.eclipse.epp.internal.mpc.core.service.ServiceUnavailableException;
+import org.eclipse.epp.mpc.core.service.ITransportFactory;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
/**
* Factory to retrieve Transport instances of p2. Will delegate to version-dependent implementations.
- *
+ *
* @author David Green
* @author Benjamin Muskalla
+ * @author Carsten Reckord
*/
-public abstract class TransportFactory {
+public abstract class TransportFactory implements ITransportFactory {
private static final String[] factoryClasses = new String[] { //
"org.eclipse.epp.internal.mpc.core.util.P2TransportFactory", // //$NON-NLS-1$
@@ -37,34 +46,63 @@ public abstract class TransportFactory {
private static TransportFactory instance;
+ /**
+ * @deprecated use registered {@link ITransportFactory} OSGi service
+ * @see ServiceHelper#getTransportFactory()
+ */
+ @Deprecated
public static synchronized TransportFactory instance() {
if (instance == null) {
- for (String factoryClass : factoryClasses) {
- TransportFactory factory;
- try {
- factory = (TransportFactory) Class.forName(factoryClass,true,TransportFactory.class.getClassLoader()).newInstance();
- } catch (Throwable t) {
- // ignore
- continue;
- }
- if (factory.isAvailable()) {
- instance = factory;
- break;
- }
- }
- if (instance == null) {
+ List<ITransportFactory> availableFactories = listAvailableFactories();
+ if (availableFactories.isEmpty()) {
throw new IllegalStateException();
}
+ instance = (TransportFactory) availableFactories.get(0);
}
return instance;
}
+ public static org.eclipse.epp.mpc.core.service.ITransport createTransport() {
+ //search for registered factory service
+ BundleContext context = MarketplaceClientCorePlugin.getBundle().getBundleContext();
+ ServiceReference<ITransportFactory> serviceReference = context.getServiceReference(ITransportFactory.class);
+ if (serviceReference != null) {
+ ITransportFactory transportService = context.getService(serviceReference);
+ if (transportService != null) {
+ try {
+ return transportService.getTransport();
+ } finally {
+ context.ungetService(serviceReference);
+ }
+ }
+ }
+ //fall back to legacy transports
+ return instance().getTransport();
+ }
+
+ public static List<ITransportFactory> listAvailableFactories() {
+ List<ITransportFactory> factories = new ArrayList<ITransportFactory>();
+ for (String factoryClass : factoryClasses) {
+ TransportFactory factory;
+ try {
+ factory = (TransportFactory) Class.forName(factoryClass, true, TransportFactory.class.getClassLoader())
+ .newInstance();
+ } catch (Throwable t) {
+ // ignore
+ continue;
+ }
+ if (factory.isAvailable()) {
+ factories.add(factory);
+ }
+ }
+ return factories;
+ }
public ITransport getTransport() {
return new ITransport() {
public InputStream stream(URI location, IProgressMonitor monitor) throws FileNotFoundException,
- CoreException {
+ org.eclipse.epp.mpc.core.service.ServiceUnavailableException, CoreException {
try {
return invokeStream(location, monitor);
} catch (Exception e) {
@@ -108,5 +146,4 @@ public abstract class TransportFactory {
}
}
}
-
} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/messages.properties b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/messages.properties
index 9e1cf227..0dfe7cff 100644
--- a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/messages.properties
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/internal/mpc/core/util/messages.properties
@@ -1,3 +1,4 @@
P2TransportFactory_AuthenticationFailed=Authentication failed: {0}
ProxyHelper_replacingAuthenticator=Unable to read default network authenticator - existing authenticator will be replaced
-DefaultMarketplaceService_serviceUnavailable503=Marketplace service is temporarily unavailable. Please try again later. \ No newline at end of file
+DefaultMarketplaceService_serviceUnavailable503=Marketplace service is temporarily unavailable. Please try again later.
+ServiceUtil_ignoringIncompatibleServiceProperty=Ignoring value '{0}' for service property '{1}' - incompatible type.
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalog.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalog.java
new file mode 100644
index 00000000..efe03f3f
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalog.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import org.eclipse.epp.mpc.core.service.ICatalogService;
+
+/**
+ * A catalog describes an entry point to a marketplace server. Its {@link #getUrl() url} is the base of the Marketplace
+ * REST API. It has a description, image and optional additional provider branding information, which can be used to
+ * present the marketplace to users, e.g. in the Marketplace Wizard.
+ *
+ * @see ICatalogService
+ * @see https://wiki.eclipse.org/Marketplace/REST
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICatalog extends IIdentifiable {
+
+ /**
+ * If the catalog is self-contained, then a {@link INode node} installation will only use the node's
+ * {@link INode#getUpdateurl() update url} and the catalog's {@link #getDependencyRepository() dependency
+ * repository}. Otherwise all known repositories are consulted.
+ *
+ * @return true if this catalog is self-contained, false if all known repositories should be used during
+ * installation
+ */
+ boolean isSelfContained();
+
+ /**
+ * @return this catalog's description suitable for presentation to the user.
+ */
+ String getDescription();
+
+ /**
+ * @return a URL to an image resource used to present this catalog in a catalog chooser. May be null.
+ */
+ String getImageUrl();
+
+ /**
+ * @return additional branding information
+ */
+ ICatalogBranding getBranding();
+
+ /**
+ * An optional URI to a repository from which dependencies may be installed, may be null.
+ *
+ * @return the URI to use for dependency resolution, or null.
+ */
+ String getDependencyRepository();
+
+ /**
+ * Each catalog can optionally point to a current news entry, e.g. to present the user with a newsletter.
+ *
+ * @return the current news entry for this catalog, or null.
+ */
+ INews getNews();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogBranding.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogBranding.java
new file mode 100644
index 00000000..672a39de
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogBranding.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+/**
+ * Branding information for a marketplace catalog entry.
+ *
+ * @see ICatalog
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICatalogBranding extends IIdentifiable {
+
+ String getWizardIcon();
+
+ boolean hasSearchTab();
+
+ String getSearchTabName();
+
+ boolean hasPopularTab();
+
+ String getPopularTabName();
+
+ boolean hasRecentTab();
+
+ String getRecentTabName();
+
+ String getWizardTitle();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogs.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogs.java
new file mode 100644
index 00000000..b9bc5734
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICatalogs.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * A list of catalogs.
+ *
+ * @see ICatalog
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICatalogs {
+
+ List<? extends ICatalog> getCatalogs();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategories.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategories.java
new file mode 100644
index 00000000..9a3da357
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategories.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * A list of categories.
+ *
+ * @see ICategory
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICategories {
+
+ List<? extends ICategory> getCategory();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategory.java
new file mode 100644
index 00000000..0dc7c9f3
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ICategory.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+
+/**
+ * Marketplaces are categorized in {@link IMarket markets} and {@link ICategory categories}. Each category can occur in
+ * one or more markets and can be associated with any number of {@link #getNode() nodes}.
+ *
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICategory extends IIdentifiable {
+
+ /**
+ * @return the number of {@link #getNode() nodes} in this category
+ */
+ Integer getCount();
+
+ /**
+ * A list of nodes for this category. Entries in this list are typically not fully realized. They will only have
+ * their {@link INode#getId() ids} and {@link INode#getName() names} set. Use
+ * {@link IMarketplaceService#getNode(INode, org.eclipse.core.runtime.IProgressMonitor) the marketplace service} to
+ * retrieve a fully realized node instance from the marketplace server.
+ *
+ * @return the list of nodes in this category.
+ */
+ List<? extends INode> getNode();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIdentifiable.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIdentifiable.java
new file mode 100644
index 00000000..867b02af
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIdentifiable.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+/**
+ * Base class for marketplace entities like nodes or categories. Instances are identified by an id unique to their
+ * {@link ICatalog marketplace server} and/or their url. Optionally, they may have a name suitable for presentation to
+ * the user.
+ *
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IIdentifiable {
+
+ /**
+ * @return this element's unique id in its {@link ICatalog catalog}
+ */
+ String getId();
+
+ /**
+ * @return this element's name
+ */
+ String getName();
+
+ /**
+ * @return the URL from which this element can be re-retrieved from the marketplace server
+ */
+ String getUrl();
+
+ /**
+ * Check if the given object's type and id match.
+ *
+ * @param obj
+ * the object to compare (can be null)
+ * @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getId() id} as this object
+ */
+ boolean equalsId(Object obj);
+
+ /**
+ * Check if the given object's type and url match.
+ *
+ * @param obj
+ * the object to compare (can be null)
+ * @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getUrl() url} as this object
+ */
+ boolean equalsUrl(Object obj);
+
+ /**
+ * Check if the given object's type and name match.
+ *
+ * @param obj
+ * the object to compare (can be null)
+ * @return true if <code>obj</code> has the same {@link #getClass() type} and {@link #getName() name} as this object
+ */
+ boolean equalsName(Object obj);
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIus.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIus.java
new file mode 100644
index 00000000..f4d35b15
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IIus.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * A list of installable units for an installable marketplace {@link INode node}
+ *
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IIus {
+
+ List<String> getIu();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IMarket.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IMarket.java
new file mode 100644
index 00000000..cd25cc39
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IMarket.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * Marketplaces are categorized in {@link IMarket markets} and {@link ICategory categories}. Each market can have a
+ * number of categories, which in turn can be associated with {@link INode nodes}.
+ *
+ * @see ICategory
+ * @see INode
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarket extends IIdentifiable {
+
+ List<? extends ICategory> getCategory();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INews.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INews.java
new file mode 100644
index 00000000..7ae3483b
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INews.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+/**
+ * Information about a published news item for a catalog. This can be used to e.g. integrate a regularly published
+ * newsletter with the marketplace wizard.
+ *
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface INews {
+
+ /**
+ * @return the URL of the published news item
+ */
+ String getUrl();
+
+ /**
+ * @return a short news title suitable to be presented before the actual news is opened.
+ */
+ String getShortTitle();
+
+ /**
+ * @return a timestamp for the last update to the news. Any change to the published news should result in an updated
+ * timestamp.
+ */
+ Long getTimestamp();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INode.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INode.java
new file mode 100644
index 00000000..0700a0fc
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/INode.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.Date;
+
+/**
+ * A node represents an entry on a marketplace. It is associated with one or more categories, under which it is listed.
+ * Additionally, tags can be specified to define related technologies.
+ * <p>
+ * A node contains all information about a marketplace entry necessary to present it to users, including a
+ * {@link #getName()}, {@link #getOwner() owner}, {@link #getShortdescription() short} and {@link #getBody() long}
+ * description, {@link #getImage() icon} and optional {@link #getScreenshot()}. Some social feedback on the node entry
+ * is provided by means of its {@link #getInstallsTotal() total} and {@link #getInstallsRecent() recent} installation
+ * counts, as well as the number of {@link #getFavorited() favorite votes} it has received.
+ * <p>
+ * Nodes can describe different kinds of {@link #getType() contributions}, like installable Eclipse plug-ins, consulting
+ * services and so on. In case of installable Eclipse plug-ins, the {@link #getIus() installable units} are provided for
+ * installation from the node's {@link #getUpdateurl() update site}.
+ *
+ * @author David Green
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface INode extends IIdentifiable {
+
+ /**
+ * The number of times this node has been favorited.
+ */
+ Integer getFavorited();
+
+ /**
+ * The number of times this node has been installed.
+ */
+ Integer getInstallsTotal();
+
+ /**
+ * The number of times this node has been installed recently (last 30 days).
+ */
+ Integer getInstallsRecent();
+
+ /**
+ * The type of listing, for example 'resource' or 'training'.
+ */
+ String getType();
+
+ /**
+ * the categories of this listing.
+ */
+ ICategories getCategories();
+
+ ITags getTags();
+
+ String getOwner();
+
+ /**
+ * The short description of this listing, may include HTML markup (escaped). Note that the short description may or
+ * may not be shorter than the body.
+ */
+ String getShortdescription();
+
+ /**
+ * The description of this listing, may include HTML markup (escaped).
+ */
+ String getBody();
+
+ /**
+ * The time of creation for this entry.
+ */
+ Date getCreated();
+
+ /**
+ * The last change time for this entry.
+ */
+ Date getChanged();
+
+ /**
+ * @return true if this node's owner is a foundation member, false otherwise, null if unknown.
+ */
+ Boolean getFoundationmember();
+
+ /**
+ * An URL for the homepage for this entry or its owner.
+ */
+ String getHomepageurl();
+
+ /**
+ * The image used as this entry's logo
+ */
+ String getImage();
+
+ /**
+ * An optional screenshot used in conjunction with the {@link #getBody() full description}.
+ */
+ String getScreenshot();
+
+ /**
+ * The version of the solution represented by this node. It is encouraged to use a valid OSGi version, but this
+ * isn't guaranteed.
+ */
+ String getVersion();
+
+ /**
+ * The license for the plug-in represented by this node, e.g. 'EPL'.
+ */
+ String getLicense();
+
+ /**
+ * The owner's company name
+ */
+ String getCompanyname();
+
+ /**
+ * The development status of this plug-in entry, e.g. "Production/Stable"
+ */
+ String getStatus();
+
+ /**
+ * A comma-separated list of supported Eclipse versions. Currently, this can take any form, although it is
+ * encouraged to use a comma-separated list of Eclipse versions like "3.6-3.8, 4.2.1, 4.2.2, 4.3".
+ * <p>
+ * This might get more standardized in the future.
+ */
+ String getEclipseversion();
+
+ /**
+ * @return a contact URL to get support for this entry
+ */
+ String getSupporturl();
+
+ /**
+ * The URL of an Eclipse update site containing this entry's {@link #getIus() installable units}.
+ */
+ String getUpdateurl();
+
+ /**
+ * The installable units that will be installed for this node.
+ */
+ IIus getIus();
+
+ /**
+ * The supported platforms under which this plug-in node can be installed.
+ */
+ IPlatforms getPlatforms();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IPlatforms.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IPlatforms.java
new file mode 100644
index 00000000..d8f0711a
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/IPlatforms.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IPlatforms {
+
+ List<String> getPlatform();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ISearchResult.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ISearchResult.java
new file mode 100644
index 00000000..123f8906
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ISearchResult.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+
+/**
+ * Search results returned by the marketplace server through the {@link IMarketplaceService}. The actual number of
+ * returned nodes might be less than the number of matches on the server. In that case, the {@link #getMatchCount()
+ * match count} reflects the number of actual matches and the {@link #getNodes() returned results} are a subset of all
+ * matches.
+ *
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ISearchResult {
+
+ /**
+ * The number of matches that matched the query, which may not be equal to the number of nodes returned.
+ */
+ Integer getMatchCount();
+
+ /**
+ * The nodes that were matched by the query
+ */
+ List<? extends INode> getNodes();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITag.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITag.java
new file mode 100644
index 00000000..f547f555
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITag.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+/**
+ * A simple tag that can be associated with nodes to give additional information about related topics.
+ *
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITag extends IIdentifiable {
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITags.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITags.java
new file mode 100644
index 00000000..a966a38f
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/model/ITags.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.model;
+
+import java.util.List;
+
+/**
+ * A list of tags.
+ *
+ * @see ITag
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITags {
+
+ List<? extends ITag> getTags();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ICatalogService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ICatalogService.java
new file mode 100644
index 00000000..e0f02eb2
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ICatalogService.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+
+/**
+ * Entry point to the marketplace API. A catalog service is used to retrieve a list of known catalogs that implement the
+ * <a href="https://wiki.eclipse.org/Marketplace/REST">Marketplace REST API</a>. An instance of this class can be
+ * retrieved through the {@link IMarketplaceServiceLocator} OSGi service.
+ *
+ * @see ICatalog
+ * @see IMarketplaceService
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICatalogService {
+
+ List<? extends ICatalog> listCatalogs(IProgressMonitor monitor) throws CoreException;
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java
new file mode 100644
index 00000000..f0a9a652
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceService.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
+
+/**
+ * A service that provides access to the marketplace and implements the <a
+ * href="https://wiki.eclipse.org/Marketplace/REST">Marketplace REST API</a>.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ * @author David Green
+ * @author Carsten Reckord
+ */
+public interface IMarketplaceService {
+
+ /**
+ * Property key for registered IMarketplaceService OSGi services indicating the marketplace's base URL.
+ */
+ public static final String BASE_URL = "url"; //$NON-NLS-1$
+
+ /**
+ * Get a list of all markets. This is the entrypoint to the marketplace.
+ */
+ List<? extends IMarket> listMarkets(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Get a market by its id
+ *
+ * @param market
+ * the market which must have an {@link IMarket#getUrl() url}.
+ * @return the identified node
+ */
+ IMarket getMarket(IMarket market, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Get a category by its id
+ *
+ * @param category
+ * A category which must have an {@link ICategory#getUrl() url}.
+ * @return the identified category
+ */
+ ICategory getCategory(ICategory category, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Get a node by its id
+ *
+ * @param node
+ * the node which must either have an {@link INode#getUrl() url} or an {@link INode#getId() id}.
+ * @return the identified node
+ */
+ INode getNode(INode node, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Find nodes in the marketplace with a text query, and optionally specify the market/category
+ *
+ * @param market
+ * the market to search in, or null if the search should span all markets
+ * @param category
+ * the category to search in, or null if the search should span all categories
+ * @param queryText
+ * the query text, must not be null
+ * @return the search result
+ */
+ ISearchResult search(IMarket market, ICategory category, String queryText, IProgressMonitor monitor)
+ throws CoreException;
+
+ /**
+ * Find featured nodes in the marketplace
+ *
+ * @return the search result
+ */
+ ISearchResult featured(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Find featured nodes in the marketplace
+ *
+ * @param market
+ * the market in which to return featured, or null if featured should include all markets
+ * @param category
+ * the category in which to return fetured, or null if featured should include all categories
+ * @return the search result
+ */
+ ISearchResult featured(IMarket market, ICategory category, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Find recently added/modified nodes in the marketplace
+ *
+ * @return the search result
+ */
+ ISearchResult recent(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Find most-favorited nodes in the marketplace
+ *
+ * @return the search result
+ */
+ ISearchResult favorites(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Find most active nodes in the marketplace
+ *
+ * @return the search result
+ */
+ ISearchResult popular(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Get the news configuration for the marketplace
+ *
+ * @return the news configuration
+ */
+ INews news(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Report an error in resolving an install operation.
+ *
+ * @param result
+ * the status of the install operation
+ * @param nodes
+ * the nodes that were included in the install, or null if unknown.
+ * @param iuIdsAndVersions
+ * the IUs and their versions (comma-delimited), or null if unknown.
+ * @param resolutionDetails
+ * the detailed error message, or null if unknown.
+ * @param monitor
+ * @noreference This method is not intended to be called by clients directly. It should only ever be called as part
+ * of an install operation.
+ */
+ void reportInstallError(IStatus result, Set<? extends INode> nodes, Set<String> iuIdsAndVersions,
+ String resolutionDetails, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Report a successful install.
+ *
+ * @param node
+ * the installed node
+ * @param monitor
+ * @noreference This method is not intended to be called by clients directly. It should only ever be called as part
+ * of an install operation.
+ */
+ void reportInstallSuccess(INode node, IProgressMonitor monitor);
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceServiceLocator.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceServiceLocator.java
new file mode 100644
index 00000000..b1dbc575
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceServiceLocator.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This service manages instances of {@link IMarketplaceService} and {@link ICatalogService} for accessing marketplace
+ * servers. An instance of this service can be retrieved from the OSGi {@link BundleContext#getServiceReference(Class)
+ * service registry}.
+ * <p>
+ * This service references a single {@link ICatalogService} for catalog {@link #getCatalogService() discovery}. For each
+ * of the discovered catalogs, a {@link IMarketplaceService marketplace service} can be
+ * {@link #getMarketplaceService(String) acquired} using the catalog's {@link ICatalog#getUrl() base url}.
+ * <p>
+ * The default implementation of this service will look for registered {@link ICatalogService} and
+ * {@link IMarketplaceService} instances with matching url paramters in the OSGi service registry and return matching
+ * services. If no match is found, the service locator will create a new instance and return this on subsequent calls.
+ *
+ * @author David Green
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarketplaceServiceLocator {
+
+ /**
+ * Property key for registered IMarketplaceServiceLocator OSGi services indicating the URL of the default
+ * marketplace and catalog service.
+ * <p>
+ * This is a convenience property to use a common value for
+ * {@link IMarketplaceServiceLocator#DEFAULT_MARKETPLACE_URL} and {@link #CATALOG_URL}
+ *
+ * @see #DEFAULT_MARKETPLACE_URL
+ * @see #CATALOG_URL
+ */
+ public static final String DEFAULT_URL = "url"; //$NON-NLS-1$
+
+ /**
+ * Property key for registered IMarketplaceServiceLocator OSGi services indicating the URL of the default
+ * marketplace service.
+ *
+ * @see #DEFAULT_URL
+ * @see #CATALOG_URL
+ */
+ public static final String DEFAULT_MARKETPLACE_URL = "marketplaceUrl"; //$NON-NLS-1$
+
+ /**
+ * Property key for registered IMarketplaceServiceLocator OSGi services indicating the URL of the catalog service.
+ *
+ * @see #DEFAULT_URL
+ * @see #DEFAULT_MARKETPLACE_URL
+ */
+ public static final String CATALOG_URL = "catalogUrl"; //$NON-NLS-1$
+
+ /**
+ * Same as {@link #getMarketplaceService(String) getMarketplaceService(DEFAULT_MARKETPLACE_URL)}
+ *
+ * @return a marketplace service for the {@link #DEFAULT_MARKETPLACE_URL default marketplace url}
+ */
+ IMarketplaceService getDefaultMarketplaceService();
+
+ /**
+ * Get a marketplace service for the given base url. The OSGi registry is searched for a registered instance
+ * matching the url. If none is found, a new instance is created and ued for subsequent calls.
+ */
+ IMarketplaceService getMarketplaceService(String baseUrl);
+
+ /**
+ * Get a catalog service for the default {@link #CATALOG_URL discovery url}.
+ */
+ ICatalogService getCatalogService();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceUnmarshaller.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceUnmarshaller.java
new file mode 100644
index 00000000..beaacc48
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/IMarketplaceUnmarshaller.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * This service provides unmarshalling support for the data returned by the <a
+ * href="https://wiki.eclipse.org/Marketplace/REST">Marketplace REST API</a>.
+ *
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarketplaceUnmarshaller {
+ /**
+ * Parse the input stream into an object of the given type.
+ *
+ * @throws IOException
+ * if an error occurs while reading from the stream
+ * @throws UnmarshalException
+ * if an error occurs while parsing the input, including unexpected content or content that doesn't
+ * match the given type.
+ */
+ public <T> T unmarshal(InputStream in, Class<T> type, IProgressMonitor monitor) throws UnmarshalException,
+ IOException;
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransport.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransport.java
new file mode 100644
index 00000000..5779d310
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransport.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.URI;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * An abstraction for a URI-based download channel. The actual download strategy depends on the implementation.
+ *
+ * @author Carsten Reckord
+ */
+public interface ITransport {
+ public InputStream stream(URI location, IProgressMonitor monitor) throws FileNotFoundException,
+ ServiceUnavailableException, CoreException;
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransportFactory.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransportFactory.java
new file mode 100644
index 00000000..637b13c9
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ITransportFactory.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+/**
+ * Factory to retrieve Transport instances of p2. Will delegate to version-dependent implementations.
+ *
+ * @author David Green
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ */
+public interface ITransportFactory {
+
+ ITransport getTransport();
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/QueryHelper.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/QueryHelper.java
new file mode 100644
index 00000000..8e83e169
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/QueryHelper.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import org.eclipse.epp.internal.mpc.core.service.Category;
+import org.eclipse.epp.internal.mpc.core.service.Identifiable;
+import org.eclipse.epp.internal.mpc.core.service.Market;
+import org.eclipse.epp.internal.mpc.core.service.Node;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+
+/**
+ * Factory for marketplace model instances suitable to use as input for {@link IMarketplaceService} requests.
+ *
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class QueryHelper {
+
+ /**
+ * @return a node instance that can be used to look up a matching node on
+ * the marketplace by id.
+ */
+ public static INode nodeById(String id) {
+ return withId(new Node(), id);
+ }
+
+ /**
+ * @return a node instance that can be used to look up a matching node on
+ * the marketplace by url.
+ */
+ public static INode nodeByUrl(String url) {
+ return withUrl(new Node(), url);
+ }
+
+ /**
+ * @return a category instance that can be used to look up a matching category on
+ * the marketplace by id.
+ */
+ public static ICategory categoryById(String id) {
+ return withId(new Category(), id);
+ }
+
+ /**
+ * @return a category instance that can be used to look up a matching category on
+ * the marketplace by url.
+ */
+ public static ICategory categoryByUrl(String url) {
+ return withUrl(new Category(), url);
+ }
+
+ /**
+ * @return a category instance that can be used to look up a matching category on
+ * the marketplace by name.
+ */
+ public static ICategory categoryByName(String name) {
+ return withName(new Category(), name);
+ }
+
+ /**
+ * @return a market instance that can be used to look up a matching market on
+ * the marketplace by id.
+ */
+ public static IMarket marketById(String id) {
+ return withId(new Market(), id);
+ }
+
+ /**
+ * @return a market instance that can be used to look up a matching market on
+ * the marketplace by url.
+ */
+ public static IMarket marketByUrl(String url) {
+ return withUrl(new Market(), url);
+ }
+
+ /**
+ * @return a market instance that can be used to look up a matching market on
+ * the marketplace by name.
+ */
+ public static IMarket marketByName(String name) {
+ return withName(new Market(), name);
+ }
+
+ private static <T extends Identifiable> T withId(T identifiable, String id) {
+ identifiable.setId(id);
+ return identifiable;
+ }
+
+ private static <T extends Identifiable> T withUrl(T identifiable, String url) {
+ identifiable.setUrl(url);
+ return identifiable;
+ }
+
+ private static <T extends Identifiable> T withName(T identifiable, String name) {
+ identifiable.setName(name);
+ return identifiable;
+ }
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java
new file mode 100644
index 00000000..81701519
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceHelper.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
+
+/**
+ * Convenience class to access marketplace-related OSGi services.
+ *
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public abstract class ServiceHelper {
+
+ private static ServiceHelper getInstance() {
+ return MarketplaceClientCorePlugin.getDefault().getServiceHelper();
+ }
+
+ protected abstract IMarketplaceServiceLocator doGetMarketplaceServiceLocator();
+
+ protected abstract ITransportFactory doGetTransportFactory();
+
+ protected abstract IMarketplaceUnmarshaller doGetMarketplaceUnmarshaller();
+
+ public static IMarketplaceServiceLocator getMarketplaceServiceLocator() {
+ ServiceHelper instance = getInstance();
+ return instance == null ? null : instance.doGetMarketplaceServiceLocator();
+ }
+
+ public static ITransportFactory getTransportFactory() {
+ ServiceHelper instance = getInstance();
+ return instance == null ? null : instance.doGetTransportFactory();
+ }
+
+ public static IMarketplaceUnmarshaller getMarketplaceUnmarshaller() {
+ ServiceHelper instance = getInstance();
+ return instance == null ? null : instance.doGetMarketplaceUnmarshaller();
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceUnavailableException.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceUnavailableException.java
new file mode 100644
index 00000000..a2919fc7
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/ServiceUnavailableException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Indicates that a service is temporarily unavailable, equivalent to HTTP status code 503
+ *
+ * @author David Green
+ */
+@SuppressWarnings("serial")
+public class ServiceUnavailableException extends CoreException {
+
+ public ServiceUnavailableException(IStatus status) {
+ super(status);
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/UnmarshalException.java b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/UnmarshalException.java
new file mode 100644
index 00000000..78696f4a
--- /dev/null
+++ b/org.eclipse.epp.mpc.core/src/org/eclipse/epp/mpc/core/service/UnmarshalException.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.core.service;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+public class UnmarshalException extends CoreException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public UnmarshalException(IStatus status) {
+ super(status);
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.tests/META-INF/MANIFEST.MF b/org.eclipse.epp.mpc.tests/META-INF/MANIFEST.MF
index 05c6d4b6..df9c3e6b 100644
--- a/org.eclipse.epp.mpc.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.epp.mpc.tests/META-INF/MANIFEST.MF
@@ -13,7 +13,14 @@ Require-Bundle: org.eclipse.osgi;bundle-version="3.6.0",
org.eclipse.equinox.p2.repository;bundle-version="2.0.0",
org.eclipse.equinox.p2.core;bundle-version="2.0.0",
org.eclipse.equinox.p2.discovery,
- org.eclipse.jface;bundle-version="3.6.0"
+ org.eclipse.jface;bundle-version="3.6.0",
+ org.eclipse.ui;bundle-version="3.106.0",
+ org.eclipse.swtbot.eclipse.finder;bundle-version="2.2.1",
+ org.eclipse.swtbot.junit4_x;bundle-version="2.2.1",
+ org.apache.log4j;bundle-version="1.2.15",
+ org.eclipse.equinox.p2.ui.discovery;bundle-version="1.0.0",
+ org.hamcrest.library;bundle-version="1.3.0",
+ org.eclipse.core.net;bundle-version="1.2.200"
Import-Package: org.eclipse.ecf.core;version="3.0.0",
org.eclipse.ecf.core.util,
org.eclipse.ecf.filetransfer,
diff --git a/org.eclipse.epp.mpc.tests/pom.xml b/org.eclipse.epp.mpc.tests/pom.xml
index 6d8757b2..e97224d0 100644
--- a/org.eclipse.epp.mpc.tests/pom.xml
+++ b/org.eclipse.epp.mpc.tests/pom.xml
@@ -22,6 +22,7 @@
<artifactId>tycho-surefire-plugin</artifactId>
<configuration>
<useUIHarness>true</useUIHarness>
+ <useUIThread>false</useUIThread>
<forkedProcessTimeoutInSeconds>600</forkedProcessTimeoutInSeconds>
<product>org.eclipse.sdk.ide</product>
<application>org.eclipse.ui.ide.workbench</application>
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/AllTests.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/AllTests.java
index 115b682b..735f4734 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/AllTests.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/AllTests.java
@@ -10,15 +10,6 @@
*******************************************************************************/
package org.eclipse.epp.mpc.tests;
-import org.eclipse.epp.mpc.tests.service.CatalogServiceTest;
-import org.eclipse.epp.mpc.tests.service.DefaultMarketplaceServiceTest;
-import org.eclipse.epp.mpc.tests.service.xml.UnmarshallerTest;
-import org.eclipse.epp.mpc.tests.ui.catalog.CatalogDescriptorTest;
-import org.eclipse.epp.mpc.tests.ui.catalog.MarketplaceInfoTest;
-import org.eclipse.epp.mpc.tests.ui.wizard.MarketplaceUrlHandlerTest;
-import org.eclipse.epp.mpc.tests.ui.wizard.SelectionModelStateSerializerTest;
-import org.eclipse.epp.mpc.tests.util.TextUtilTest;
-import org.eclipse.epp.mpc.tests.util.TransportFactoryTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@@ -28,17 +19,8 @@ import org.junit.runners.Suite.SuiteClasses;
*/
@RunWith(Suite.class)
@SuiteClasses({ //
- UnmarshallerTest.class, //
- DefaultMarketplaceServiceTest.class, //
- TextUtilTest.class, //
- SelectionModelStateSerializerTest.class, //
- MarketplaceUrlHandlerTest.class, //
- TransportFactoryTest.class, //
- MarketplaceInfoTest.class, //
- CatalogServiceTest.class, //
- CatalogDescriptorTest.class //
-
+ UITests.class, //
+ BotTests.class //
})
public class AllTests {
-
}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/BotTests.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/BotTests.java
new file mode 100644
index 00000000..09173c50
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/BotTests.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests;
+
+import org.eclipse.epp.mpc.tests.ui.wizard.MarketplaceClientServiceTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author David Green
+ */
+@RunWith(Suite.class)
+@SuiteClasses({ //
+ MarketplaceClientServiceTest.class
+})
+public class BotTests {
+
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UISuite.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UISuite.java
new file mode 100644
index 00000000..76837aea
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UISuite.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests;
+
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+public class UISuite extends Suite {
+
+ public UISuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
+ super(klass, builder);
+ }
+
+ public UISuite(RunnerBuilder builder, Class<?>[] classes) throws InitializationError {
+ super(builder, classes);
+ }
+
+ void doRun(RunNotifier notifier) {
+ super.run(notifier);
+ }
+
+ @Override
+ public void run(final RunNotifier notifier) {
+ if (!PlatformUI.isWorkbenchRunning()) {
+ notifier.fireTestFailure(new Failure(getDescription(), new IllegalStateException("Workbench not running")));
+ }
+ if (Display.getCurrent() != null) {
+ super.run(notifier);//we are in an UI Thread already
+ } else {
+ final Display display = PlatformUI.getWorkbench().getDisplay();
+ display.syncExec(new Runnable() {
+ public void run() {
+ doRun(notifier);
+ }
+ });
+ }
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UITests.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UITests.java
new file mode 100644
index 00000000..59d35200
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/UITests.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests;
+
+import org.eclipse.epp.mpc.tests.service.CatalogServiceTest;
+import org.eclipse.epp.mpc.tests.service.DefaultMarketplaceServiceTest;
+import org.eclipse.epp.mpc.tests.service.xml.UnmarshallerTest;
+import org.eclipse.epp.mpc.tests.ui.catalog.CatalogDescriptorTest;
+import org.eclipse.epp.mpc.tests.ui.catalog.MarketplaceInfoTest;
+import org.eclipse.epp.mpc.tests.ui.wizard.MarketplaceUrlHandlerTest;
+import org.eclipse.epp.mpc.tests.ui.wizard.SelectionModelStateSerializerTest;
+import org.eclipse.epp.mpc.tests.util.TextUtilTest;
+import org.eclipse.epp.mpc.tests.util.TransportFactoryTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author David Green
+ */
+@RunWith(UISuite.class)
+@SuiteClasses({ //
+ UnmarshallerTest.class, //
+ DefaultMarketplaceServiceTest.class, //
+ TextUtilTest.class, //
+ SelectionModelStateSerializerTest.class, //
+ MarketplaceUrlHandlerTest.class, //
+ TransportFactoryTest.class, //
+ MarketplaceInfoTest.class, //
+ CatalogServiceTest.class, //
+ CatalogDescriptorTest.class //
+
+})
+public class UITests {
+
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/CatalogServiceTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/CatalogServiceTest.java
index 7dd05d1d..a45d2ffd 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/CatalogServiceTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/CatalogServiceTest.java
@@ -7,12 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.service;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import java.util.Collections;
import java.util.List;
@@ -20,14 +19,22 @@ import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
import org.eclipse.epp.internal.mpc.core.ServiceLocator;
import org.eclipse.epp.internal.mpc.core.service.Catalog;
import org.eclipse.epp.internal.mpc.core.service.CatalogService;
+import org.eclipse.epp.internal.mpc.core.util.ServiceUtil;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
/**
* @author Benjamin Muskalla
@@ -43,23 +50,29 @@ public class CatalogServiceTest {
}
}
- private CatalogService catalogService;
+ private ICatalogService catalogService;
- private ServiceLocator serviceLocator;
+ private IMarketplaceServiceLocator serviceLocator;
+
+ private ServiceReference<IMarketplaceServiceLocator> serviceLocatorReference;
+
+ private BundleContext bundleContext;
@Before
public void setUp() throws Exception {
- serviceLocator = ServiceLocator.getInstance();
+ bundleContext = MarketplaceClientCorePlugin.getBundle().getBundleContext();
+ serviceLocatorReference = bundleContext.getServiceReference(IMarketplaceServiceLocator.class);
+ serviceLocator = bundleContext.getService(serviceLocatorReference);
catalogService = serviceLocator.getCatalogService();
}
@Test
public void listCatalogs() throws CoreException {
- List<Catalog> catalogs = catalogService.listCatalogs(new NullProgressMonitor());
+ List<? extends ICatalog> catalogs = catalogService.listCatalogs(new NullProgressMonitor());
assertNotNull(catalogs);
assertFalse(catalogs.isEmpty());
- for (Catalog catalog : catalogs) {
+ for (ICatalog catalog : catalogs) {
assertNotNull(catalog.getId());
assertNotNull(catalog.getUrl());
assertNotNull(catalog.getName());
@@ -68,20 +81,31 @@ public class CatalogServiceTest {
@Test
public void testSampleCatalog() throws Exception {
- ServiceLocator.setInstance(new ServiceLocator() {
- @Override
- public CatalogService getCatalogService() {
- return new MockCatalogService();
- }
- });
- catalogService = ServiceLocator.getInstance().getCatalogService();
- List<Catalog> catalogs = catalogService.listCatalogs(null);
- assertEquals(1, catalogs.size());
- assertEquals("mock", catalogs.get(0).getId());
+ // ServiceLocator oldInstance = ServiceLocator.getInstance();
+ // ServiceLocator.setInstance(new ServiceLocator() {
+ // @Override
+ // public ICatalogService getCatalogService() {
+ // return new MockCatalogService();
+ // }
+ // });
+ ServiceRegistration<ICatalogService> registration = bundleContext.registerService(ICatalogService.class,
+ new MockCatalogService(), ServiceUtil.serviceRanking(Integer.MAX_VALUE, null));
+ try {
+ catalogService = ServiceLocator.getInstance().getCatalogService();
+ List<? extends ICatalog> catalogs = catalogService.listCatalogs(null);
+ assertEquals(1, catalogs.size());
+ assertEquals("mock", catalogs.get(0).getId());
+ } finally {
+ // ServiceLocator.setInstance(oldInstance);
+ registration.unregister();
+ }
}
@After
public void tearDown() {
- ServiceLocator.setInstance(serviceLocator);
+ serviceLocator = null;
+ bundleContext.ungetService(serviceLocatorReference);
+ serviceLocatorReference = null;
+ bundleContext = null;
}
}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/DefaultMarketplaceServiceTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/DefaultMarketplaceServiceTest.java
index dcca279d..cbce24a3 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/DefaultMarketplaceServiceTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/DefaultMarketplaceServiceTest.java
@@ -7,14 +7,12 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
* Yatta Solutions - bug 397004
*******************************************************************************/
package org.eclipse.epp.mpc.tests.service;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.HashSet;
@@ -28,9 +26,11 @@ import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.service.Category;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.core.service.RemoteMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.SearchResult;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,28 +56,27 @@ public class DefaultMarketplaceServiceTest {
@Test
public void listMarkets() throws CoreException {
- List<Market> markets = marketplaceService.listMarkets(new NullProgressMonitor());
+ List<? extends IMarket> markets = marketplaceService.listMarkets(new NullProgressMonitor());
assertNotNull(markets);
assertFalse(markets.isEmpty());
- for (Market market : markets) {
+ for (IMarket market : markets) {
assertNotNull(market.getId());
assertNotNull(market.getUrl());
assertNotNull(market.getName());
}
}
- @SuppressWarnings("null")
@Test
public void getCategory() throws CoreException {
- List<Market> markets = marketplaceService.listMarkets(new NullProgressMonitor());
+ List<? extends IMarket> markets = marketplaceService.listMarkets(new NullProgressMonitor());
assertNotNull(markets);
assertFalse(markets.isEmpty());
final String marketName = "Tools";
- Market market = null;
- for (Market m : markets) {
+ IMarket market = null;
+ for (IMarket m : markets) {
if (marketName.equals(m.getName())) {
market = m;
break;
@@ -89,8 +88,8 @@ public class DefaultMarketplaceServiceTest {
final String categoryName = "Mylyn Connectors";
- Category category = null;
- for (Category c : market.getCategory()) {
+ ICategory category = null;
+ for (ICategory c : market.getCategory()) {
if (categoryName.equals(c.getName())) {
category = c;
break;
@@ -98,7 +97,7 @@ public class DefaultMarketplaceServiceTest {
}
assertNotNull("Expected category " + categoryName, category);
- Category result = marketplaceService.getCategory(category, new NullProgressMonitor());
+ ICategory result = marketplaceService.getCategory(category, new NullProgressMonitor());
assertNotNull(result);
// FIXME: pending bug 302671
@@ -183,22 +182,21 @@ public class DefaultMarketplaceServiceTest {
assertEquals(DefaultMarketplaceService.API_TAXONOMY_URI + "38,31", searchUrl);
}
- @SuppressWarnings("null")
@Test
public void search() throws CoreException {
- List<Market> markets = marketplaceService.listMarkets(new NullProgressMonitor());
+ List<? extends IMarket> markets = marketplaceService.listMarkets(new NullProgressMonitor());
assertTrue(!markets.isEmpty());
- Market toolsMarket = null;
- for (Market market : markets) {
+ IMarket toolsMarket = null;
+ for (IMarket market : markets) {
if ("Tools".equals(market.getName())) {
toolsMarket = market;
break;
}
}
assertNotNull(toolsMarket);
- Category mylynCategory = null;
- for (Category category : toolsMarket.getCategory()) {
+ ICategory mylynCategory = null;
+ for (ICategory category : toolsMarket.getCategory()) {
if ("Mylyn Connectors".equals(category.getName())) {
mylynCategory = category;
break;
@@ -206,14 +204,14 @@ public class DefaultMarketplaceServiceTest {
}
assertNotNull(mylynCategory);
- SearchResult result = marketplaceService.search(toolsMarket, mylynCategory, "WikiText",
+ ISearchResult result = marketplaceService.search(toolsMarket, mylynCategory, "WikiText",
new NullProgressMonitor());
assertNotNull(result);
assertNotNull(result.getNodes());
assertEquals(Integer.valueOf(1), result.getMatchCount());
assertEquals(1, result.getNodes().size());
- Node node = result.getNodes().get(0);
+ INode node = result.getNodes().get(0);
assertTrue(node.getName().startsWith("Mylyn WikiText"));
assertEquals("1065", node.getId());
@@ -221,13 +219,13 @@ public class DefaultMarketplaceServiceTest {
@Test
public void featured() throws CoreException {
- SearchResult result = marketplaceService.featured(new NullProgressMonitor());
+ ISearchResult result = marketplaceService.featured(new NullProgressMonitor());
assertSearchResultSanity(result);
}
@Test
public void favorites() throws CoreException {
- SearchResult result = marketplaceService.favorites(new NullProgressMonitor());
+ ISearchResult result = marketplaceService.favorites(new NullProgressMonitor());
assertSearchResultSanity(result);
}
@@ -235,17 +233,17 @@ public class DefaultMarketplaceServiceTest {
public void popular() throws CoreException {
// NOTE: this test is failing until the following bug is fixed
// bug 303275: REST API popular returns count of 6 with 10 nodes returned
- SearchResult result = marketplaceService.popular(new NullProgressMonitor());
+ ISearchResult result = marketplaceService.popular(new NullProgressMonitor());
assertSearchResultSanity(result);
}
@Test
public void recent() throws CoreException {
- SearchResult result = marketplaceService.recent(new NullProgressMonitor());
+ ISearchResult result = marketplaceService.recent(new NullProgressMonitor());
assertSearchResultSanity(result);
}
- protected void assertSearchResultSanity(SearchResult result) {
+ protected void assertSearchResultSanity(ISearchResult result) {
assertNotNull(result);
assertNotNull(result.getNodes());
assertNotNull(result.getMatchCount());
@@ -253,7 +251,7 @@ public class DefaultMarketplaceServiceTest {
assertTrue(result.getNodes().size() > 0);
Set<String> ids = new HashSet<String>();
- for (Node node : result.getNodes()) {
+ for (INode node : result.getNodes()) {
assertNotNull(node.getId());
assertTrue(ids.add(node.getId()));
assertNotNull(node.getName());
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/ServiceLocatorTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/ServiceLocatorTest.java
new file mode 100644
index 00000000..1d6c4b74
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/ServiceLocatorTest.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests.service;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServiceLocatorTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testGetMarketplaceServiceString() {
+ fail("Not yet implemented");
+ }
+
+ @Test
+ public void testGetCatalogService() {
+ fail("Not yet implemented");
+ }
+
+ @Test
+ public void testGetInstance() {
+ fail("Not yet implemented");
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/xml/UnmarshallerTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/xml/UnmarshallerTest.java
index a5136ece..0bdb9398 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/xml/UnmarshallerTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/service/xml/UnmarshallerTest.java
@@ -7,14 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.service.xml;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
@@ -22,21 +19,22 @@ import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-import org.eclipse.epp.internal.mpc.core.service.Catalog;
-import org.eclipse.epp.internal.mpc.core.service.CatalogBranding;
-import org.eclipse.epp.internal.mpc.core.service.Catalogs;
-import org.eclipse.epp.internal.mpc.core.service.Categories;
-import org.eclipse.epp.internal.mpc.core.service.Category;
import org.eclipse.epp.internal.mpc.core.service.Favorites;
import org.eclipse.epp.internal.mpc.core.service.Featured;
-import org.eclipse.epp.internal.mpc.core.service.Market;
import org.eclipse.epp.internal.mpc.core.service.Marketplace;
import org.eclipse.epp.internal.mpc.core.service.News;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.core.service.Recent;
import org.eclipse.epp.internal.mpc.core.service.Search;
-import org.eclipse.epp.internal.mpc.core.service.Tag;
import org.eclipse.epp.internal.mpc.core.service.xml.Unmarshaller;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.eclipse.epp.mpc.core.model.ICatalogBranding;
+import org.eclipse.epp.mpc.core.model.ICatalogs;
+import org.eclipse.epp.mpc.core.model.ICategories;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ITag;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -77,14 +75,14 @@ public class UnmarshallerTest {
assertEquals(4, marketplace.getMarket().size());
- Market market = marketplace.getMarket().get(0);
+ IMarket market = marketplace.getMarket().get(0);
assertEquals("31", market.getId());
assertEquals("Tools", market.getName());
assertEquals("http://www.eclipseplugincentral.net/category/markets/tools", market.getUrl());
assertEquals(36, market.getCategory().size());
- Category category = market.getCategory().get(10);
+ ICategory category = market.getCategory().get(10);
assertEquals("24", category.getId());
assertEquals("IDE", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/24%2C31", category.getUrl());
@@ -100,14 +98,14 @@ public class UnmarshallerTest {
assertEquals(1, marketplace.getCategory().size());
- Category category = marketplace.getCategory().get(0);
+ ICategory category = marketplace.getCategory().get(0);
assertEquals("38,31", category.getId());
assertEquals("Mylyn Connectors", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/38%2C31", category.getUrl());
assertEquals(9, category.getNode().size());
- Node node = category.getNode().get(0);
+ INode node = category.getNode().get(0);
// <node id="641" name="Tasktop Pro">
// <url>http://www.eclipseplugincentral.net/content/tasktop-pro</url>
// <favorited>3</favorited>
@@ -127,7 +125,7 @@ public class UnmarshallerTest {
assertEquals(1, marketplace.getNode().size());
- Node node = marketplace.getNode().get(0);
+ INode node = marketplace.getNode().get(0);
assertEquals("1065", node.getId());
assertEquals("Mylyn WikiText - Lightweight Markup Editing, Tools and Framework", node.getName());
assertEquals(
@@ -140,7 +138,7 @@ public class UnmarshallerTest {
assertNotNull(node.getCategories());
assertEquals(5, node.getCategories().getCategory().size());
- Category category = node.getCategories().getCategory().get(1);
+ ICategory category = node.getCategories().getCategory().get(1);
// <category name='Tools'>/taxonomy/term/17</category>
assertEquals("Tools", category.getName());
// FIXME category id.
@@ -169,15 +167,15 @@ public class UnmarshallerTest {
assertEquals(Integer.valueOf(6), featured.getCount());
assertEquals(6, featured.getNode().size());
- Node node = featured.getNode().get(0);
+ INode node = featured.getNode().get(0);
assertEquals("248", node.getId());
assertEquals("eUML2 free edition", node.getName());
assertEquals("http://www.eclipseplugincentral.net/content/euml2-free-edition", node.getUrl());
assertEquals("resource", node.getType());
- Categories categories = node.getCategories();
+ ICategories categories = node.getCategories();
assertNotNull(categories);
assertEquals(1, categories.getCategory().size());
- Category category = categories.getCategory().get(0);
+ ICategory category = categories.getCategory().get(0);
assertEquals("19", category.getId());
assertEquals("UML", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/19", category.getUrl());
@@ -215,16 +213,16 @@ public class UnmarshallerTest {
search.getUrl());
assertEquals(Integer.valueOf(62), search.getCount());
assertEquals(7, search.getNode().size());
- Node node = search.getNode().get(0);
+ INode node = search.getNode().get(0);
assertEquals("983", node.getId());
assertEquals("Run All Tests", node.getName());
assertEquals("http://www.eclipseplugincentral.net/content/run-all-tests", node.getUrl());
assertEquals("resource", node.getType());
- Categories categories = node.getCategories();
+ ICategories categories = node.getCategories();
assertNotNull(categories);
assertEquals(1, categories.getCategory().size());
- Category category = categories.getCategory().get(0);
+ ICategory category = categories.getCategory().get(0);
assertEquals("16", category.getId());
assertEquals("Testing", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/16", category.getUrl());
@@ -246,7 +244,7 @@ public class UnmarshallerTest {
assertEquals(Integer.valueOf(299995), node.getInstallsTotal());
assertEquals(Integer.valueOf(34540), node.getInstallsRecent());
- Node lastNode = search.getNode().get(search.getNode().size() - 1);
+ INode lastNode = search.getNode().get(search.getNode().size() - 1);
assertEquals("1011", lastNode.getId());
assertEquals("JUnit Flux", lastNode.getName());
@@ -271,16 +269,16 @@ public class UnmarshallerTest {
assertEquals(6, favorites.getNode().size());
- Node node = favorites.getNode().get(0);
+ INode node = favorites.getNode().get(0);
assertEquals("206", node.getId());
assertEquals("Mylyn", node.getName());
assertEquals("http://www.eclipseplugincentral.net/content/mylyn", node.getUrl());
assertEquals("resource", node.getType());
- Categories categories = node.getCategories();
+ ICategories categories = node.getCategories();
assertNotNull(categories);
assertEquals(1, categories.getCategory().size());
- Category category = categories.getCategory().get(0);
+ ICategory category = categories.getCategory().get(0);
assertEquals("18", category.getId());
assertEquals("UI", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/18", category.getUrl());
@@ -317,17 +315,17 @@ public class UnmarshallerTest {
assertEquals(6, recent.getNode().size());
- Node node = recent.getNode().get(0);
+ INode node = recent.getNode().get(0);
assertEquals("1091", node.getId());
assertEquals("API Demonstration Listing", node.getName());
assertEquals("http://www.eclipseplugincentral.net/content/api-demonstration-listing", node.getUrl());
assertEquals("resource", node.getType());
- Categories categories = node.getCategories();
+ ICategories categories = node.getCategories();
assertNotNull(categories);
assertEquals(6, categories.getCategory().size());
- Category category = categories.getCategory().get(0);
+ ICategory category = categories.getCategory().get(0);
assertEquals("3", category.getId());
assertEquals("Database", category.getName());
assertEquals("http://www.eclipseplugincentral.net/taxonomy/term/3", category.getUrl());
@@ -376,11 +374,11 @@ public class UnmarshallerTest {
public void tags() throws Exception {
Object model = process("resources/node.xml");
Marketplace marketplace = (Marketplace) model;
- Node node = marketplace.getNode().get(0);
+ INode node = marketplace.getNode().get(0);
assertNotNull(node.getTags());
assertEquals(5, node.getCategories().getCategory().size());
- Tag tag = node.getTags().getTags().get(3);
+ ITag tag = node.getTags().getTags().get(3);
assertEquals("mylyn", tag.getName());
assertEquals("88", tag.getId());
assertEquals("http://marketplace.eclipse.org/category/free-tagging/mylyn", tag.getUrl());
@@ -390,8 +388,8 @@ public class UnmarshallerTest {
public void marketplaceCatalogs() throws IOException, SAXException {
Object model = process("resources/catalogs.xml");
assertNotNull(model);
- assertTrue(model instanceof Catalogs);
- Catalogs catalogs = (Catalogs) model;
+ assertTrue(model instanceof ICatalogs);
+ ICatalogs catalogs = (ICatalogs) model;
assertEquals(3, catalogs.getCatalogs().size());
@@ -406,7 +404,7 @@ public class UnmarshallerTest {
// </wizard>
// </catalog>
- Catalog catalog = catalogs.getCatalogs().get(0);
+ ICatalog catalog = catalogs.getCatalogs().get(0);
assertEquals("35656", catalog.getId());
assertEquals("Marketplace Catalog", catalog.getName());
assertEquals("http://marketplace.eclipse.org", catalog.getUrl());
@@ -415,7 +413,7 @@ public class UnmarshallerTest {
assertEquals("http://marketplace.eclipse.org/sites/default/files/marketplace32.png", catalog.getImageUrl());
assertEquals("http://download.eclipse.org/releases/helios", catalog.getDependencyRepository());
- CatalogBranding branding = catalog.getBranding();
+ ICatalogBranding branding = catalog.getBranding();
assertNotNull(branding);
assertEquals("Eclipse Marketplace Catalog", branding.getWizardTitle());
assertEquals("http://marketplace.eclipse.org/sites/default/files/giant-rabbit2.jpg", branding.getWizardIcon());
@@ -426,7 +424,7 @@ public class UnmarshallerTest {
assertFalse(branding.hasPopularTab());
assertTrue(branding.hasRecentTab());
- News news = catalog.getNews();
+ INews news = catalog.getNews();
assertNotNull(news);
assertEquals("http://marketplace.eclipse.org/news", news.getUrl());
assertEquals("News", news.getShortTitle());
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/MarketplaceClientUiTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/MarketplaceClientUiTest.java
index 45860c2c..d08e06b5 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/MarketplaceClientUiTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/MarketplaceClientUiTest.java
@@ -7,11 +7,11 @@
*
* Contributors:
* Yatta Solutions - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.lang.reflect.InvocationTargetException;
import java.net.ConnectException;
@@ -25,12 +25,12 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.ServiceLocator;
-import org.eclipse.epp.internal.mpc.core.service.CatalogService;
import org.eclipse.epp.internal.mpc.core.service.DefaultCatalogService;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.eclipse.osgi.util.NLS;
import org.junit.Test;
@@ -96,7 +96,7 @@ public class MarketplaceClientUiTest {
try {
ServiceLocator.setInstance(new ServiceLocator() {
@Override
- public CatalogService getCatalogService() {
+ public ICatalogService getCatalogService() {
return catalogService;
}
});
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/CatalogDescriptorTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/CatalogDescriptorTest.java
index edad2207..2ece9129 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/CatalogDescriptorTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/CatalogDescriptorTest.java
@@ -7,11 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.catalog;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.net.URL;
@@ -70,6 +70,6 @@ public class CatalogDescriptorTest {
@Test(expected = IllegalArgumentException.class)
public void testCopyCtorNull() {
- new CatalogDescriptor(null);
+ new CatalogDescriptor((CatalogDescriptor) null);
}
}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceCatalogTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceCatalogTest.java
index 5498ea68..9f2a820a 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceCatalogTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceCatalogTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.catalog;
@@ -31,6 +32,8 @@ import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
+import org.eclipse.epp.mpc.core.model.IIus;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.junit.Before;
@@ -38,20 +41,20 @@ import org.junit.Test;
public class MarketplaceCatalogTest {
- protected Set<Node> installedNodes;
+ protected Set<INode> installedNodes;
- protected Set<Node> updateAvailable;
+ protected Set<INode> updateAvailable;
- protected Set<Node> checkedForUpdate;
+ protected Set<INode> checkedForUpdate;
protected List<Node> discoveryNodes;
private MarketplaceCatalog catalog;
@Before
public void setUp() throws Exception {
- installedNodes = new HashSet<Node>();
- updateAvailable = new HashSet<Node>();
- checkedForUpdate = new HashSet<Node>();
+ installedNodes = new HashSet<INode>();
+ updateAvailable = new HashSet<INode>();
+ checkedForUpdate = new HashSet<INode>();
discoveryNodes = new ArrayList<Node>();
setupNodes();
@@ -107,8 +110,8 @@ public class MarketplaceCatalogTest {
@Override
protected Set<String> computeInstalledFeatures(IProgressMonitor monitor) {
Set<String> installedIuIds = new HashSet<String>();
- for (Node node : installedNodes) {
- Ius ius = node.getIus();
+ for (INode node : installedNodes) {
+ IIus ius = node.getIus();
if (ius != null) {
for (String iu : ius.getIu()) {
installedIuIds.add(iu + ".feature.group");
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceInfoTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceInfoTest.java
index 7a22c2c1..a5ccb6c1 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceInfoTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/catalog/MarketplaceInfoTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.catalog;
@@ -23,6 +24,7 @@ import org.eclipse.epp.internal.mpc.core.service.Ius;
import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceInfo;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
+import org.eclipse.epp.mpc.core.model.INode;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -88,7 +90,7 @@ public class MarketplaceInfoTest {
Set<String> installedIus = new HashSet<String>();
installedIus.add("com.foo.bar");
- Set<Node> installedCatalogNodeIds = catalogRegistry.computeInstalledNodes(item.getMarketplaceUrl(),
+ Set<? extends INode> installedCatalogNodeIds = catalogRegistry.computeInstalledNodes(item.getMarketplaceUrl(),
installedIus);
assertNotNull(installedCatalogNodeIds);
assertEquals(0, installedCatalogNodeIds.size());
@@ -138,7 +140,7 @@ public class MarketplaceInfoTest {
@Test
@SuppressWarnings("deprecation")
public void computeInstalledLegacy() throws Exception {
- Node node = item.getData();
+ Node node = (Node) item.getData();
assertTrue(item.getInstallableUnits().size() > 1);
assertEquals(0, catalogRegistry.getNodeKeyToIU().size());
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceClientServiceTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceClientServiceTest.java
new file mode 100644
index 00000000..90da3337
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceClientServiceTest.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests.ui.wizard;
+
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceClientService;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.service.QueryHelper;
+import org.eclipse.epp.mpc.tests.ui.wizard.matcher.NodeMatcher;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientConfiguration;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientService;
+import org.eclipse.epp.mpc.ui.MarketplaceClient;
+import org.eclipse.epp.mpc.ui.Operation;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.ArrayResult;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+import org.eclipse.swtbot.swt.finder.waits.WaitForObjectCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTabItem;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
+import org.eclipse.ui.PlatformUI;
+import org.hamcrest.Matchers;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class MarketplaceClientServiceTest {
+
+ private SWTBot bot;
+
+ private Display display;
+
+ private IMarketplaceClientConfiguration config;
+
+ private MarketplaceClientService service;
+
+ @Before
+ public void setUp() {
+ service = new MarketplaceClientService();
+ config = service.newConfiguration();
+ display = PlatformUI.getWorkbench().getDisplay();
+ }
+
+ protected void initWizardBot() {
+ bot = new SWTBot();
+ bot.waitUntil(Conditions.shellIsActive("Eclipse Marketplace"));
+ bot = bot.shell("Eclipse Marketplace").bot();
+ SWTBotButton cancelButton = bot.button("Cancel");
+ bot.waitUntil(Conditions.widgetIsEnabled(cancelButton), 30000);
+ }
+
+ @After
+ public void tearDownBot() {
+ if (bot != null) {
+ String problem = null;
+ try {
+ //check if dialog is still open
+ SWTBotShell mpcShell = bot.shell("Eclipse Marketplace");
+ try {
+ //check if any message dialogs are open
+ WaitForObjectCondition<Shell> subShellResult = Conditions.waitForShell(Matchers.any(Shell.class),
+ mpcShell.widget);
+ bot.waitUntil(subShellResult, 100, 60);
+ List<Shell> subShells = subShellResult.getAllMatches();
+ for (Shell shell : subShells) {
+ SWTBotShell botShell = new SWTBotShell(shell);
+
+ //children are unexpected, so let's cry foul...
+ if (problem == null) {
+ problem = "MPC wizard has open child dialog:";
+ }
+ problem+="\n Shell(\""+botShell.getText()+"\")";
+
+ //kill message dialog
+ botShell.close();
+ }
+ } catch (TimeoutException ex) {
+ }
+ //try killing it softly
+ try {
+ mpcShell.bot().button("Cancel").click();
+ try {
+ ICondition shellCloses = Conditions.shellCloses(mpcShell);
+ bot.waitUntil(shellCloses);
+ return;
+ } catch (TimeoutException ex) {
+ }
+ } catch (TimeoutException ex) {
+ }
+ //now kill it hard - this is a last resort, because it can cause spurious errors in MPC jobs
+ mpcShell.close();
+ } catch (TimeoutException e) {
+ //no MPC wizard found - maybe a bit strange, but so be it...
+ } finally {
+ if (problem != null) {
+ //something happened
+ fail(problem);
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testClientServiceAvailable() {
+ IMarketplaceClientService marketplaceClientService = MarketplaceClient.getMarketplaceClientService();
+ assertNotNull(marketplaceClientService);
+ }
+
+ @Test
+ public void testOpenDefault() throws Exception {
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.open(config);
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Search");
+ }
+
+ @Test
+ public void testOpenInstalled() throws Exception {
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.openInstalled(config);
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Installed");
+ //We should get a message dialog here. Let's check that and close it.
+ bot.shell("No Extensions Found").close();
+ }
+
+ @Test
+ public void testOpenNodes() throws Exception {
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.open(config, Collections.singleton(QueryHelper.nodeById("206")));
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Search");
+ itemBot("206");
+ }
+
+ @Test
+ public void testOpenSearch() throws Exception {
+ final IMarket toolsMarket = QueryHelper.marketByName("Tools");
+ final ICategory mylynCategory = QueryHelper.categoryByName("Mylyn Connectors");
+
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.openSearch(config, toolsMarket, mylynCategory, "WikiText");
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Search");
+
+ SWTBotCombo marketCombo = bot.comboBox(0);
+ SWTBotCombo categoryCombo = bot.comboBox(1);
+ assertEquals("Tools", marketCombo.getText());
+ assertEquals("Mylyn Connectors", categoryCombo.getText());
+
+ SWTBotText searchText = bot.text(0);
+ assertEquals("WikiText", searchText.getText());
+
+ itemBot(NodeMatcher.withNameRegex(".*WikiText.*"));
+
+ }
+
+ @Test
+ public void testOpenWithSelection() throws Exception {
+ config.setInitialOperations(Collections.singletonMap("206", Operation.INSTALL));
+
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.open(config);
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Search");
+ SWTBot itemBot = itemBot("206");
+ itemBot.button("Install Pending").isEnabled();
+ bot.button("Install Now >").isEnabled();
+ }
+
+ @Test
+ public void testOpenSelected() throws Exception {
+ config.setInitialOperations(Collections.singletonMap("206", Operation.INSTALL));
+
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.openSelected(config);
+ }
+ });
+
+ initWizardBot();
+ checkSelectedTab("Search");
+ SWTBot itemBot = itemBot("206");
+ itemBot.button("Install Pending").isEnabled();
+ bot.button("Install Now >").isEnabled();
+ }
+
+ @Test
+ public void testOpenProvisioning() throws Exception {
+ config.setInitialOperations(Collections.singletonMap("206", Operation.INSTALL));
+
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ service.openProvisioning(config);
+ }
+ });
+
+ initWizardBot();
+
+ //make sure we are on the second page and can proceed
+ bot.label("Confirm Selected Features");
+ bot.button("< Install More").isEnabled();
+ bot.button("Confirm >").isEnabled();
+
+ //make sure we have one top-level item with multiple children
+ SWTBotTreeItem[] nodeItems = bot.tree().getAllItems();
+ assertEquals(1, nodeItems.length);
+ SWTBotTreeItem[] featureItems = nodeItems[0].getItems();
+ assertTrue(featureItems.length > 0);
+ }
+
+ protected SWTBot itemBot(NodeMatcher<? extends Widget> matcher) {
+ List<? extends Widget> controls = bot.getFinder().findControls(matcher);
+ assertThat(controls.size(), greaterThanOrEqualTo(1));
+ Widget firstItem = controls.get(0);
+ return new SWTBot(firstItem);
+ }
+
+ protected SWTBot itemBot(String id) {
+ return itemBot(NodeMatcher.withId(id));
+ }
+
+ protected void checkSelectedTab(String tabLabel) {
+ SWTBotTabItem searchTab = bot.tabItem(tabLabel);
+ final TabItem tab = searchTab.widget;
+ TabItem[] selection = UIThreadRunnable.syncExec(new ArrayResult<TabItem>() {
+
+ public TabItem[] run() {
+ return tab.getParent().getSelection();
+ }
+ });
+ assertEquals(1, selection.length);
+ assertSame(tab, selection[0]);
+ }
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceDiscoveryStrategyTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceDiscoveryStrategyTest.java
index 178379ff..3d535414 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceDiscoveryStrategyTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceDiscoveryStrategyTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.wizard;
@@ -17,15 +18,16 @@ import java.net.URL;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.service.Category;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.MarketplaceService;
import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.core.service.SearchResult;
import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.junit.After;
import org.junit.Assert;
@@ -53,10 +55,10 @@ public class MarketplaceDiscoveryStrategyTest {
catalog = new MarketplaceCatalog();
}
- private void setupCatalog(final MarketplaceService marketplaceService) {
+ private void setupCatalog(final IMarketplaceService marketplaceService) {
discoveryStrategy = new MarketplaceDiscoveryStrategy(catalogDescriptor) {
@Override
- public MarketplaceService createMarketplaceService() {
+ public IMarketplaceService createMarketplaceService() {
return marketplaceService;
}
};
@@ -72,16 +74,16 @@ public class MarketplaceDiscoveryStrategyTest {
@Test
public void testSearchByNodeUrl() throws Exception {
- final Node[] testNode = new Node[1];
- final MarketplaceService marketplaceService = new DefaultMarketplaceService(catalogUrl) {
+ final INode[] testNode = new INode[1];
+ final IMarketplaceService marketplaceService = new DefaultMarketplaceService(catalogUrl) {
@Override
- public Node getNode(Node node, IProgressMonitor monitor) throws CoreException {
+ public Node getNode(INode node, IProgressMonitor monitor) throws CoreException {
testNode[0] = node;
- return node;
+ return (Node) node;
}
@Override
- public SearchResult search(Market market, Category category, String queryText, IProgressMonitor monitor)
+ public SearchResult search(IMarket market, ICategory category, String queryText, IProgressMonitor monitor)
throws CoreException {
Assert.fail("Unexpected invocation");
return null;//dead code
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceUrlHandlerTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceUrlHandlerTest.java
index b34a50f5..a7fd3210 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceUrlHandlerTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/MarketplaceUrlHandlerTest.java
@@ -7,29 +7,26 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.wizard;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.net.URL;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
-import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceUrlHandler;
-import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceUrlHandler.SolutionInstallationInfo;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Test {@link MarketplaceUrlHandler}
- *
+ *
* @author Benjamin Muskalla
*/
public class MarketplaceUrlHandlerTest {
@@ -91,10 +88,10 @@ public class MarketplaceUrlHandlerTest {
@Test
public void testNodeUrls() throws Exception {
- final Node[] testNode = new Node[1];
+ final INode[] testNode = new INode[1];
MarketplaceUrlHandler handler = new MarketplaceUrlHandler() {
@Override
- protected boolean handleNode(CatalogDescriptor descriptor, String url, Node node) {
+ protected boolean handleNode(CatalogDescriptor descriptor, String url, INode node) {
testNode[0] = node;
return true;
}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/SelectionModelStateSerializerTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/SelectionModelStateSerializerTest.java
index 010a80e3..2b267645 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/SelectionModelStateSerializerTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/SelectionModelStateSerializerTest.java
@@ -7,13 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.ui.wizard;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import java.net.URL;
import java.util.Collections;
@@ -24,14 +22,14 @@ import java.util.Set;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.MarketplaceService;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
import org.eclipse.epp.internal.mpc.ui.wizards.InstallProfile;
-import org.eclipse.epp.internal.mpc.ui.wizards.Operation;
import org.eclipse.epp.internal.mpc.ui.wizards.SelectionModel;
import org.eclipse.epp.internal.mpc.ui.wizards.SelectionModelStateSerializer;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.junit.After;
import org.junit.Before;
@@ -54,7 +52,7 @@ public class SelectionModelStateSerializerTest {
"Eclipse.org Marketplace");
discoveryStrategy = new MarketplaceDiscoveryStrategy(catalogDescriptor) {
@Override
- public MarketplaceService createMarketplaceService() {
+ public IMarketplaceService createMarketplaceService() {
DefaultMarketplaceService marketplaceService = new DefaultMarketplaceService(catalogDescriptor.getUrl());
Map<String, String> requestMetaParameters = new HashMap<String, String>();
requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_CLIENT, MarketplaceClientCore.BUNDLE_ID);
@@ -97,15 +95,15 @@ public class SelectionModelStateSerializerTest {
selectionModel.clear();
- assertTrue(selectionModel.getItemToOperation().isEmpty());
+ assertTrue(selectionModel.getItemToSelectedOperation().isEmpty());
assertFalse(selectionModel.computeProvisioningOperationViable());
- serializer.deserialize(new NullProgressMonitor(), state);
+ serializer.deserialize(state, new NullProgressMonitor());
- assertEquals(2, selectionModel.getItemToOperation().size());
+ assertEquals(2, selectionModel.getItemToSelectedOperation().size());
assertTrue(selectionModel.computeProvisioningOperationViable());
- Map<CatalogItem, Operation> itemToOperation = selectionModel.getItemToOperation();
+ Map<CatalogItem, Operation> itemToOperation = selectionModel.getItemToSelectedOperation();
assertEquals(Operation.INSTALL, itemToOperation.get(firstItem));
assertEquals(Operation.INSTALL, itemToOperation.get(secondItem));
}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/matcher/NodeMatcher.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/matcher/NodeMatcher.java
new file mode 100644
index 00000000..ed1767aa
--- /dev/null
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/ui/wizard/matcher/NodeMatcher.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.tests.ui.wizard.matcher;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.matchers.AbstractMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+public class NodeMatcher<T extends Widget> extends AbstractMatcher<T> {
+
+ private final Matcher<INode> matcher;
+
+ NodeMatcher(Matcher<INode> matcher) {
+ this.matcher = matcher;
+ }
+
+ @Override
+ protected boolean doMatch(Object obj) {
+ if (obj instanceof Widget) {
+ Widget w = (Widget) obj;
+ Object data = w.getData();
+ INode node = null;
+ if (data instanceof CatalogItem) {
+ data = ((CatalogItem) data).getData();
+ }
+ if (data instanceof INode) {
+ node = (INode) data;
+ }
+ return node != null && matcher.matches(node);
+ }
+ return false;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("with node matching "); //$NON-NLS-1$
+ matcher.describeTo(description);
+ }
+
+ @Factory
+ public static <T extends Widget> NodeMatcher<T> withNode(Matcher<INode> matcher) {
+ return new NodeMatcher<T>(matcher);
+ }
+
+ @Factory
+ public static <T extends Widget> NodeMatcher<T> withId(String id) {
+ return withNode(new NodeValueMatcher<String>("id", id) {
+
+ @Override
+ protected String getValue(INode item) {
+ return item.getId();
+ }
+ });
+ }
+
+ @Factory
+ public static <T extends Widget> NodeMatcher<T> withUrl(String url) {
+ return withNode(new NodeValueMatcher<String>("url", url) {
+
+ @Override
+ protected String getValue(INode item) {
+ return item.getUrl();
+ }
+ });
+ }
+
+ @Factory
+ public static <T extends Widget> NodeMatcher<T> withName(String name) {
+ return withNode(new NodeValueMatcher<String>("name", name) {
+
+ @Override
+ protected String getValue(INode item) {
+ return item.getName();
+ }
+ });
+ }
+
+ @Factory
+ public static <T extends Widget> NodeMatcher<T> withNameRegex(String name) {
+ return withNode(new NodeValueMatcher<String>("name", name) {
+ private final Pattern pattern = Pattern.compile(expected);
+ @Override
+ protected boolean doMatch(String expected, String actual) {
+ return pattern.matcher(actual).matches();
+ }
+
+ @Override
+ protected String getValue(INode item) {
+ return item.getName();
+ }
+ });
+ }
+
+ private static abstract class NodeValueMatcher<T> extends AbstractMatcher<INode> {
+ final String valueName;
+
+ final T expected;
+
+ public NodeValueMatcher(String valueName, T expected) {
+ super();
+ this.valueName = valueName;
+ this.expected = expected;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText(valueName).appendText(" ");
+ description.appendValue(expected);
+ }
+
+ @Override
+ protected boolean doMatch(Object item) {
+ return item instanceof INode && doMatch(expected, getValue((INode) item));
+ }
+
+ protected boolean doMatch(T expected, T actual) {
+ return expected.equals(actual);
+ }
+
+ protected abstract T getValue(INode item);
+ }
+}
diff --git a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
index 96423ed3..6ddfa122 100644
--- a/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
+++ b/org.eclipse.epp.mpc.tests/src/org/eclipse/epp/mpc/tests/util/TransportFactoryTest.java
@@ -7,33 +7,75 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.tests.util;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
import java.io.InputStream;
import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.util.ITransport;
+import org.eclipse.epp.internal.mpc.core.MarketplaceClientCorePlugin;
import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
+import org.eclipse.epp.mpc.core.service.ITransport;
+import org.eclipse.epp.mpc.core.service.ITransportFactory;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
+import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
@RunWith(BlockJUnit4ClassRunner.class)
public class TransportFactoryTest {
@Test
+ public void testRegisteredFactories() throws Exception {
+ BundleContext context = MarketplaceClientCorePlugin.getBundle().getBundleContext();
+ Collection<ServiceReference<ITransportFactory>> serviceReferences = context.getServiceReferences(
+ ITransportFactory.class, null);
+ assertFalse(serviceReferences.isEmpty());
+ List<Class<?>> registeredFactories;
+ registeredFactories = new ArrayList<Class<?>>();
+ for (ServiceReference<ITransportFactory> serviceReference : serviceReferences) {
+ try {
+ ITransportFactory service = context.getService(serviceReference);
+ assertNotNull(service);
+ registeredFactories.add(service.getClass());
+ } finally {
+ context.ungetService(serviceReference);
+ }
+ }
+
+ List<ITransportFactory> legacyFactories = TransportFactory.listAvailableFactories();
+ for (ITransportFactory factory : legacyFactories) {
+ assertThat(registeredFactories, CoreMatchers.hasItem(factory.getClass()));
+ }
+ }
+
+ @Test
public void testTansportFactoryInstance() {
- ITransport transport = TransportFactory.instance().getTransport();
+ ITransport transport = TransportFactory.createTransport();
+ assertNotNull(transport);
+ }
+
+ @Test
+ @SuppressWarnings("deprecation")
+ public void testLegacyTansportFactoryInstance() {
+ TransportFactory instance = TransportFactory.instance();
+ org.eclipse.epp.internal.mpc.core.util.ITransport transport = instance.getTransport();
assertNotNull(transport);
}
@Test
public void testStream() throws Exception {
- ITransport transport = TransportFactory.instance().getTransport();
+ ITransport transport = ServiceHelper.getTransportFactory().getTransport();
URI uri = new URI("http://www.eclipse.org/index.php");
InputStream stream = transport.stream(uri, new NullProgressMonitor());
assertNotNull(stream);
diff --git a/org.eclipse.epp.mpc.ui/.project b/org.eclipse.epp.mpc.ui/.project
index 85d0cd8a..930dbe31 100644
--- a/org.eclipse.epp.mpc.ui/.project
+++ b/org.eclipse.epp.mpc.ui/.project
@@ -25,6 +25,11 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
diff --git a/org.eclipse.epp.mpc.ui/.settings/.api_filters b/org.eclipse.epp.mpc.ui/.settings/.api_filters
new file mode 100644
index 00000000..55115751
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/.settings/.api_filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.epp.mpc.ui" version="2">
+ <resource path="src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java" type="org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy">
+ <filter comment="Report install error as part of the wizard's install operation" id="640712815">
+ <message_arguments>
+ <message_argument value="IMarketplaceService"/>
+ <message_argument value="MarketplaceDiscoveryStrategy"/>
+ <message_argument value="reportInstallError(IStatus, Set&lt;? extends INode&gt;, Set&lt;String&gt;, String, IProgressMonitor)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java" type="org.eclipse.epp.internal.mpc.ui.wizards.ProvisioningJobListener">
+ <filter comment="report install success as part of the wizard's install operation" id="640712815">
+ <message_arguments>
+ <message_argument value="IMarketplaceService"/>
+ <message_argument value="ProvisioningJobListener"/>
+ <message_argument value="reportInstallSuccess(INode, IProgressMonitor)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.epp.mpc.ui/META-INF/MANIFEST.MF b/org.eclipse.epp.mpc.ui/META-INF/MANIFEST.MF
index 4c1894ad..de142a49 100644
--- a/org.eclipse.epp.mpc.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.epp.mpc.ui/META-INF/MANIFEST.MF
@@ -16,10 +16,12 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.6.0",
org.eclipse.equinox.p2.core;bundle-version="1.0.4",
org.eclipse.equinox.p2.ui;bundle-version="1.0.4",
org.eclipse.equinox.p2.metadata;bundle-version="1.0.0",
- org.eclipse.equinox.p2.operations,
+ org.eclipse.equinox.p2.operations;bundle-version="2.3.0",
org.eclipse.equinox.p2.repository;bundle-version="1.0.0",
org.eclipse.equinox.p2.engine,
- org.eclipse.equinox.p2.director
+ org.eclipse.equinox.p2.director,
+ org.eclipse.osgi.services;bundle-version="3.4.0",
+ org.eclipse.equinox.ds;bundle-version="1.4.200"
Export-Package: org.eclipse.epp.internal.mpc.ui;x-internal:=true,
org.eclipse.epp.internal.mpc.ui.actions;x-internal:=true,
org.eclipse.epp.internal.mpc.ui.catalog;x-internal:=true,
@@ -30,3 +32,4 @@ Export-Package: org.eclipse.epp.internal.mpc.ui;x-internal:=true,
org.eclipse.epp.mpc.ui
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin
+Service-Component: OSGI-INF/services/*.xml
diff --git a/org.eclipse.epp.mpc.ui/OSGI-INF/services/marketplace-client.xml b/org.eclipse.epp.mpc.ui/OSGI-INF/services/marketplace-client.xml
new file mode 100644
index 00000000..232fe0aa
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/OSGI-INF/services/marketplace-client.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.epp.mpc.ui.marketplace-client">
+ <implementation class="org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceClientService"/>
+ <service>
+ <provide interface="org.eclipse.epp.mpc.ui.IMarketplaceClientService"/>
+ </service>
+</scr:component>
diff --git a/org.eclipse.epp.mpc.ui/build.properties b/org.eclipse.epp.mpc.ui/build.properties
index 0baae269..2190a209 100644
--- a/org.eclipse.epp.mpc.ui/build.properties
+++ b/org.eclipse.epp.mpc.ui/build.properties
@@ -7,6 +7,7 @@
#
# Contributors:
# The Eclipse Foundation - initial API and implementation
+# Yatta Solutions - bug 432803: public API
###############################################################################
source.. = src/
output.. = bin/
@@ -19,6 +20,7 @@ bin.includes = META-INF/,\
about.ini,\
about.html,\
OSGI-INF/l10n/,\
+ OSGI-INF/services/,\
.options
src.includes = schema/,\
about.html
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/CatalogRegistry.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/CatalogRegistry.java
index e274c7f4..18ba5c2d 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/CatalogRegistry.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/CatalogRegistry.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui;
@@ -16,8 +17,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
-import org.eclipse.epp.internal.mpc.core.service.CatalogBranding;
-import org.eclipse.epp.internal.mpc.core.service.News;
+import org.eclipse.epp.mpc.core.model.ICatalogBranding;
+import org.eclipse.epp.mpc.core.model.INews;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
/**
@@ -37,9 +38,7 @@ public class CatalogRegistry {
private final List<CatalogDescriptor> catalogDescriptors = new CopyOnWriteArrayList<CatalogDescriptor>();
- private final Map<CatalogDescriptor, CatalogBranding> catalogBrandings = new HashMap<CatalogDescriptor, CatalogBranding>();
-
- private final Map<CatalogDescriptor, News> catalogNews = new HashMap<CatalogDescriptor, News>();
+ private final Map<CatalogDescriptor, INews> catalogNews = new HashMap<CatalogDescriptor, INews>();
public CatalogRegistry() {
catalogDescriptors.addAll(new CatalogExtensionPointReader().getCatalogDescriptors());
@@ -51,7 +50,6 @@ public class CatalogRegistry {
public void unregister(CatalogDescriptor catalogDescriptor) {
catalogDescriptors.remove(catalogDescriptor);
- catalogBrandings.remove(catalogDescriptor);
catalogNews.remove(catalogDescriptor);
}
@@ -59,21 +57,31 @@ public class CatalogRegistry {
return Collections.unmodifiableList(catalogDescriptors);
}
- // TODO: remove and integrate into CatalogDescriptor once we are not in API freeze
- public void addCatalogBranding(CatalogDescriptor descriptor, CatalogBranding branding) {
- catalogBrandings.put(descriptor, branding);
+ /**
+ * @deprecated use {@link CatalogDescriptor#setCatalogBranding(ICatalogBranding)
+ * descriptor.setCatalogBranding(branding)}
+ */
+ @Deprecated
+ public void addCatalogBranding(CatalogDescriptor descriptor, ICatalogBranding branding) {
+ if (descriptor != null) {
+ descriptor.setCatalogBranding(branding);
+ }
}
- public CatalogBranding getCatalogBranding(CatalogDescriptor descriptor) {
- return catalogBrandings.get(descriptor);
+ /**
+ * @deprecated use {@link CatalogDescriptor#getCatalogBranding() descriptor.getCatalogBranding()}
+ */
+ @Deprecated
+ public ICatalogBranding getCatalogBranding(CatalogDescriptor descriptor) {
+ return descriptor == null ? null : descriptor.getCatalogBranding();
}
// manage the predefined news configuration here, since that isn't supposed to become API
- public void addCatalogNews(CatalogDescriptor descriptor, News news) {
+ public void addCatalogNews(CatalogDescriptor descriptor, INews news) {
catalogNews.put(descriptor, news);
}
- public News getCatalogNews(CatalogDescriptor descriptor) {
+ public INews getCatalogNews(CatalogDescriptor descriptor) {
return catalogNews.get(descriptor);
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUi.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUi.java
index d72581c7..2ce30963 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUi.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUi.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - error handling (bug 374105)
+ * Yatta Solutions - error handling (bug 374105), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui;
@@ -19,7 +19,6 @@ import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -154,9 +153,9 @@ public class MarketplaceClientUi {
public static Map<String, IInstallableUnit> computeInstalledIUsById(IProgressMonitor monitor) {
Map<String, IInstallableUnit> iUs = new HashMap<String, IInstallableUnit>();
BundleContext bundleContext = MarketplaceClientUi.getBundleContext();
- ServiceReference serviceReference = bundleContext.getServiceReference(IProvisioningAgent.SERVICE_NAME);
+ ServiceReference<IProvisioningAgent> serviceReference = bundleContext.getServiceReference(IProvisioningAgent.class);
if (serviceReference != null) {
- IProvisioningAgent agent = (IProvisioningAgent) bundleContext.getService(serviceReference);
+ IProvisioningAgent agent = bundleContext.getService(serviceReference);
try {
IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
if (profileRegistry != null) {
@@ -164,8 +163,7 @@ public class MarketplaceClientUi {
if (profile != null) {
IQueryResult<IInstallableUnit> result = profile.available(QueryUtil.createIUGroupQuery(),
monitor);
- for (Iterator<IInstallableUnit> it = result.iterator(); it.hasNext();) {
- IInstallableUnit unit = it.next();
+ for (IInstallableUnit unit : result) {
iUs.put(unit.getId(), unit);
}
}
@@ -181,9 +179,9 @@ public class MarketplaceClientUi {
Set<String> features = new HashSet<String>();
BundleContext bundleContext = MarketplaceClientUi.getBundleContext();
- ServiceReference serviceReference = bundleContext.getServiceReference(IProvisioningAgent.SERVICE_NAME);
+ ServiceReference<IProvisioningAgent> serviceReference = bundleContext.getServiceReference(IProvisioningAgent.class);
if (serviceReference != null) {
- IProvisioningAgent agent = (IProvisioningAgent) bundleContext.getService(serviceReference);
+ IProvisioningAgent agent = bundleContext.getService(serviceReference);
try {
IProfileRegistry profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
if (profileRegistry != null) {
@@ -191,8 +189,7 @@ public class MarketplaceClientUi {
if (profile != null) {
IQueryResult<IInstallableUnit> result = profile.available(QueryUtil.createIUGroupQuery(),
monitor);
- for (Iterator<IInstallableUnit> it = result.iterator(); it.hasNext();) {
- IInstallableUnit unit = it.next();
+ for (IInstallableUnit unit : result) {
features.add(unit.getId());
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUiPlugin.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUiPlugin.java
index 089963db..37c9ccf8 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUiPlugin.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/MarketplaceClientUiPlugin.java
@@ -7,16 +7,19 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientService;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
/**
* bundle activator. Prefer {@link MarketplaceClientUi} where possible.
- *
+ *
* @author David Green
*/
public class MarketplaceClientUiPlugin extends AbstractUIPlugin {
@@ -49,6 +52,8 @@ public class MarketplaceClientUiPlugin extends AbstractUIPlugin {
private static MarketplaceClientUiPlugin instance;
+ private ServiceTracker<IMarketplaceClientService, IMarketplaceClientService> clientServiceTracker;
+
public MarketplaceClientUiPlugin() {
}
@@ -56,10 +61,15 @@ public class MarketplaceClientUiPlugin extends AbstractUIPlugin {
public void start(BundleContext context) throws Exception {
instance = this;
super.start(context);
+ clientServiceTracker = new ServiceTracker<IMarketplaceClientService, IMarketplaceClientService>(context,
+ IMarketplaceClientService.class, null);
+ clientServiceTracker.open();
}
@Override
public void stop(BundleContext context) throws Exception {
+ clientServiceTracker.close();
+ clientServiceTracker = null;
super.stop(context);
instance = null;
}
@@ -87,4 +97,8 @@ public class MarketplaceClientUiPlugin extends AbstractUIPlugin {
imageRegistry.put(ITEM_ICON_SHARE, imageDescriptorFromPlugin(getBundle().getSymbolicName(), "icons/share.png")); //$NON-NLS-1$
return imageRegistry;
}
+
+ public IMarketplaceClientService getClientService() {
+ return clientServiceTracker == null ? null : clientServiceTracker.getService();
+ }
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/AbstractResourceRunnable.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/AbstractResourceRunnable.java
index 2aafe699..0e46c2f3 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/AbstractResourceRunnable.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/AbstractResourceRunnable.java
@@ -29,7 +29,7 @@ import org.eclipse.osgi.util.NLS;
/**
* A runnable that downloads a resource from an URL
- *
+ *
* @author David Green
*/
abstract class AbstractResourceRunnable implements IRunnableWithProgress, Callable<Object> {
@@ -61,7 +61,7 @@ abstract class AbstractResourceRunnable implements IRunnableWithProgress, Callab
try {
URL imageUrl = new URL(resourceUrl);
- InputStream in = TransportFactory.instance().getTransport().stream(imageUrl.toURI(), monitor);
+ InputStream in = TransportFactory.createTransport().stream(imageUrl.toURI(), monitor);
try {
resourceProvider.putResource(resourceUrl, in);
} finally {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalog.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalog.java
index 2687d8a8..2037f12f 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalog.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalog.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - error handling (bug 374105), news (bug 401721)
+ * Yatta Solutions - error handling (bug 374105), news (bug 401721), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
@@ -28,12 +28,12 @@ import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.service.Category;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.News;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.util.ConcurrentTaskManager;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.equinox.internal.p2.discovery.AbstractDiscoveryStrategy;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
@@ -61,13 +61,13 @@ public class MarketplaceCatalog extends Catalog {
private final Map<String, Boolean> updateAvailableByNodeId = new HashMap<String, Boolean>();
- private News news;
+ private INews news;
private interface DiscoveryOperation {
public void run(MarketplaceDiscoveryStrategy strategy, IProgressMonitor monitor) throws CoreException;
}
- public IStatus performQuery(final Market market, final Category category, final String queryText,
+ public IStatus performQuery(final IMarket market, final ICategory category, final String queryText,
IProgressMonitor monitor) {
return performDiscovery(new DiscoveryOperation() {
public void run(MarketplaceDiscoveryStrategy strategy, IProgressMonitor monitor) throws CoreException {
@@ -92,7 +92,7 @@ public class MarketplaceCatalog extends Catalog {
}, monitor);
}
- public IStatus featured(IProgressMonitor monitor, final Market market, final Category category) {
+ public IStatus featured(IProgressMonitor monitor, final IMarket market, final ICategory category) {
return performDiscovery(new DiscoveryOperation() {
public void run(MarketplaceDiscoveryStrategy strategy, IProgressMonitor monitor) throws CoreException {
strategy.featured(monitor, market, category);
@@ -134,7 +134,7 @@ public class MarketplaceCatalog extends Catalog {
* the nodes to retrieve
* @return
*/
- public IStatus performNodeQuery(IProgressMonitor monitor, final Set<Node> nodes) {
+ public IStatus performNodeQuery(IProgressMonitor monitor, final Set<? extends INode> nodes) {
return performDiscovery(new DiscoveryOperation() {
public void run(MarketplaceDiscoveryStrategy strategy, IProgressMonitor monitor) throws CoreException {
strategy.performNodeQuery(monitor, nodes);
@@ -182,7 +182,7 @@ public class MarketplaceCatalog extends Catalog {
Map<URI, List<MarketplaceNodeCatalogItem>> installedCatalogItemsByUpdateUri = new HashMap<URI, List<MarketplaceNodeCatalogItem>>();
for (MarketplaceNodeCatalogItem catalogItem : updateCheckNeeded) {
- Node node = catalogItem.getData();
+ INode node = catalogItem.getData();
try {
String updateurl = node.getUpdateurl();
if (updateurl == null) {
@@ -387,7 +387,7 @@ public class MarketplaceCatalog extends Catalog {
throw new IllegalStateException();
}
- News news = null;
+ INews news = null;
MultiStatus status = new MultiStatus(MarketplaceClientUi.BUNDLE_ID, 0, Messages.MarketplaceCatalog_queryFailed,
null);
@@ -450,11 +450,11 @@ public class MarketplaceCatalog extends Catalog {
}
}
- public News getNews() {
+ public INews getNews() {
return news;
}
- public void setNews(News news) {
+ public void setNews(INews news) {
this.news = news;
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalogSource.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalogSource.java
index 813e90ca..a4a6bec5 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalogSource.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCatalogSource.java
@@ -7,13 +7,14 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
import java.io.IOException;
import java.net.URL;
-import org.eclipse.epp.internal.mpc.core.service.MarketplaceService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
/**
@@ -21,11 +22,11 @@ import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
*/
public class MarketplaceCatalogSource extends AbstractCatalogSource {
- private final MarketplaceService marketplaceService;
+ private final IMarketplaceService marketplaceService;
private ResourceProvider resourceProvider;
- public MarketplaceCatalogSource(MarketplaceService marketplaceService) {
+ public MarketplaceCatalogSource(IMarketplaceService marketplaceService) {
this.marketplaceService = marketplaceService;
try {
resourceProvider = new ResourceProvider();
@@ -48,7 +49,7 @@ public class MarketplaceCatalogSource extends AbstractCatalogSource {
return resourceProvider;
}
- public MarketplaceService getMarketplaceService() {
+ public IMarketplaceService getMarketplaceService() {
return marketplaceService;
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCategory.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCategory.java
index bcda0ce4..6c06c076 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCategory.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceCategory.java
@@ -7,13 +7,14 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
import java.util.List;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.SearchResult;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
/**
@@ -25,17 +26,17 @@ public class MarketplaceCategory extends CatalogCategory {
FEATURED, POPULAR, INSTALLED, RECENT, QUERY
}
- private List<Market> markets;
+ private List<? extends IMarket> markets;
private Contents contents;
private int matchCount;
- public void setMarkets(List<Market> markets) {
+ public void setMarkets(List<? extends IMarket> markets) {
this.markets = markets;
}
- public List<Market> getMarkets() {
+ public List<? extends IMarket> getMarkets() {
return markets;
}
@@ -54,7 +55,7 @@ public class MarketplaceCategory extends CatalogCategory {
/**
* Indicate how many solutions matched the query, which may not be the same as the number of nodes returned.
*
- * @see SearchResult#getMatchCount()
+ * @see ISearchResult#getMatchCount()
*/
public int getMatchCount() {
return matchCount;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
index 2606a542..cc2ff55c 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceDiscoveryStrategy.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - bug 314936, bug 398200
+ * Yatta Solutions - bug 314936, bug 398200, public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
@@ -15,38 +15,39 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
-import org.eclipse.epp.internal.mpc.core.service.CachingMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Categories;
-import org.eclipse.epp.internal.mpc.core.service.Category;
-import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Ius;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.MarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.News;
+import org.eclipse.epp.internal.mpc.core.ServiceLocator;
+import org.eclipse.epp.internal.mpc.core.service.Identifiable;
import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.core.service.SearchResult;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory.Contents;
import org.eclipse.epp.internal.mpc.ui.util.ConcurrentTaskManager;
-import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceUrlHandler;
+import org.eclipse.epp.mpc.core.model.ICategories;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IIdentifiable;
+import org.eclipse.epp.mpc.core.model.IIus;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ISearchResult;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+import org.eclipse.epp.mpc.core.service.IMarketplaceServiceLocator;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler;
import org.eclipse.equinox.internal.p2.discovery.AbstractDiscoveryStrategy;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
@@ -55,7 +56,6 @@ import org.eclipse.equinox.internal.p2.discovery.model.Overview;
import org.eclipse.equinox.internal.p2.discovery.model.Tag;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.osgi.util.NLS;
-import org.osgi.framework.Bundle;
/**
* @author David Green
@@ -68,7 +68,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
protected final CatalogDescriptor catalogDescriptor;
- private final MarketplaceService marketplaceService;
+ private final IMarketplaceService marketplaceService;
private MarketplaceCatalogSource source;
@@ -81,46 +81,30 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
throw new IllegalArgumentException();
}
this.catalogDescriptor = catalogDescriptor;
- marketplaceService = createMarketplaceService();
+ marketplaceService = createMarketplaceService();//use deprecated method in case someone has overridden it
source = new MarketplaceCatalogSource(marketplaceService);
marketplaceInfo = MarketplaceInfo.getInstance();
}
- public MarketplaceService createMarketplaceService() {
- DefaultMarketplaceService service = new DefaultMarketplaceService(this.catalogDescriptor.getUrl());
- Map<String, String> requestMetaParameters = computeDefaultRequestMetaParameters();
- service.setRequestMetaParameters(requestMetaParameters);
- return new CachingMarketplaceService(service);
+ /**
+ * @deprecated get a marketplace service from the registered {@link IMarketplaceServiceLocator} OSGi service instead
+ */
+ @Deprecated
+ public IMarketplaceService createMarketplaceService() {
+ return acquireMarketplaceService();
}
+ protected IMarketplaceService acquireMarketplaceService() {
+ String baseUrl = this.catalogDescriptor.getUrl().toExternalForm();
+ return ServiceLocator.getCompatibilityLocator().getMarketplaceService(baseUrl);
+ }
+
+ /**
+ * @deprecated moved to {@link ServiceLocator#computeDefaultRequestMetaParameters()}
+ */
+ @Deprecated
public static Map<String, String> computeDefaultRequestMetaParameters() {
- Map<String, String> requestMetaParameters = new HashMap<String, String>();
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_CLIENT, MarketplaceClientCore.BUNDLE_ID);
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_OS, Platform.getOS());
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_WS, Platform.getWS());
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_NL, Platform.getNL());
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_JAVA_VERSION, System.getProperty("java.version")); //$NON-NLS-1$
- IProduct product = Platform.getProduct();
- if (product != null) {
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PRODUCT, product.getId());
- Bundle productBundle = product.getDefiningBundle();
- if (productBundle != null) {
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PRODUCT_VERSION,
- productBundle.getVersion().toString());
- }
- }
- Bundle runtimeBundle = Platform.getBundle("org.eclipse.core.runtime"); //$NON-NLS-1$
- if (runtimeBundle != null) {
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_RUNTIME_VERSION, runtimeBundle.getVersion()
- .toString());
- }
- // also send the platform version to distinguish between 3.x and 4.x platforms using the same runtime
- Bundle platformBundle = Platform.getBundle("org.eclipse.platform"); //$NON-NLS-1$
- if (platformBundle != null) {
- requestMetaParameters.put(DefaultMarketplaceService.META_PARAM_PLATFORM_VERSION,
- platformBundle.getVersion().toString());
- }
- return requestMetaParameters;
+ return ServiceLocator.computeDefaultRequestMetaParameters();
}
@Override
@@ -149,7 +133,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
catalogCategory.setContents(Contents.FEATURED);
- SearchResult featured = marketplaceService.featured(new SubProgressMonitor(monitor, workSegment));
+ ISearchResult featured = marketplaceService.featured(new SubProgressMonitor(monitor, workSegment));
handleSearchResult(catalogCategory, featured, new SubProgressMonitor(monitor, workSegment));
maybeAddCatalogItem(catalogCategory);
} finally {
@@ -157,7 +141,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
}
- protected void handleSearchResult(MarketplaceCategory catalogCategory, SearchResult result,
+ protected void handleSearchResult(MarketplaceCategory catalogCategory, ISearchResult result,
final IProgressMonitor monitor) {
if (!result.getNodes().isEmpty()) {
int totalWork = 10000000;
@@ -165,22 +149,22 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
ConcurrentTaskManager executor = new ConcurrentTaskManager(result.getNodes().size(),
Messages.MarketplaceDiscoveryStrategy_loadingResources);
try {
- for (final Node node : result.getNodes()) {
+ for (final INode node : result.getNodes()) {
final MarketplaceNodeCatalogItem catalogItem = new MarketplaceNodeCatalogItem();
catalogItem.setMarketplaceUrl(catalogDescriptor.getUrl());
catalogItem.setId(node.getId());
catalogItem.setName(getCatalogItemName(node));
catalogItem.setCategoryId(catalogCategory.getId());
- Categories categories = node.getCategories();
+ ICategories categories = node.getCategories();
if (categories != null) {
- for (Category category : categories.getCategory()) {
- catalogItem.addTag(new Tag(Category.class, category.getId(), category.getName()));
+ for (ICategory category : categories.getCategory()) {
+ catalogItem.addTag(new Tag(ICategory.class, category.getId(), category.getName()));
}
}
catalogItem.setData(node);
catalogItem.setSource(source);
catalogItem.setLicense(node.getLicense());
- Ius ius = node.getIus();
+ IIus ius = node.getIus();
if (ius != null) {
List<String> discoveryIus = new ArrayList<String>(ius.getIu());
for (int x = 0; x < discoveryIus.size(); ++x) {
@@ -281,7 +265,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
}
- private String getCatalogItemName(Node node) {
+ private String getCatalogItemName(INode node) {
String name = node.getName();
String version = node.getVersion();
return version == null || version.length() == 0 ? name : NLS.bind(
@@ -306,7 +290,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
items.add(catalogItem);
}
- private void createIcon(CatalogItem catalogItem, final Node node) {
+ private void createIcon(CatalogItem catalogItem, final INode node) {
Icon icon = new Icon();
// don't know the size
icon.setImage32(node.getImage());
@@ -315,13 +299,13 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
catalogItem.setIcon(icon);
}
- public void performQuery(Market market, Category category, String queryText, IProgressMonitor monitor)
+ public void performQuery(IMarket market, ICategory category, String queryText, IProgressMonitor monitor)
throws CoreException {
final int totalWork = 1000000;
SubMonitor progress = SubMonitor.convert(monitor, Messages.MarketplaceDiscoveryStrategy_searchingMarketplace,
totalWork);
try {
- SearchResult result;
+ ISearchResult result;
MarketplaceCategory catalogCategory = findMarketplaceCategory(progress.newChild(1));
catalogCategory.setContents(Contents.QUERY);
@@ -335,8 +319,22 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
if (result == null) {
//regular query
+
+ //resolve market and category if necessary
+ IMarket resolvedMarket;
+ ICategory resolvedCategory;
+ try {
+ resolvedMarket = resolve(market, catalogCategory.getMarkets());
+ resolvedCategory = resolveCategory(category, catalogCategory.getMarkets());
+ } catch (IllegalArgumentException ex) {
+ throw new CoreException(MarketplaceClientUi.computeStatus(ex, Messages.MarketplaceDiscoveryStrategy_invalidFilter));
+ } catch (NoSuchElementException ex) {
+ throw new CoreException(MarketplaceClientUi.computeStatus(ex, Messages.MarketplaceDiscoveryStrategy_unknownFilter));
+ }
+
progress.setWorkRemaining(totalWork);
- result = marketplaceService.search(market, category, queryText, progress.newChild(totalWork / 2));
+ result = marketplaceService.search(resolvedMarket, resolvedCategory, queryText,
+ progress.newChild(totalWork / 2));
}
handleSearchResult(catalogCategory, result, progress.newChild(totalWork / 2));
@@ -349,20 +347,68 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
}
- private SearchResult performNodeQuery(String nodeUrl, IProgressMonitor progress) throws CoreException {
- final Node[] queryNode = new Node[1];
+ private ICategory resolveCategory(ICategory category, List<? extends IMarket> markets)
+ throws IllegalArgumentException, NoSuchElementException {
+ if (category != null && category.getId() == null) {
+ //need to resolve
+ if (category.getUrl() == null && category.getName() == null) {
+ throw new IllegalArgumentException(NLS.bind(Messages.MarketplaceDiscoveryStrategy_unidentifiableItem,
+ category));
+ }
+ for (IMarket market : markets) {
+ List<? extends ICategory> categories = market.getCategory();
+ ICategory resolved = resolve(category, categories);
+ if (resolved != null) {
+ return resolved;
+ }
+ }
+ if (category.getUrl() != null) {
+ throw new NoSuchElementException(NLS.bind(Messages.MarketplaceDiscoveryStrategy_noUrlMatch,
+ category.getUrl()));
+ } else {
+ throw new NoSuchElementException(NLS.bind(Messages.MarketplaceDiscoveryStrategy_noNameMatch,
+ category.getName()));
+ }
+ }
+ return category;
+ }
+
+ private <T extends IIdentifiable> T resolve(T id, List<? extends T> candidates) throws IllegalArgumentException,
+ NoSuchElementException {
+ if (id != null && id.getId() == null) {
+ //need to resolve
+ if (id.getUrl() == null && id.getName() == null) {
+ throw new IllegalArgumentException(NLS.bind(
+ Messages.MarketplaceDiscoveryStrategy_unidentifiableItem, id));
+ }
+ for (T candidate : candidates) {
+ if (Identifiable.matches(candidate, id)) {
+ return candidate;
+ }
+ }
+ if (id.getUrl() != null) {
+ throw new NoSuchElementException(NLS.bind(Messages.MarketplaceDiscoveryStrategy_noUrlMatch, id.getUrl()));
+ } else {
+ throw new NoSuchElementException(NLS.bind(Messages.MarketplaceDiscoveryStrategy_noNameMatch, id.getName()));
+ }
+ }
+ return id;
+ }
+
+ private ISearchResult performNodeQuery(String nodeUrl, IProgressMonitor progress) throws CoreException {
+ final INode[] queryNode = new INode[1];
MarketplaceUrlHandler urlHandler = new MarketplaceUrlHandler() {
@Override
- protected boolean handleNode(CatalogDescriptor descriptor, String url, Node node) {
+ protected boolean handleNode(CatalogDescriptor descriptor, String url, INode node) {
queryNode[0] = node;
return true;
}
};
if (urlHandler.handleUri(nodeUrl) && queryNode[0] != null) {
- Node node = marketplaceService.getNode(queryNode[0], progress);
+ INode node = marketplaceService.getNode(queryNode[0], progress);
SearchResult result = new SearchResult();
result.setMatchCount(1);
- result.setNodes(Collections.singletonList(node));
+ result.setNodes(Collections.singletonList((Node) node));
return result;
}
return null;
@@ -374,7 +420,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
try {
MarketplaceCategory catalogCategory = findMarketplaceCategory(new SubProgressMonitor(monitor, 1));
catalogCategory.setContents(Contents.RECENT);
- SearchResult result = marketplaceService.recent(new SubProgressMonitor(monitor, totalWork / 2));
+ ISearchResult result = marketplaceService.recent(new SubProgressMonitor(monitor, totalWork / 2));
handleSearchResult(catalogCategory, result, new SubProgressMonitor(monitor, totalWork / 2));
maybeAddCatalogItem(catalogCategory);
} finally {
@@ -382,14 +428,14 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
}
- public void featured(IProgressMonitor monitor, final Market market, final Category category) throws CoreException {
+ public void featured(IProgressMonitor monitor, final IMarket market, final ICategory category) throws CoreException {
final int totalWork = 1000000;
monitor.beginTask(Messages.MarketplaceDiscoveryStrategy_searchingMarketplace, totalWork);
try {
MarketplaceCategory catalogCategory = findMarketplaceCategory(new SubProgressMonitor(monitor, 1));
catalogCategory.setContents(Contents.FEATURED);
- SearchResult result = marketplaceService.featured(new SubProgressMonitor(monitor, totalWork / 2), market,
- category);
+ ISearchResult result = marketplaceService.featured(market, category,
+ new SubProgressMonitor(monitor, totalWork / 2));
handleSearchResult(catalogCategory, result, new SubProgressMonitor(monitor, totalWork / 2));
maybeAddCatalogItem(catalogCategory);
} finally {
@@ -398,13 +444,12 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
public void popular(IProgressMonitor monitor) throws CoreException {
- // FIXME: do we want popular or favorites?
final int totalWork = 1000000;
monitor.beginTask(Messages.MarketplaceDiscoveryStrategy_searchingMarketplace, totalWork);
try {
MarketplaceCategory catalogCategory = findMarketplaceCategory(new SubProgressMonitor(monitor, 1));
catalogCategory.setContents(Contents.POPULAR);
- SearchResult result = marketplaceService.popular(new SubProgressMonitor(monitor, totalWork / 2));
+ ISearchResult result = marketplaceService.popular(new SubProgressMonitor(monitor, totalWork / 2));
handleSearchResult(catalogCategory, result, new SubProgressMonitor(monitor, totalWork / 2));
maybeAddCatalogItem(catalogCategory);
} finally {
@@ -422,13 +467,13 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
result.setNodes(new ArrayList<Node>());
Set<String> installedFeatures = computeInstalledFeatures(monitor);
if (!monitor.isCanceled()) {
- Set<Node> catalogNodes = marketplaceInfo.computeInstalledNodes(catalogDescriptor.getUrl(),
+ Set<INode> catalogNodes = marketplaceInfo.computeInstalledNodes(catalogDescriptor.getUrl(),
installedFeatures);
if (!catalogNodes.isEmpty()) {
int unitWork = totalWork / (2 * catalogNodes.size());
- for (Node node : catalogNodes) {
+ for (INode node : catalogNodes) {
node = marketplaceService.getNode(node, monitor);
- result.getNodes().add(node);
+ result.getNodes().add((Node) node);
monitor.worked(unitWork);
}
} else {
@@ -442,7 +487,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
public void performQuery(IProgressMonitor monitor, Set<String> nodeIds) throws CoreException {
- Set<Node> nodes = new HashSet<Node>();
+ Set<INode> nodes = new HashSet<INode>();
for (String nodeId : nodeIds) {
Node node = new Node();
node.setId(nodeId);
@@ -451,7 +496,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
performNodeQuery(monitor, nodes);
}
- public void performNodeQuery(IProgressMonitor monitor, Set<Node> nodes) throws CoreException {
+ public void performNodeQuery(IProgressMonitor monitor, Set<? extends INode> nodes) throws CoreException {
final int totalWork = 1000000;
monitor.beginTask(Messages.MarketplaceDiscoveryStrategy_searchingMarketplace, totalWork);
try {
@@ -462,9 +507,9 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
if (!monitor.isCanceled()) {
if (!nodes.isEmpty()) {
int unitWork = totalWork / (2 * nodes.size());
- for (Node node : nodes) {
+ for (INode node : nodes) {
node = marketplaceService.getNode(node, monitor);
- result.getNodes().add(node);
+ result.getNodes().add((Node) node);
monitor.worked(unitWork);
}
} else {
@@ -502,7 +547,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
}
if (catalogCategory == null) {
- List<Market> markets = marketplaceService.listMarkets(new SubProgressMonitor(monitor, 10000));
+ List<? extends IMarket> markets = marketplaceService.listMarkets(new SubProgressMonitor(monitor, 10000));
// marketplace has markets and categories, however a node and/or category can appear in multiple
// markets. This doesn't match well with discovery's concept of a category. Discovery requires all
@@ -522,7 +567,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
return catalogCategory;
}
- public News performNewsDiscovery(IProgressMonitor monitor) throws CoreException {
+ public INews performNewsDiscovery(IProgressMonitor monitor) throws CoreException {
return marketplaceService.news(monitor);
}
@@ -533,7 +578,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
Set<Node> nodes = new HashSet<Node>();
for (CatalogItem item : items) {
Object data = item.getData();
- if (data instanceof Node) {
+ if (data instanceof INode) {
nodes.add((Node) data);
}
}
@@ -543,7 +588,7 @@ public class MarketplaceDiscoveryStrategy extends AbstractDiscoveryStrategy {
String version = iu.getVersion() == null ? null : iu.getVersion().toString();
iuIdsAndVersions.add(id + "," + version); //$NON-NLS-1$
}
- marketplaceService.reportInstallError(monitor, result, nodes, iuIdsAndVersions, resolutionDetails);
+ marketplaceService.reportInstallError(result, nodes, iuIdsAndVersions, resolutionDetails, monitor);
} finally {
monitor.done();
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceInfo.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceInfo.java
index ba30bf40..165581f4 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceInfo.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceInfo.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
@@ -33,6 +34,7 @@ import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
+import org.eclipse.epp.mpc.core.model.INode;
/**
* A means of knowing about how nodes map to IUs and visa versa. Can handle nodes from multiple marketplaces, and does a
@@ -78,8 +80,8 @@ public class MarketplaceInfo {
* all of the currently installed IUs
* @return a set of node ids, or an empty set if there are no known installed nodes
*/
- public synchronized Set<Node> computeInstalledNodes(URL repositoryUrl, Set<String> installedIus) {
- Set<Node> nodes = new HashSet<Node>();
+ public synchronized Set<INode> computeInstalledNodes(URL repositoryUrl, Set<String> installedIus) {
+ Set<INode> nodes = new HashSet<INode>();
String keyPrefix = computeUrlKey(repositoryUrl) + '#';
for (Map.Entry<String, List<String>> entry : nodeKeyToIU.entrySet()) {
@@ -110,7 +112,7 @@ public class MarketplaceInfo {
* @deprecated use {@link #computeInstalled(Set, INode)} instead
*/
@Deprecated
- public boolean computeInstalled(Set<String> installedFeatures, Set<URI> knownRepositories, Node node) {
+ public boolean computeInstalled(Set<String> installedFeatures, Set<URI> knownRepositories, INode node) {
String updateurl = node.getUpdateurl();
if (updateurl == null) {
// don't consider installed if there's no update site
@@ -137,7 +139,7 @@ public class MarketplaceInfo {
* Compute if the given node is installed. The given node must be fully realized, including its
* {@link Node#getIus() ius}.
*/
- public boolean computeInstalled(Set<String> installedFeatures, Node node) {
+ public boolean computeInstalled(Set<String> installedFeatures, INode node) {
if (node.getIus() != null && !node.getIus().getIu().isEmpty()) {
List<String> ius = new ArrayList<String>(new HashSet<String>(node.getIus().getIu()));
return computeInstalled(installedFeatures, ius);
@@ -156,7 +158,7 @@ public class MarketplaceInfo {
return installCount > 0;
}
- public synchronized void map(URL marketUrl, Node node) {
+ public synchronized void map(URL marketUrl, INode node) {
String itemKey = computeItemKey(marketUrl, node);
if (node.getIus() != null && !node.getIus().getIu().isEmpty()) {
List<String> ius = new ArrayList<String>(new HashSet<String>(node.getIus().getIu()));
@@ -189,7 +191,7 @@ public class MarketplaceInfo {
}
}
- private String computeItemKey(URL marketUrl, Node item) {
+ private String computeItemKey(URL marketUrl, INode item) {
return computeUrlKey(marketUrl) + '#' + item.getId();
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceNodeCatalogItem.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceNodeCatalogItem.java
index c41d6046..a29051ad 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceNodeCatalogItem.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/MarketplaceNodeCatalogItem.java
@@ -7,12 +7,16 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.catalog;
import java.net.URL;
+import java.util.EnumSet;
+import java.util.Set;
-import org.eclipse.epp.internal.mpc.core.service.Node;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
/**
@@ -25,8 +29,8 @@ public class MarketplaceNodeCatalogItem extends CatalogItem {
private Boolean updateAvailable;
@Override
- public Node getData() {
- return (Node) super.getData();
+ public INode getData() {
+ return (INode) super.getData();
}
public URL getMarketplaceUrl() {
@@ -45,6 +49,32 @@ public class MarketplaceNodeCatalogItem extends CatalogItem {
this.updateAvailable = updateAvailable;
}
+ public Set<Operation> getAvailableOperations() {
+ Set<Operation> available = EnumSet.noneOf(Operation.class);
+ MarketplaceNodeCatalogItem catalogItem = (MarketplaceNodeCatalogItem) getData();
+ if (!catalogItem.getInstallableUnits().isEmpty()) {
+ if (isInstalled()) {
+ available.add(Operation.UNINSTALL);
+ if (maybeUpdateAvailable()) {
+ available.add(Operation.UPDATE);
+ }
+ } else if (maybeAvailable()) {
+ available.add(Operation.INSTALL);
+ }
+ }
+ return available;
+ }
+
+ private boolean maybeAvailable() {
+ Boolean available = getAvailable();
+ return available == null || Boolean.TRUE.equals(available);
+ }
+
+ private boolean maybeUpdateAvailable() {
+ Boolean updateAvailable = getUpdateAvailable();
+ return updateAvailable == null || Boolean.TRUE.equals(updateAvailable);
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
index 8ea97668..6952d3d6 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/Messages.java
@@ -35,15 +35,25 @@ class Messages extends NLS {
public static String MarketplaceDiscoveryStrategy_findingInstalled;
+ public static String MarketplaceDiscoveryStrategy_invalidFilter;
+
public static String MarketplaceDiscoveryStrategy_loadingMarketplace;
public static String MarketplaceDiscoveryStrategy_loadingResources;
public static String MarketplaceDiscoveryStrategy_Name_and_Version;
+ public static String MarketplaceDiscoveryStrategy_noNameMatch;
+
+ public static String MarketplaceDiscoveryStrategy_noUrlMatch;
+
public static String MarketplaceDiscoveryStrategy_searchingMarketplace;
public static String MarketplaceDiscoveryStrategy_sendingErrorNotification;
+
+ public static String MarketplaceDiscoveryStrategy_unidentifiableItem;
+
+ public static String MarketplaceDiscoveryStrategy_unknownFilter;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
index 918b47cd..c325678a 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/catalog/messages.properties
@@ -18,8 +18,13 @@ MarketplaceCatalog_queryFailed=Query failed to complete
MarketplaceCatalog_queryingMarketplace=Querying marketplace
MarketplaceDiscoveryStrategy_catalogCategory=Catalog category
MarketplaceDiscoveryStrategy_findingInstalled=Finding Installed
+MarketplaceDiscoveryStrategy_invalidFilter=Invalid filter selection
MarketplaceDiscoveryStrategy_loadingMarketplace=Loading marketplace
MarketplaceDiscoveryStrategy_loadingResources=Loading resources
MarketplaceDiscoveryStrategy_Name_and_Version={0} {1}
+MarketplaceDiscoveryStrategy_noNameMatch=No known item found for name '{0}'
+MarketplaceDiscoveryStrategy_noUrlMatch=No known item found for url '{0}'
MarketplaceDiscoveryStrategy_searchingMarketplace=Searching Marketplace
MarketplaceDiscoveryStrategy_sendingErrorNotification=Sending Marketplace error notification
+MarketplaceDiscoveryStrategy_unidentifiableItem=Unidentifiable item {0}: At least one of id, url or name must be set.
+MarketplaceDiscoveryStrategy_unknownFilter=Unknown filter selection
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/commands/MarketplaceWizardCommand.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/commands/MarketplaceWizardCommand.java
index b5a9931f..1c5664fb 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/commands/MarketplaceWizardCommand.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/commands/MarketplaceWizardCommand.java
@@ -8,12 +8,11 @@
* Contributors:
* The Eclipse Foundation - initial API and implementation
* Yatta Solutions - category filtering (bug 314936), error handling (bug 374105),
- * multiselect hints (bug 337774)
+ * multiselect hints (bug 337774), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.commands;
import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -31,11 +30,6 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.epp.internal.mpc.core.ServiceLocator;
-import org.eclipse.epp.internal.mpc.core.service.Catalog;
-import org.eclipse.epp.internal.mpc.core.service.CatalogService;
-import org.eclipse.epp.internal.mpc.core.service.Category;
-import org.eclipse.epp.internal.mpc.core.service.Market;
import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
@@ -45,16 +39,22 @@ import org.eclipse.epp.internal.mpc.ui.wizards.ComboTagFilter;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceCatalogConfiguration;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceFilter;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceWizard;
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceWizard.WizardState;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceWizardDialog;
-import org.eclipse.epp.internal.mpc.ui.wizards.Operation;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientConfiguration;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
import org.eclipse.equinox.internal.p2.discovery.model.Tag;
import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogFilter;
import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.wizard.WizardDialog;
@@ -73,7 +73,9 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
private String wizardState;
- private Map<String, Operation> operationByNodeId;
+ private Map<String, Operation> operations;
+
+ private WizardState wizardDialogState;
public Object execute(ExecutionEvent event) throws ExecutionException {
final MarketplaceCatalog catalog = new MarketplaceCatalog();
@@ -136,8 +138,8 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
for (CatalogCategory category : catalog.getCategories()) {
if (category instanceof MarketplaceCategory) {
MarketplaceCategory marketplaceCategory = (MarketplaceCategory) category;
- for (Market market : marketplaceCategory.getMarkets()) {
- Tag marketTag = new Tag(Market.class, market.getId(), market.getName());
+ for (IMarket market : marketplaceCategory.getMarkets()) {
+ Tag marketTag = new Tag(IMarket.class, market.getId(), market.getName());
marketTag.setData(market);
choices.add(marketTag);
}
@@ -148,7 +150,7 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
};
marketFilter.setSelectAllOnNoSelection(true);
marketFilter.setNoSelectionLabel(Messages.MarketplaceWizardCommand_allMarkets);
- marketFilter.setTagClassification(Category.class);
+ marketFilter.setTagClassification(ICategory.class);
marketFilter.setChoices(new ArrayList<Tag>());
final ComboTagFilter marketCategoryTagFilter = new ComboTagFilter() {
@@ -159,7 +161,7 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
};
marketCategoryTagFilter.setSelectAllOnNoSelection(true);
marketCategoryTagFilter.setNoSelectionLabel(Messages.MarketplaceWizardCommand_allCategories);
- marketCategoryTagFilter.setTagClassification(Category.class);
+ marketCategoryTagFilter.setTagClassification(ICategory.class);
marketCategoryTagFilter.setChoices(new ArrayList<Tag>());
final IPropertyChangeListener marketListener = new IPropertyChangeListener() {
@@ -175,8 +177,8 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
configuration.getFilters().add(marketFilter);
configuration.getFilters().add(marketCategoryTagFilter);
configuration.setInitialState(wizardState);
- if (operationByNodeId != null && !operationByNodeId.isEmpty()) {
- configuration.setInitialOperationByNodeId(operationByNodeId);
+ if (operations != null && !operations.isEmpty()) {
+ configuration.setInitialOperations(operations);
}
for (CatalogFilter filter : configuration.getFilters()) {
@@ -184,7 +186,7 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
}
MarketplaceWizard wizard = new MarketplaceWizard(catalog, configuration);
-
+ wizard.setInitialState(wizardDialogState);
wizard.setWindowTitle(Messages.MarketplaceWizardCommand_eclipseMarketplace);
WizardDialog dialog = new MarketplaceWizardDialog(WorkbenchUtil.getShell(), wizard);
@@ -197,19 +199,19 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
Set<Tag> newChoices = new HashSet<Tag>();
List<Tag> choices = new ArrayList<Tag>();
- Set<Market> selectedMarkets = new HashSet<Market>();
+ Set<IMarket> selectedMarkets = new HashSet<IMarket>();
for (Tag marketTag : marketFilter.getSelected()) {
- selectedMarkets.add((Market) marketTag.getData());
+ selectedMarkets.add((IMarket) marketTag.getData());
}
final MarketplaceCatalog catalog = (MarketplaceCatalog) marketCategoryTagFilter.getCatalog();
for (CatalogCategory category : catalog.getCategories()) {
if (category instanceof MarketplaceCategory) {
MarketplaceCategory marketplaceCategory = (MarketplaceCategory) category;
- for (Market market : marketplaceCategory.getMarkets()) {
+ for (IMarket market : marketplaceCategory.getMarkets()) {
if (selectedMarkets.isEmpty() || selectedMarkets.contains(market)) {
- for (Category marketCategory : market.getCategory()) {
- Tag categoryTag = new Tag(Category.class, marketCategory.getId(), marketCategory.getName());
+ for (ICategory marketCategory : market.getCategory()) {
+ Tag categoryTag = new Tag(ICategory.class, marketCategory.getId(), marketCategory.getName());
categoryTag.setData(marketCategory);
if (newChoices.add(categoryTag)) {
choices.add(categoryTag);
@@ -239,19 +241,39 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
this.wizardState = wizardState;
}
- public void setOperationByNodeId(Map<String, Operation> operationByNodeId) {
- this.operationByNodeId = operationByNodeId;
+ public void setWizardDialogState(WizardState wizardState) {
+ this.wizardDialogState = wizardState;
+ }
+
+ /**
+ * @deprecated use {@link #setOperations(Map)} instead
+ */
+ @Deprecated
+ public void setOperationByNodeId(Map<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> operationByNodeId) {
+ this.operations = org.eclipse.epp.internal.mpc.ui.wizards.Operation.mapAllBack(operationByNodeId);
+ }
+
+ public void setOperations(Map<String, Operation> operationByNodeId) {
+ this.operations = operationByNodeId;
+ }
+
+ public void setConfiguration(IMarketplaceClientConfiguration configuration) {
+ setCatalogDescriptors(configuration.getCatalogDescriptors());
+ setOperations(configuration.getInitialOperations());
+ setWizardState((String) configuration.getInitialState());
+ setSelectedCatalogDescriptor(configuration.getCatalogDescriptor());
}
public IStatus installRemoteCatalogs() {
try {
- final AtomicReference<List<Catalog>> result = new AtomicReference<List<Catalog>>();
+ final AtomicReference<List<? extends ICatalog>> result = new AtomicReference<List<? extends ICatalog>>();
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
- CatalogService catalogService = ServiceLocator.getInstance().getCatalogService();
- final List<Catalog> catalogs = catalogService.listCatalogs(monitor);
+ ICatalogService catalogService = ServiceHelper.getMarketplaceServiceLocator()
+ .getCatalogService();
+ final List<? extends ICatalog> catalogs = catalogService.listCatalogs(monitor);
result.set(catalogs);
} catch (CoreException e) {
throw new InvocationTargetException(e);
@@ -259,22 +281,10 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
}
});
- List<Catalog> catalogs = result.get();
- for (Catalog catalog : catalogs) {
- CatalogDescriptor descriptor = new CatalogDescriptor();
- descriptor.setLabel(catalog.getName());
- descriptor.setUrl(new URL(catalog.getUrl()));
- descriptor.setIcon(ImageDescriptor.createFromURL(new URL(catalog.getImageUrl())));
- descriptor.setDescription(catalog.getDescription());
- descriptor.setInstallFromAllRepositories(!catalog.isSelfContained());
- if (catalog.getDependencyRepository() != null) {
- descriptor.setDependenciesRepository(new URL(catalog.getDependencyRepository()));
- }
+ List<? extends ICatalog> catalogs = result.get();
+ for (ICatalog catalog : catalogs) {
+ CatalogDescriptor descriptor = new CatalogDescriptor(catalog);
registerOrOverrideCatalog(descriptor);
- CatalogRegistry.getInstance().addCatalogBranding(descriptor, catalog.getBranding());
- if (catalog.getNews() != null) {
- CatalogRegistry.getInstance().addCatalogNews(descriptor, catalog.getNews());
- }
}
} catch (InterruptedException ie) {
return Status.CANCEL_STATUS;
@@ -296,5 +306,4 @@ public class MarketplaceWizardCommand extends AbstractHandler implements IHandle
}
catalogRegistry.register(descriptor);
}
-
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/Messages.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/Messages.java
index e5242cc1..a13abcc4 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/Messages.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/Messages.java
@@ -15,6 +15,8 @@ import org.eclipse.osgi.util.NLS;
class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.epp.internal.mpc.ui.operations.messages"; //$NON-NLS-1$
+ public static String ProfileChangeOperationComputer_unknownOperation;
+
public static String ProvisioningOperation_commaSeparator;
public static String ProvisioningOperation_configuringProvisioningOperation;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/ProfileChangeOperationComputer.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/ProfileChangeOperationComputer.java
index 54fda396..20677c28 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/ProfileChangeOperationComputer.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/ProfileChangeOperationComputer.java
@@ -4,10 +4,11 @@
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
* Contributors:
* Tasktop Technologies - initial API and implementation
* JBoss (Pascal Rapicault) - Bug 406907 - Add p2 remediation page to MPC install flow
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.operations;
@@ -51,7 +52,7 @@ import org.eclipse.swt.widgets.Display;
* A job that configures a p2 provisioning operation for installing/updating/removing one or more {@link CatalogItem
* connectors}. The bulk of the installation work is done by p2; this class just sets up the p2 repository meta-data and
* selects the appropriate features to install.
- *
+ *
* @author David Green
* @author Steffen Pingel
*/
@@ -73,7 +74,26 @@ public class ProfileChangeOperationComputer extends AbstractProvisioningOperatio
/**
* uninstall features
*/
- UNINSTALL
+ UNINSTALL;
+
+ public static OperationType map(org.eclipse.epp.mpc.ui.Operation operation) {
+ if (operation == null) {
+ return null;
+ }
+ switch (operation) {
+ case INSTALL:
+ return INSTALL;
+ case UNINSTALL:
+ return UNINSTALL;
+ case UPDATE:
+ return UPDATE;
+ case NONE:
+ return null;
+ default:
+ throw new IllegalArgumentException(NLS.bind(Messages.ProfileChangeOperationComputer_unknownOperation,
+ operation));
+ }
+ }
}
private final OperationType operationType;
@@ -308,7 +328,7 @@ public class ProfileChangeOperationComputer extends AbstractProvisioningOperatio
/**
* Remove ius from the given list where the current profile already contains a newer version of that iu.
- *
+ *
* @param installableUnits
* @throws CoreException
*/
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/messages.properties b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/messages.properties
index 41491f9a..05dacdab 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/messages.properties
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/operations/messages.properties
@@ -8,6 +8,7 @@
# Contributors:
# The Eclipse Foundation - initial API and implementation
###############################################################################
+ProfileChangeOperationComputer_unknownOperation=Unknown operation: {0}
ProvisioningOperation_commaSeparator=,
ProvisioningOperation_configuringProvisioningOperation=Configuring provisioning operation
ProvisioningOperation_nothingToUpdate=There is nothing to update.
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/BrowseCatalogItem.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/BrowseCatalogItem.java
index 86213f18..e0354865 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/BrowseCatalogItem.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/BrowseCatalogItem.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - bug 397004
+ * Yatta Solutions - bug 397004, bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -17,12 +17,12 @@ import java.net.URL;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.epp.internal.mpc.core.service.Category;
import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Market;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceViewer.ContentType;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.AbstractDiscoveryItem;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.DiscoveryResources;
@@ -101,8 +101,8 @@ public class BrowseCatalogItem extends AbstractDiscoveryItem<CatalogDescriptor>
ContentType contentType = viewer.getQueryContentType();
if (contentType == ContentType.SEARCH) {
String queryText = viewer.getQueryText();
- Category queryCategory = viewer.getQueryCategory();
- Market queryMarket = viewer.getQueryMarket();
+ ICategory queryCategory = viewer.getQueryCategory();
+ IMarket queryMarket = viewer.getQueryMarket();
String path = new DefaultMarketplaceService(url).computeRelativeSearchUrl(queryMarket,
queryCategory, queryText, false);
if (path != null) {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/DiscoveryItem.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/DiscoveryItem.java
index 8fb8cb3d..982581fa 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/DiscoveryItem.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/DiscoveryItem.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -15,13 +16,14 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.MessageFormat;
-import org.eclipse.epp.internal.mpc.core.service.Node;
-import org.eclipse.epp.internal.mpc.core.service.Tag;
-import org.eclipse.epp.internal.mpc.core.service.Tags;
import org.eclipse.epp.internal.mpc.core.util.TextUtil;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
import org.eclipse.epp.internal.mpc.ui.util.Util;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.model.ITag;
+import org.eclipse.epp.mpc.core.model.ITags;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.discovery.model.Overview;
@@ -324,7 +326,7 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
hookLinkListener(installInfoLink, new LinkListener() {
@Override
protected void selected(String href) {
- browser.openUrl(((Node) connector.getData()).getUrl());
+ browser.openUrl(((INode) connector.getData()).getUrl());
}
});
GridDataFactory.swtDefaults().align(SWT.TRAIL, SWT.CENTER).grab(false, true).applyTo(installInfoLink);
@@ -348,8 +350,8 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
Integer installsTotal = null;
Integer installsRecent = null;
- if (connector.getData() instanceof Node) {
- Node node = (Node) connector.getData();
+ if (connector.getData() instanceof INode) {
+ INode node = (INode) connector.getData();
installsTotal = node.getInstallsTotal();
installsRecent = node.getInstallsRecent();
}
@@ -374,16 +376,16 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
installInfo.append(installInfoText.substring(formatTotalsStart + totalText.length()));
}
} else {
- if (shareSolutionLink != null) {
- shareSolutionLink.setShowText(true);
- }
+ if (shareSolutionLink != null) {
+ shareSolutionLink.setShowText(true);
+ }
}
}
private void createSocialButtons(Composite parent) {
Integer favorited = null;
- if (connector.getData() instanceof Node) {
- Node node = (Node) connector.getData();
+ if (connector.getData() instanceof INode) {
+ INode node = (INode) connector.getData();
favorited = node.getFavorited();
}
if (favorited == null || getCatalogItemUrl() == null) {
@@ -407,7 +409,7 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
Label spacer = new Label(this, SWT.NONE);
spacer.setText(" ");//$NON-NLS-1$
GridDataFactory.fillDefaults().indent(0, BUTTONBAR_MARGIN_TOP).align(SWT.CENTER, SWT.FILL).applyTo(spacer);
- }
+ }
}
private void createRatingsButton(Composite parent, Integer favoritedCount) {
@@ -477,8 +479,8 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
private String getCatalogItemUrl() {
Object data = connector.getData();
- if (data instanceof Node) {
- Node node = (Node) data;
+ if (data instanceof INode) {
+ INode node = (INode) data;
return node.getUrl();
}
return null;
@@ -622,11 +624,11 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
.grab(true, false)
.applyTo(tagsLink);
- Tags tags = ((Node) connector.getData()).getTags();
+ ITags tags = ((INode) connector.getData()).getTags();
if (tags == null) {
return;
}
- for (Tag tag : tags.getTags()) {
+ for (ITag tag : tags.getTags()) {
String tagName = tag.getName();
appendLink(tagsLink, tagName, SWT.NORMAL).data = tagName;
tagsLink.append(" "); //$NON-NLS-1$
@@ -649,6 +651,14 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
&& connector.getOverview().getSummary().length() > 0;
}
+ /**
+ * @deprecated use {@link #maybeModifySelection(Operation)}
+ */
+ @Deprecated
+ protected boolean maybeModifySelection(org.eclipse.epp.internal.mpc.ui.wizards.Operation operation) {
+ return maybeModifySelection(operation.getOperation());
+ }
+
protected boolean maybeModifySelection(Operation operation) {
viewer.modifySelection(connector, operation);
return true;
@@ -659,8 +669,16 @@ public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<
return getData().isSelected();
}
- public Operation getOperation() {
- return viewer.getSelectionModel().getOperation(getData());
+ /**
+ * @deprecated use {@link #getSelectedOperation()} instead
+ */
+ @Deprecated
+ public org.eclipse.epp.internal.mpc.ui.wizards.Operation getOperation() {
+ return org.eclipse.epp.internal.mpc.ui.wizards.Operation.map(getSelectedOperation());
+ }
+
+ public Operation getSelectedOperation() {
+ return viewer.getSelectionModel().getSelectedOperation(getData());
}
public void propertyChange(PropertyChangeEvent evt) {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/FeatureSelectionWizardPage.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/FeatureSelectionWizardPage.java
index ae51247c..48473028 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/FeatureSelectionWizardPage.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/FeatureSelectionWizardPage.java
@@ -8,6 +8,7 @@
* Contributors:
* The Eclipse Foundation - initial API and implementation
* JBoss (Pascal Rapicault) - Bug 406907 - Add p2 remediation page to MPC install flow
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -82,8 +83,8 @@ public class FeatureSelectionWizardPage extends WizardPage {
public Image getImage(Object element) {
if (element instanceof FeatureEntry) {
FeatureEntry entry = (FeatureEntry) element;
- switch (entry.getParent().getOperation()) {
- case CHECK_FOR_UPDATES:
+ switch (entry.getParent().getSelectedOperation()) {
+ case UPDATE:
if (entry.isInstalled()) {
return MarketplaceClientUiPlugin.getInstance()
.getImageRegistry()
@@ -294,7 +295,7 @@ public class FeatureSelectionWizardPage extends WizardPage {
private void updateFeatures() {
viewer.setInput(getWizard().getSelectionModel());
ResolveFeatureNamesOperation operation = new ResolveFeatureNamesOperation(new ArrayList<CatalogItem>(
- getWizard().getSelectionModel().getItemToOperation().keySet())) {
+ getWizard().getSelectionModel().getItemToSelectedOperation().keySet())) {
Display display = getControl().getDisplay();
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/IDiscoveryItemFactory.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/IDiscoveryItemFactory.java
new file mode 100644
index 00000000..9756158b
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/IDiscoveryItemFactory.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.ui.wizards;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.DiscoveryResources;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.widgets.Composite;
+
+public interface IDiscoveryItemFactory {
+ public <T extends CatalogItem> DiscoveryItem<T> createDiscoveryItem(T connector, MarketplaceViewer viewer,
+ Composite parent, DiscoveryResources resources, IShellProvider shellProvider, IMarketplaceWebBrowser browser);
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ItemButtonController.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ItemButtonController.java
index 00beb479..5faa2971 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ItemButtonController.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ItemButtonController.java
@@ -7,10 +7,12 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
@@ -18,7 +20,7 @@ import org.eclipse.swt.widgets.Button;
/**
* A controller that controls the multi-state install/uninstall button
- *
+ *
* @author David Green
*/
@SuppressWarnings("rawtypes")
@@ -31,7 +33,7 @@ class ItemButtonController {
DISABLED(Messages.ItemButtonController_install, Operation.NONE, true), //
UPDATE_DISABLED(Messages.ItemButtonController_update, Operation.NONE, true), //
UPDATE(Messages.ItemButtonController_update, Operation.NONE, false), //
- UPDATE_PENDING(Messages.ItemButtonController_updatePending, Operation.CHECK_FOR_UPDATES, false);
+ UPDATE_PENDING(Messages.ItemButtonController_updatePending, Operation.UPDATE, false);
final String label;
@@ -137,11 +139,11 @@ class ItemButtonController {
buttonState = ButtonState.DISABLED;
secondaryButtonState = ButtonState.DISABLED;
} else {
- Operation operation = item.getOperation();
+ Operation operation = item.getSelectedOperation();
boolean installed = isItemInstalled();
if (installed) {
switch (operation) {
- case CHECK_FOR_UPDATES:
+ case UPDATE:
buttonState = ButtonState.UPDATE_PENDING;
secondaryButtonState = ButtonState.UNINSTALL;
break;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceBrowserIntegration.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceBrowserIntegration.java
index 3adcdde8..35229a66 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceBrowserIntegration.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceBrowserIntegration.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - error handling (bug 374105), news (bug 401721)
+ * Yatta Solutions - error handling (bug 374105), news (bug 401721), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -19,7 +19,7 @@ import org.eclipse.swt.browser.WindowEvent;
/**
* Browser integration for the marketplace that intercepts calls to install buttons and causes them to open the
* marketplace wizard.
- *
+ *
* @author dgreen
* @author Carsten Reckord
*/
@@ -41,7 +41,7 @@ OpenWindowListener {
@Override
protected boolean handleInstallRequest(SolutionInstallationInfo installInfo, String url) {
- MarketplaceUrlHandler.triggerInstall(installInfo);
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.triggerInstall(installInfo);
return true;
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceCatalogConfiguration.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceCatalogConfiguration.java
index d8c6f072..72022a28 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceCatalogConfiguration.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceCatalogConfiguration.java
@@ -7,27 +7,33 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientConfiguration;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogConfiguration;
+import org.eclipse.osgi.util.NLS;
/**
* @author David Green
*/
-public class MarketplaceCatalogConfiguration extends CatalogConfiguration {
+public class MarketplaceCatalogConfiguration extends CatalogConfiguration implements IMarketplaceClientConfiguration {
private List<CatalogDescriptor> catalogDescriptors = new ArrayList<CatalogDescriptor>();
private CatalogDescriptor catalogDescriptor;
private String initialState;
- private Map<String, Operation> initialOperationByNodeId;
+ private Map<String, Operation> initialOperations;
public MarketplaceCatalogConfiguration() {
setShowTagFilter(false);
@@ -37,6 +43,14 @@ public class MarketplaceCatalogConfiguration extends CatalogConfiguration {
setShowCategories(false);
}
+ public MarketplaceCatalogConfiguration(IMarketplaceClientConfiguration configuration) {
+ this();
+ setCatalogDescriptors(configuration.getCatalogDescriptors());
+ setCatalogDescriptor(configuration.getCatalogDescriptor());
+ setInitialState(configuration.getInitialState());
+ setInitialOperations(configuration.getInitialOperations());
+ }
+
public List<CatalogDescriptor> getCatalogDescriptors() {
return catalogDescriptors;
}
@@ -53,6 +67,16 @@ public class MarketplaceCatalogConfiguration extends CatalogConfiguration {
this.catalogDescriptor = catalogDescriptor;
}
+ public void setInitialState(Object state) {
+ if (state == null || state instanceof String) {
+ String stateString = (String) state;
+ setInitialState(stateString);
+ } else {
+ throw new IllegalArgumentException(NLS.bind(Messages.MarketplaceCatalogConfiguration_invalidStateObject,
+ state));
+ }
+ }
+
public void setInitialState(String initialState) {
this.initialState = initialState;
}
@@ -61,12 +85,29 @@ public class MarketplaceCatalogConfiguration extends CatalogConfiguration {
return initialState;
}
- public Map<String, Operation> getInitialOperationByNodeId() {
- return initialOperationByNodeId;
+ public Map<String, Operation> getInitialOperations() {
+ return initialOperations == null ? null : Collections.unmodifiableMap(initialOperations);
}
- public void setInitialOperationByNodeId(Map<String, Operation> initialOperationByNodeId) {
- this.initialOperationByNodeId = initialOperationByNodeId;
+ public void setInitialOperations(Map<String, Operation> initialOperations) {
+ this.initialOperations = new LinkedHashMap<String, Operation>(initialOperations);
}
+ /**
+ * @deprecated use {@link #getInitialOperations()} instead
+ */
+ @Deprecated
+ public Map<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> getInitialOperationByNodeId() {
+ Map<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> map = org.eclipse.epp.internal.mpc.ui.wizards.Operation.mapAll(initialOperations);
+ return map == null ? null : Collections.unmodifiableMap(map);
+ }
+
+ /**
+ * @deprecated use {@link #setInitialOperations(Map)} instead
+ */
+ @Deprecated
+ public void setInitialOperationByNodeId(
+ Map<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> initialOperationByNodeId) {
+ this.initialOperations = org.eclipse.epp.internal.mpc.ui.wizards.Operation.mapAllBack(initialOperationByNodeId);
+ }
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceClientService.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceClientService.java
new file mode 100644
index 00000000..e9779fb8
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceClientService.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2010 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.internal.mpc.ui.wizards;
+
+import java.util.Set;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceViewer.ContentType;
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceWizard.WizardState;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientConfiguration;
+import org.eclipse.epp.mpc.ui.IMarketplaceClientService;
+
+public class MarketplaceClientService implements IMarketplaceClientService {
+
+ public IMarketplaceClientConfiguration newConfiguration() {
+ return new MarketplaceCatalogConfiguration();
+ }
+
+ public void open(IMarketplaceClientConfiguration configuration) {
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ public void openSelected(IMarketplaceClientConfiguration configuration) {
+ checkInitialState(configuration);
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setContentType(ContentType.SELECTION);
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ public void openInstalled(IMarketplaceClientConfiguration configuration) {
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setContentType(ContentType.INSTALLED);
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ public void openSearch(IMarketplaceClientConfiguration configuration, IMarket market, ICategory category,
+ String query) {
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setContentType(ContentType.SEARCH);
+ wizardState.setFilterMarket(market);
+ wizardState.setFilterCategory(category);
+ wizardState.setFilterQuery(query);
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ public void open(IMarketplaceClientConfiguration configuration, Set<INode> nodes) {
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setContent(nodes);
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ public void openProvisioning(IMarketplaceClientConfiguration configuration) {
+ checkInitialState(configuration);
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setConfiguration(configuration);
+ WizardState wizardState = new WizardState();
+ wizardState.setProceedWithInstallation(true);
+ command.setWizardDialogState(wizardState);
+ execute(command);
+ }
+
+ private void checkInitialState(IMarketplaceClientConfiguration configuration) {
+ if (configuration.getInitialState() == null
+ && (configuration.getInitialOperations() == null || configuration.getInitialOperations().isEmpty())) {
+ throw new IllegalArgumentException(Messages.MarketplaceClientService_noProvisioningOperation);
+ }
+ }
+
+ private void execute(MarketplaceWizardCommand command) {
+ try {
+ command.execute(new ExecutionEvent());
+ } catch (ExecutionException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceDropAdapter.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceDropAdapter.java
index 0c777893..f09eff31 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceDropAdapter.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceDropAdapter.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -14,7 +15,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceUrlHandler.SolutionInstallationInfo;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplacePage.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplacePage.java
index 83c55a8d..7f8bf433 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplacePage.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplacePage.java
@@ -7,8 +7,8 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - news (bug 401721)
- * JBoss (Pascal Rapicault) - Bug 406907 - Add p2 remediation page to MPC install flow
+ * Yatta Solutions - news (bug 401721), public API (bug 432803)
+ * JBoss (Pascal Rapicault) - Bug 406907 - Add p2 remediation page to MPC install flow
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -19,16 +19,18 @@ import java.util.Set;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.service.CatalogBranding;
-import org.eclipse.epp.internal.mpc.core.service.Category;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.News;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.util.Util;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceViewer.ContentType;
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceWizard.WizardState;
+import org.eclipse.epp.mpc.core.model.ICatalogBranding;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryImages;
import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogPage;
@@ -176,7 +178,7 @@ public class MarketplacePage extends CatalogPage {
return;
}
SelectionModel selectionModel = getWizard().getSelectionModel();
- int newSelectionSize = selectionModel.getItemToOperation().size();
+ int newSelectionSize = selectionModel.getItemToSelectedOperation().size();
// important: we don't do anything if the selection is empty, since CatalogViewer
// sets the empty selection whenever the catalog is updated.
@@ -214,7 +216,7 @@ public class MarketplacePage extends CatalogPage {
return;
}
if (tab == newsTabItem) {
- final News news = getNews();
+ final INews news = getNews();
boolean wasUpdated = newsViewer.isUpdated(news);
newsViewer.showNews(news);
if (wasUpdated) {
@@ -229,6 +231,14 @@ public class MarketplacePage extends CatalogPage {
}
return;
}
+ ContentType currentContentType = getViewer().getContentType();
+ if (currentContentType != null) {
+ TabItem tabItem = getTabItem(currentContentType);
+ if (tabItem == tab) {
+ setActiveTab(currentContentType);
+ return;
+ }
+ }
for (ContentType contentType : ContentType.values()) {
if (getTabItem(contentType) == tab) {
setActiveTab(contentType);
@@ -292,7 +302,7 @@ public class MarketplacePage extends CatalogPage {
newsTabItem = new TabItem(tabFolder, SWT.NULL | SWT.BOLD);
newsTabItem.setText(Messages.MarketplacePage_DefaultNewsTitle);
- News news = getNews();
+ INews news = getNews();
if (news == null) {
newsTabItem.dispose();
return;
@@ -318,7 +328,7 @@ public class MarketplacePage extends CatalogPage {
}
private void updateNewsStatus() {
- News news = getNews();
+ INews news = getNews();
Image tabImage = null;
if (news != null && newsViewer.isUpdated(news)) {
@@ -330,9 +340,9 @@ public class MarketplacePage extends CatalogPage {
newsTabItem.getParent().layout();
}
- private News getNews() {
+ private INews getNews() {
CatalogDescriptor descriptor = configuration.getCatalogDescriptor();
- News news = CatalogRegistry.getInstance().getCatalogNews(descriptor);
+ INews news = CatalogRegistry.getInstance().getCatalogNews(descriptor);
return news;
}
@@ -371,7 +381,7 @@ public class MarketplacePage extends CatalogPage {
final String originalText = selectionLink.getText();
String text = " "; //$NON-NLS-1$
- int count = getWizard().getSelectionModel().getItemToOperation().size();
+ int count = getWizard().getSelectionModel().getItemToSelectedOperation().size();
if (count == 1) {
text = Messages.MarketplacePage_linkShowSelection_One;
} else if (count > 0) {
@@ -491,11 +501,16 @@ public class MarketplacePage extends CatalogPage {
disableTabSelection = true;
updateTitle();
CatalogDescriptor descriptor = configuration.getCatalogDescriptor();
- CatalogBranding branding = CatalogRegistry.getInstance().getCatalogBranding(descriptor);
+ ICatalogBranding branding = descriptor == null ? null : descriptor.getCatalogBranding();
if (branding == null) {
branding = getDefaultBranding();
}
+ TabItem selectedTabItem = null;
+ int selectionIndex = tabFolder.getSelectionIndex();
+ if (selectionIndex != -1) {
+ selectedTabItem = tabFolder.getItem(selectionIndex);
+ }
newsTabItem.dispose();
searchTabItem.dispose();
recentTabItem.dispose();
@@ -504,26 +519,53 @@ public class MarketplacePage extends CatalogPage {
boolean hasSearchTab = branding.hasSearchTab();
if (hasSearchTab) {
+ boolean isSelected = (selectedTabItem == searchTabItem);
createSearchTab();
searchTabItem.setText(branding.getSearchTabName());
+ if (isSelected) {
+ selectedTabItem = searchTabItem;
+ }
}
boolean hasRecentTab = branding.hasRecentTab();
if (hasRecentTab) {
+ boolean isSelected = (selectedTabItem == recentTabItem);
createRecentTab();
recentTabItem.setText(branding.getRecentTabName());
+ if (isSelected) {
+ selectedTabItem = recentTabItem;
+ }
}
boolean hasPopularTab = branding.hasPopularTab();
if (hasPopularTab) {
+ boolean isSelected = (selectedTabItem == popularTabItem);
createPopularTab();
popularTabItem.setText(branding.getPopularTabName());
+ if (isSelected) {
+ selectedTabItem = popularTabItem;
+ }
}
- createInstalledTab();
+ {
+ boolean isSelected = (selectedTabItem == installedTabItem);
+ createInstalledTab();
+ if (isSelected) {
+ selectedTabItem = installedTabItem;
+ }
+ }
- createNewsTab();
+ {
+ boolean isSelected = (selectedTabItem == newsTabItem);
+ createNewsTab();
+ if (isSelected) {
+ selectedTabItem = newsTabItem;
+ }
+ }
+ if (selectedTabItem == null || selectedTabItem.isDisposed()) {
+ selectedTabItem = tabFolder.getItem(0);
+ }
- tabFolder.setSelection(searchTabItem);
+ tabFolder.setSelection(selectedTabItem);
try {
ImageDescriptor wizardIconDescriptor;
@@ -539,7 +581,7 @@ public class MarketplacePage extends CatalogPage {
disableTabSelection = false;
}
- private CatalogBranding getDefaultBranding() {
+ private ICatalogBranding getDefaultBranding() {
CatalogBranding branding = new CatalogBranding();
branding.setHasSearchTab(true);
branding.setHasPopularTab(true);
@@ -583,6 +625,16 @@ public class MarketplacePage extends CatalogPage {
updateBranding();
}
+ public void showNews(CatalogDescriptor catalogDescriptor) {
+ IStatus proceed = Status.OK_STATUS;
+ if (catalogDescriptor != null) {
+ proceed = showMarketplace(catalogDescriptor);
+ }
+ if (proceed.isOK()) {
+ setActiveTab(newsTabItem);
+ }
+ }
+
public void show(CatalogDescriptor catalogDescriptor, MarketplaceViewer.ContentType content) {
IStatus proceed = Status.OK_STATUS;
if (catalogDescriptor != null) {
@@ -593,7 +645,7 @@ public class MarketplacePage extends CatalogPage {
}
}
- public void show(CatalogDescriptor catalogDescriptor, final Set<Node> nodes) {
+ public void show(CatalogDescriptor catalogDescriptor, final Set<? extends INode> nodes) {
IStatus proceed = Status.OK_STATUS;
if (catalogDescriptor != null) {
proceed = showMarketplace(catalogDescriptor);
@@ -604,7 +656,7 @@ public class MarketplacePage extends CatalogPage {
}
}
- public void search(CatalogDescriptor catalogDescriptor, final Market searchMarket, final Category searchCategory,
+ public void search(CatalogDescriptor catalogDescriptor, final IMarket searchMarket, final ICategory searchCategory,
final String searchString) {
IStatus proceed = Status.OK_STATUS;
if (catalogDescriptor != null) {
@@ -616,6 +668,22 @@ public class MarketplacePage extends CatalogPage {
}
}
+ protected void initialize(WizardState initialState) {
+ ContentType contentType = initialState.getContentType();
+ if (contentType != null && contentType != ContentType.SEARCH) {
+ show(configuration.getCatalogDescriptor(), contentType);
+ } else if (initialState.getContent() != null && !initialState.getContent().isEmpty()) {
+ show(configuration.getCatalogDescriptor(), initialState.getContent());
+ } else {
+ IMarket market = initialState.getFilterMarket();
+ ICategory category = initialState.getFilterCategory();
+ String query = initialState.getFilterQuery();
+ if (market != null || category != null || query != null) {
+ search(configuration.getCatalogDescriptor(), market, category, query);
+ }
+ }
+ }
+
@Override
public void dispose() {
if (marketplaceSwitcher != null) {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceUrlHandler.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceUrlHandler.java
index 8dfd7d40..b7f62dac 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceUrlHandler.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceUrlHandler.java
@@ -7,382 +7,59 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
- * Yatta Solutions - news (bug 401721)
+ * Yatta Solutions - news (bug 401721), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Node;
-import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
-import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
-import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
-import org.eclipse.ui.statushandlers.StatusManager;
/**
* @author David Green
* @author Benjamin Muskalla
* @author Carsten Reckord
+ * @deprecated use {@link org.eclipse.epp.mpc.ui.MarketplaceUrlHandler} instead
*/
-public abstract class MarketplaceUrlHandler {
-
- public static final String DESCRIPTOR_HINT = "org.eclipse.epp.mpc.descriptorHint"; //$NON-NLS-1$
-
- public static final String MPC_INSTALL_URI = "/mpc/install?"; //$NON-NLS-1$
-
- public static final String SITE_SEARCH_URI = "/search/site"; //$NON-NLS-1$
-
- private static final Pattern CONTENT_URL_PATTERN = Pattern.compile("(?:^|/)content/([^/#?]+)"); //$NON-NLS-1$
-
- private static final Pattern NODE_URL_PATTERN = Pattern.compile("(?:^|/)node/([^/#?]+)"); //$NON-NLS-1$
+@Deprecated
+public abstract class MarketplaceUrlHandler extends org.eclipse.epp.mpc.ui.MarketplaceUrlHandler {
- public static class SolutionInstallationInfo {
- private String installId;
+ /**
+ * @deprecated use {@link org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo} instead
+ */
+ @Deprecated
+ public static class SolutionInstallationInfo extends
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo {
- private String state;
-
- private CatalogDescriptor catalogDescriptor;
-
- public String getInstallId() {
- return installId;
+ public SolutionInstallationInfo() {
+ super();
}
- public String getState() {
- return state;
- }
-
- public CatalogDescriptor getCatalogDescriptor() {
- return catalogDescriptor;
+ protected SolutionInstallationInfo(String installId, String state, CatalogDescriptor catalogDescriptor) {
+ super(installId, state, catalogDescriptor);
}
}
- protected static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
-
- private static final String PARAM_SPLIT_REGEX = "&"; //$NON-NLS-1$
-
- private static final String EQUALS_REGEX = "="; //$NON-NLS-1$
-
- private static final String MPC_STATE = "mpc_state"; //$NON-NLS-1$
-
- private static final String MPC_INSTALL = "mpc_install"; //$NON-NLS-1$
-
public static SolutionInstallationInfo createSolutionInstallInfo(String url) {
- String query;
- try {
- query = new URL(url).getQuery();
- } catch (MalformedURLException e) {
- return null;
- }
- if (query == null) {
- return null;
- }
- String[] params = query.split(PARAM_SPLIT_REGEX);
- String installId = null;
- String state = null;
- for (String param : params) {
- String[] keyValue = param.split(EQUALS_REGEX);
- if(keyValue.length == 2) {
- String key = keyValue[0];
- String value = keyValue[1];
- if (key.equals(MPC_INSTALL)) {
- installId = value;
- } else if (key.equals(MPC_STATE)) {
- state = value;
- }
- }
- }
- if (installId != null) {
- CatalogDescriptor descriptor = CatalogRegistry.getInstance().findCatalogDescriptor(url);
- SolutionInstallationInfo info = new SolutionInstallationInfo();
- info.installId = installId;
- info.state = state;
- if (descriptor != null) {
- info.catalogDescriptor = descriptor;
- } else {
- try {
- info.catalogDescriptor = new CatalogDescriptor(new URL(url), DESCRIPTOR_HINT);
- } catch (MalformedURLException e) {
- return null;
- }
- }
- return info;
- }
- return null;
- }
-
- public static boolean isPotentialSolution(String url) {
- return url != null && url.contains(MPC_INSTALL);
- }
-
- public static void triggerInstall(SolutionInstallationInfo info) {
- String installId = info.getInstallId();
- String mpcState = info.getState();
- CatalogDescriptor catalogDescriptor = info.getCatalogDescriptor();
- MarketplaceWizardCommand command = new MarketplaceWizardCommand();
- command.setSelectedCatalogDescriptor(catalogDescriptor);
- try {
- if (mpcState != null) {
- command.setWizardState(URLDecoder.decode(mpcState, UTF_8));
- }
- Map<String, Operation> nodeIdToOperation = new HashMap<String, Operation>();
- nodeIdToOperation.put(URLDecoder.decode(installId, UTF_8), Operation.INSTALL);
- command.setOperationByNodeId(nodeIdToOperation);
- } catch (UnsupportedEncodingException e1) {
- throw new IllegalStateException(e1);
- }
- try {
- command.execute(new ExecutionEvent());
- } catch (ExecutionException e) {
- IStatus status = MarketplaceClientUi.computeStatus(e,
- Messages.MarketplaceBrowserIntegration_cannotOpenMarketplaceWizard);
- StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
- }
- }
-
- public boolean handleUri(String uri) {
- if (isPotentialSolution(uri)) {
- SolutionInstallationInfo installInfo = createSolutionInstallInfo(uri);
- if (installInfo != null) {
- return handleInstallRequest(installInfo, uri);
- }
- }
-
- CatalogDescriptor descriptor = CatalogRegistry.getInstance().findCatalogDescriptor(uri);
- if (descriptor == null) {
- descriptor = handleUnknownCatalog(uri);
- if (descriptor == null) {
- return false;
- }
- }
-
- String baseUri;
- try {
- baseUri = descriptor.getUrl().toURI().toString();
- if (!baseUri.endsWith("/")) { //$NON-NLS-1$
- baseUri += '/';
- }
- } catch (URISyntaxException e) {
- // should be unreachable
- throw new IllegalStateException(e);
- }
-
- if (!uri.startsWith(baseUri)) {
- uri = resolve(uri, baseUri, descriptor);
- if (!uri.startsWith(baseUri)) {
- return false;
- }
- }
- String relativeUri = uri.substring(baseUri.length());
- if (relativeUri.startsWith(DefaultMarketplaceService.API_FAVORITES_URI)) {
- return handleFavorites(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_FEATURED_URI)) {
- return handleFeatured(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_NODE_CONTENT_URI)) {
- return handleNodeContent(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_NODE_URI)) {
- return handleNode(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_POPULAR_URI)) {
- return handlePopular(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_RECENT_URI)) {
- return handleRecent(descriptor, relativeUri);
- } else if (relativeUri.startsWith(DefaultMarketplaceService.API_SEARCH_URI)
- || relativeUri.startsWith(DefaultMarketplaceService.API_SEARCH_URI_FULL)) {
- return handleSolrSearch(descriptor, relativeUri);
- } else if (relativeUri.startsWith(SITE_SEARCH_URI.substring(1))) {
- return handleSiteSearch(descriptor, relativeUri);
- } else {
- return handleUnknownPath(descriptor, relativeUri);
- }
- }
-
- protected String resolve(String url, String baseUri, CatalogDescriptor descriptor) {
- if (url.startsWith("https:") && baseUri.startsWith("http:")) { //$NON-NLS-1$ //$NON-NLS-2$
- url = "http:" + url.substring("https:".length()); //$NON-NLS-1$ //$NON-NLS-2$
- } else if (url.startsWith("http:") && baseUri.startsWith("https:")) { //$NON-NLS-1$ //$NON-NLS-2$
- url = "https:" + url.substring("http:".length()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return url;
- }
-
- protected boolean handleUnknownPath(CatalogDescriptor descriptor, String url) {
- return false;
- }
-
- private boolean handleSolrSearch(CatalogDescriptor descriptor, String url) {
- try {
- Map<String, String> params = new HashMap<String, String>();
- String searchString = parseSearchQuery(descriptor, url, params);
- return handleSearch(descriptor, url, searchString, params);
- } catch (MalformedURLException e) {
- // don't handle malformed URLs
- return false;
- } catch (URISyntaxException e) {
- // don't handle malformed URLs
- return false;
- }
- }
-
- private boolean handleSiteSearch(CatalogDescriptor descriptor, String url) {
- try {
- Map<String, String> params = new HashMap<String, String>();
- String searchString = parseSearchQuery(descriptor, url, params);
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo solutionInstallInfo = org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.createSolutionInstallInfo(url);
- // convert queries of this format
- // f[0]=im_taxonomy_vocabulary_1:38&f[1]=im_taxonomy_vocabulary_3:31
- // to internal solr format
- // filter=tid:38 tid:31
- StringBuilder filter = new StringBuilder();
- for (Iterator<String> i = params.values().iterator(); i.hasNext();) {
- String str = i.next();
- if (str.startsWith("im_taxonomy_vocabulary_")) { //$NON-NLS-1$
- int sep = str.indexOf(':');
- if (sep != -1) {
- String tid = str.substring(sep + 1);
- if (filter.length() > 0) {
- filter.append(' ');
- }
- filter.append(tid);
- i.remove();
- }
- }
- }
- return handleSearch(descriptor, url, searchString, params);
- } catch (MalformedURLException e) {
- // don't handle malformed URLs
- return false;
- } catch (URISyntaxException e) {
- // don't handle malformed URLs
- return false;
- }
+ return wrap(solutionInstallInfo);
}
- private String parseSearchQuery(CatalogDescriptor descriptor, String url, Map<String, String> params)
- throws URISyntaxException, MalformedURLException {
- URI searchUri = new URL(descriptor.getUrl(), url).toURI();
- String path = searchUri.getPath();
- if (path.endsWith("/")) { //$NON-NLS-1$
- path = path.substring(0, path.length() - 1);
- }
- int sep = path.lastIndexOf('/');
- String searchString = path.substring(sep + 1);
- String query = searchUri.getQuery();
- if (query != null) {
- extractParams(query, params);
- }
- return searchString;
- }
-
- protected boolean handleSearch(CatalogDescriptor descriptor, String url, String searchString,
- Map<String, String> params) {
- return false;
+ private static SolutionInstallationInfo wrap(
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo solutionInstallInfo) {
+ return new SolutionInstallationInfo(solutionInstallInfo.getInstallId(), solutionInstallInfo.getState(),
+ solutionInstallInfo.getCatalogDescriptor());
}
- private void extractParams(String query, Map<String, String> params) {
- final String[] paramStrings = query.split("&"); //$NON-NLS-1$
- for (String param : paramStrings) {
- final String[] parts = param.split("="); //$NON-NLS-1$
- if (parts.length == 2) {
- params.put(parts[0], parts[1]);
- }
- }
- }
-
- protected boolean handleRecent(CatalogDescriptor descriptor, String url) {
- return false;
- }
-
- protected boolean handlePopular(CatalogDescriptor descriptor, String url) {
- return false;
- }
-
- private boolean handleNode(CatalogDescriptor descriptor, String url) {
- Matcher matcher = NODE_URL_PATTERN.matcher(url);
- String id = null;
- if (matcher.find()) {
- id = matcher.group(1);
- }
- Node node = new Node();
- node.setId(id);
- return handleNode(descriptor, url, node);
- }
-
- private boolean handleNodeContent(CatalogDescriptor descriptor, String url) {
- Matcher matcher = CONTENT_URL_PATTERN.matcher(url);
- String title = null;
- if (matcher.find()) {
- title = matcher.group(1);
- }
- Node node = new Node();
- node.setUrl(url);
- if (title != null) {
- String base = descriptor.getUrl().toExternalForm();
- if (!base.endsWith("/")) { //$NON-NLS-1$
- base += "/"; //$NON-NLS-1$
- }
- int titleEnd = matcher.end();
- if (titleEnd > -1) {
- //clean the url of other query parameters
- node.setUrl(base + url.substring(0, titleEnd));
- } else {
- //unknown format, leave as-is
- node.setUrl(base + url);
- }
- }
- return handleNode(descriptor, url, node);
- }
-
- protected boolean handleNode(CatalogDescriptor descriptor, String url, Node node) {
- return false;
- }
-
- private boolean handleFeatured(CatalogDescriptor descriptor, String url) {
- Matcher matcher = Pattern.compile("(?:^|/)featured/(\\d+)(?:,(\\d+))?").matcher(url); //$NON-NLS-1$
- String cat = null;
- String market = null;
- if (matcher.find()) {
- cat = matcher.group(1);
- if (matcher.groupCount() > 1) {
- market = matcher.group(2);
- }
- }
- return handleFeatured(descriptor, url, cat, market);
- }
-
- protected boolean handleFeatured(CatalogDescriptor descriptor, String url, String category, String market) {
- return false;
- }
-
- protected boolean handleFavorites(CatalogDescriptor descriptor, String url) {
+ protected boolean handleInstallRequest(SolutionInstallationInfo installInfo, String url) {
return false;
}
- protected CatalogDescriptor handleUnknownCatalog(String url) {
- if (url.startsWith("https:")) { //$NON-NLS-1$
- url = "http:" + url.substring("https:".length()); //$NON-NLS-1$ //$NON-NLS-2$
- return CatalogRegistry.getInstance().findCatalogDescriptor(url);
- } else if (url.startsWith("http:")) { //$NON-NLS-1$
- url = "https:" + url.substring("http:".length()); //$NON-NLS-1$ //$NON-NLS-2$
- return CatalogRegistry.getInstance().findCatalogDescriptor(url);
+ @Override
+ protected boolean handleInstallRequest(
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo installInfo, String url) {
+ if (installInfo instanceof SolutionInstallationInfo) {
+ return handleInstallRequest((SolutionInstallationInfo) installInfo, url);
}
- return null;
- }
-
- protected boolean handleInstallRequest(SolutionInstallationInfo installInfo, String url) {
- return false;
+ return handleInstallRequest(wrap(installInfo), url);
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceViewer.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceViewer.java
index ba0fc28b..c407a20f 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceViewer.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceViewer.java
@@ -8,7 +8,7 @@
* Contributors:
* The Eclipse Foundation - initial API and implementation
* Yatta Solutions - error handling (bug 374105), header layout (bug 341014),
- * news (bug 401721)
+ * news (bug 401721), public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -26,15 +26,18 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.epp.internal.mpc.core.service.Category;
import org.eclipse.epp.internal.mpc.core.service.Identifiable;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
+import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory.Contents;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IIdentifiable;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
@@ -58,6 +61,8 @@ import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
@@ -65,6 +70,8 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.statushandlers.StatusManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
/**
* @author Steffen Pingel
@@ -117,9 +124,9 @@ public class MarketplaceViewer extends CatalogViewer {
private String queryText;
- private Market queryMarket;
+ private IMarket queryMarket;
- private Category queryCategory;
+ private ICategory queryCategory;
private ContentType queryContentType;
@@ -131,6 +138,8 @@ public class MarketplaceViewer extends CatalogViewer {
private final List<IPropertyChangeListener> listeners = new LinkedList<IPropertyChangeListener>();
+ private IDiscoveryItemFactory discoveryItemFactory;
+
public MarketplaceViewer(Catalog catalog, IShellProvider shellProvider, MarketplaceWizard wizard) {
super(catalog, shellProvider, wizard.getContainer(), wizard.getConfiguration());
this.browser = wizard;
@@ -184,6 +193,7 @@ public class MarketplaceViewer extends CatalogViewer {
((MarketplaceFilter) filter).catalogUpdated(wasCancelled);
}
}
+ setFilters(queryMarket, queryCategory, queryText);
}
@Override
@@ -197,7 +207,6 @@ public class MarketplaceViewer extends CatalogViewer {
doQuery();
}
- @SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected ControlListItem<?> doCreateViewerItem(Composite parent, Object element) {
if (element instanceof CatalogItem) {
@@ -207,8 +216,7 @@ public class MarketplaceViewer extends CatalogViewer {
return new BrowseCatalogItem(parent, getResources(), shellProvider, browser,
(MarketplaceCategory) catalogItem.getCategory(), catalogDescriptor, this);
} else {
- DiscoveryItem discoveryItem = new DiscoveryItem(parent, SWT.NONE, getResources(), shellProvider,
- browser, catalogItem, this);
+ DiscoveryItem<CatalogItem> discoveryItem = createDiscoveryItem(parent, catalogItem);
discoveryItem.setSelected(getCheckedItems().contains(catalogItem));
return discoveryItem;
}
@@ -227,7 +235,16 @@ public class MarketplaceViewer extends CatalogViewer {
return super.doCreateViewerItem(parent, element);
}
- public void show(Set<Node> nodes) {
+ private DiscoveryItem<CatalogItem> createDiscoveryItem(Composite parent, CatalogItem catalogItem) {
+ if (discoveryItemFactory != null) {
+ return discoveryItemFactory.createDiscoveryItem(catalogItem, this, parent, getResources(), shellProvider,
+ browser);
+ }
+ return new DiscoveryItem<CatalogItem>(parent, SWT.NONE, getResources(), shellProvider, browser, catalogItem,
+ this);
+ }
+
+ public void show(Set<? extends INode> nodes) {
ContentType newContentType = ContentType.SEARCH;
ContentType oldContentType = contentType;
contentType = newContentType;
@@ -236,7 +253,7 @@ public class MarketplaceViewer extends CatalogViewer {
doQuery(null, null, null, nodes);
}
- public void search(Market market, Category category, String query) {
+ public void search(IMarket market, ICategory category, String query) {
ContentType newContentType = ContentType.SEARCH;
ContentType oldContentType = contentType;
contentType = newContentType;
@@ -250,19 +267,19 @@ public class MarketplaceViewer extends CatalogViewer {
doQuery(market, category, query, null);
}
- private void setFilters(Market market, Category category, String query) {
- setFindText(query);
+ private void setFilters(IMarket market, ICategory category, String query) {
+ setFindText(query == null ? "" : query); //$NON-NLS-1$
for (CatalogFilter filter : getConfiguration().getFilters()) {
if (filter instanceof AbstractTagFilter) {
AbstractTagFilter tagFilter = (AbstractTagFilter) filter;
- if (tagFilter.getTagClassification() == Category.class) {
+ if (tagFilter.getTagClassification() == ICategory.class) {
List<Tag> choices = tagFilter.getChoices();
Tag tag = choices.isEmpty() ? null : choices.get(0);
if (tag != null) {
- Identifiable data = null;
- if (tag.getTagClassifier() == Market.class) {
+ IIdentifiable data = null;
+ if (tag.getTagClassifier() == IMarket.class) {
data = market;
- } else if (tag.getTagClassifier() == Category.class) {
+ } else if (tag.getTagClassifier() == ICategory.class) {
data = category;
} else {
continue;
@@ -271,13 +288,13 @@ public class MarketplaceViewer extends CatalogViewer {
if (data != null) {
for (Tag choice : choices) {
final Object choiceData = choice.getData();
- if (data == choiceData || data.equalsId(choiceData)) {
+ if (choiceData == data || matches(data, choiceData)) {
tag = choice;
break;
}
}
}
- tagFilter.setSelected(tag == null ? null : Collections.singleton(tag));
+ tagFilter.setSelected(tag == null ? Collections.<Tag> emptySet() : Collections.singleton(tag));
//we expect a query to happen next, so don't fire a property change resulting in an additional query
tagFilter.updateUi();
}
@@ -286,7 +303,16 @@ public class MarketplaceViewer extends CatalogViewer {
}
}
+ private static boolean matches(IIdentifiable data, final Object tagData) {
+ return tagData instanceof IIdentifiable && Identifiable.matches((IIdentifiable) tagData, data);
+ }
+
private void doQuery() {
+ initQueryFromFilters();
+ doQuery(queryMarket, queryCategory, queryText, null);
+ }
+
+ private void initQueryFromFilters() {
queryMarket = null;
queryCategory = null;
queryText = null;
@@ -295,20 +321,19 @@ public class MarketplaceViewer extends CatalogViewer {
for (CatalogFilter filter : getConfiguration().getFilters()) {
if (filter instanceof AbstractTagFilter) {
AbstractTagFilter tagFilter = (AbstractTagFilter) filter;
- if (tagFilter.getTagClassification() == Category.class) {
+ if (tagFilter.getTagClassification() == ICategory.class) {
Tag tag = tagFilter.getSelected().isEmpty() ? null : tagFilter.getSelected().iterator().next();
if (tag != null) {
- if (tag.getTagClassifier() == Market.class) {
- queryMarket = (Market) tag.getData();
- } else if (tag.getTagClassifier() == Category.class) {
- queryCategory = (Category) tag.getData();
+ if (tag.getTagClassifier() == IMarket.class) {
+ queryMarket = (IMarket) tag.getData();
+ } else if (tag.getTagClassifier() == ICategory.class) {
+ queryCategory = (ICategory) tag.getData();
}
}
}
}
}
queryText = findText;
- doQuery(queryMarket, queryCategory, queryText, null);
}
public void doQueryForTag(String tag) {
@@ -339,7 +364,8 @@ public class MarketplaceViewer extends CatalogViewer {
firePropertyChangeEvent(new PropertyChangeEvent(source, property, oldValue, newValue));
}
- private void doQuery(final Market market, final Category category, final String queryText, final Set<Node> nodes) {
+ private void doQuery(final IMarket market, final ICategory category, final String queryText,
+ final Set<? extends INode> nodes) {
try {
final ContentType queryType = contentType;
queryContentType = queryType;
@@ -358,8 +384,8 @@ public class MarketplaceViewer extends CatalogViewer {
break;
case SELECTION:
Set<String> nodeIds = new HashSet<String>();
- for (CatalogItem item : getSelectionModel().getItemToOperation().keySet()) {
- nodeIds.add(((Node) item.getData()).getId());
+ for (CatalogItem item : getSelectionModel().getItemToSelectedOperation().keySet()) {
+ nodeIds.add(((INode) item.getData()).getId());
}
result[0] = getCatalog().performQuery(monitor, nodeIds);
break;
@@ -489,8 +515,27 @@ public class MarketplaceViewer extends CatalogViewer {
@Override
protected StructuredViewer doCreateViewer(Composite container) {
+ ServiceReference<IDiscoveryItemFactory> serviceReference = null;
+ final BundleContext bundleContext = MarketplaceClientUiPlugin.getInstance().getBundle().getBundleContext();
+ try {
+ serviceReference = bundleContext.getServiceReference(IDiscoveryItemFactory.class);
+ if (serviceReference != null) {
+ discoveryItemFactory = bundleContext.getService(serviceReference);
+ }
+ } catch (Exception ex) {
+ //fall back
+ MarketplaceClientUi.error(ex);
+ }
StructuredViewer viewer = super.doCreateViewer(container);
viewer.setSorter(null);
+ if (serviceReference != null) {
+ final ServiceReference<IDiscoveryItemFactory> ref = serviceReference;
+ viewer.getControl().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ bundleContext.ungetService(ref);
+ }
+ });
+ }
return viewer;
}
@@ -502,6 +547,14 @@ public class MarketplaceViewer extends CatalogViewer {
throw new UnsupportedOperationException();
}
+ /**
+ * @deprecated use {@link #modifySelection(CatalogItem, Operation)} instead
+ */
+ @Deprecated
+ protected void modifySelection(CatalogItem connector, org.eclipse.epp.internal.mpc.ui.wizards.Operation operation) {
+ modifySelection(connector, operation == null ? null : operation.getOperation());
+ }
+
protected void modifySelection(CatalogItem connector, Operation operation) {
if (operation == null) {
throw new IllegalArgumentException();
@@ -548,7 +601,7 @@ public class MarketplaceViewer extends CatalogViewer {
@Override
public List<CatalogItem> getCheckedItems() {
List<CatalogItem> items = new ArrayList<CatalogItem>();
- for (Entry<CatalogItem, Operation> entry : getSelectionModel().getItemToOperation().entrySet()) {
+ for (Entry<CatalogItem, Operation> entry : getSelectionModel().getItemToSelectedOperation().entrySet()) {
if (entry.getValue() != Operation.NONE) {
items.add(entry.getKey());
}
@@ -568,31 +621,31 @@ public class MarketplaceViewer extends CatalogViewer {
/**
* the text for the current query
*/
- String getQueryText() {
+ public String getQueryText() {
return queryText;
}
/**
* the category for the current query
- *
+ *
* @return the market or null if no category has been selected
*/
- Category getQueryCategory() {
+ public ICategory getQueryCategory() {
return queryCategory;
}
/**
* the market for the current query
- *
+ *
* @return the market or null if no market has been selected
*/
- Market getQueryMarket() {
+ public IMarket getQueryMarket() {
return queryMarket;
}
/**
* the content type for the current query
- *
+ *
* @return the content type or null if it's unknown
*/
ContentType getQueryContentType() {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
index 17539b95..7e0d5921 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/MarketplaceWizard.java
@@ -7,7 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
- * Yatta Solutions - news (bug 401721)
+ * Yatta Solutions - news (bug 401721), public API (bug 432803)
* JBoss (Pascal Rapicault) - Bug 406907 - Add p2 remediation page to MPC install flow
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -19,6 +19,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
@@ -30,6 +31,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -43,13 +46,21 @@ import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
+import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
import org.eclipse.epp.internal.mpc.ui.operations.AbstractProvisioningOperation;
import org.eclipse.epp.internal.mpc.ui.operations.FeatureDescriptor;
import org.eclipse.epp.internal.mpc.ui.operations.ProfileChangeOperationComputer;
import org.eclipse.epp.internal.mpc.ui.operations.ProfileChangeOperationComputer.OperationType;
+import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceViewer.ContentType;
import org.eclipse.epp.internal.mpc.ui.wizards.SelectionModel.CatalogItemEntry;
import org.eclipse.epp.internal.mpc.ui.wizards.SelectionModel.FeatureEntry;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INews;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.MarketplaceUrlHandler;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.AbstractDiscoveryStrategy;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.ui.ProvUI;
@@ -76,7 +87,7 @@ import org.eclipse.ui.statushandlers.StatusManager;
/**
* A wizard for interacting with a marketplace service.
- *
+ *
* @author David Green
* @author Carsten Reckord
*/
@@ -90,6 +101,68 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
private static final String DEBUG_NEWS_URL = MarketplaceClientUi.BUNDLE_ID + "/news/url"; //$NON-NLS-1$
+ public static class WizardState {
+ private ContentType contentType;
+
+ private Set<INode> content;
+
+ private IMarket filterMarket;
+
+ private ICategory filterCategory;
+
+ private String filterQuery;
+
+ private Boolean proceedWithInstallation;
+
+ public ContentType getContentType() {
+ return contentType;
+ }
+
+ public void setContentType(ContentType contentType) {
+ this.contentType = contentType;
+ }
+
+ public Set<INode> getContent() {
+ return content;
+ }
+
+ public void setContent(Set<INode> content) {
+ this.content = content;
+ }
+
+ public IMarket getFilterMarket() {
+ return filterMarket;
+ }
+
+ public void setFilterMarket(IMarket filterMarket) {
+ this.filterMarket = filterMarket;
+ }
+
+ public ICategory getFilterCategory() {
+ return filterCategory;
+ }
+
+ public void setFilterCategory(ICategory filterCategory) {
+ this.filterCategory = filterCategory;
+ }
+
+ public String getFilterQuery() {
+ return filterQuery;
+ }
+
+ public void setFilterQuery(String filterQuery) {
+ this.filterQuery = filterQuery;
+ }
+
+ public Boolean getProceedWithInstallation() {
+ return proceedWithInstallation;
+ }
+
+ public void setProceedWithInstallation(Boolean proceedWithInstallation) {
+ this.proceedWithInstallation = proceedWithInstallation;
+ }
+ }
+
private Set<String> installedFeatures;
private SelectionModel selectionModel;
@@ -114,6 +187,8 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
private String errorMessage;
+ private WizardState initialState;
+
public String getErrorMessage() {
return errorMessage;
}
@@ -168,30 +243,48 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
}
initialSelectionInitialized = true;
initializeCatalog();
- try {
- getContainer().run(true, true, new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
- new SelectionModelStateSerializer(getCatalog(), getSelectionModel()).deserialize(monitor,
- getConfiguration().getInitialState(), getConfiguration().getInitialOperationByNodeId());
+ if (getConfiguration().getInitialState() != null || getConfiguration().getInitialOperations() != null) {
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ new SelectionModelStateSerializer(getCatalog(), getSelectionModel()).deserialize(
+ getConfiguration().getInitialState(), getConfiguration().getInitialOperations(),
+ monitor);
+ }
+ });
+ } catch (InvocationTargetException e) {
+ throw new CoreException(MarketplaceClientUi.computeStatus(e,
+ Messages.MarketplaceViewer_unexpectedException));
+ } catch (InterruptedException e) {
+ // user canceled
+ throw new CoreException(Status.CANCEL_STATUS);
+ }
+ for (Entry<CatalogItem, Operation> entry : getSelectionModel().getItemToSelectedOperation().entrySet()) {
+ if (entry.getValue() != Operation.NONE) {
+ entry.getKey().setSelected(true);
}
- });
- } catch (InvocationTargetException e) {
- throw new CoreException(
- MarketplaceClientUi.computeStatus(e, Messages.MarketplaceViewer_unexpectedException));
- } catch (InterruptedException e) {
- // user canceled
- throw new CoreException(Status.CANCEL_STATUS);
- }
- for (Entry<CatalogItem, Operation> entry : getSelectionModel().getItemToOperation().entrySet()) {
- if (entry.getValue() != Operation.NONE) {
- entry.getKey().setSelected(true);
}
}
+ WizardState initialState = getInitialState();
+ if (initialState != null && getStartingPage() == getCatalogPage()) {
+ getCatalogPage().initialize(initialState);
+ }
}
boolean wantInitializeInitialSelection() {
- return !initialSelectionInitialized
- && (getConfiguration().getInitialState() != null || getConfiguration().getInitialOperationByNodeId() != null);
+ if (initialSelectionInitialized) {
+ return false;
+ } else if (getConfiguration().getInitialState() != null || getConfiguration().getInitialOperations() != null) {
+ return true;
+ } else if (initialState != null) {
+ WizardState initialState = getInitialState();
+ if ((initialState.getContent() != null && !initialState.getContent().isEmpty())
+ || (initialState.getContentType() != null && initialState.getContentType() != ContentType.SEARCH)
+ || (initialState.getFilterCategory() != null || initialState.getFilterMarket() != null || initialState.getFilterQuery() != null)) {
+ return true;
+ }
+ }
+ return false;
}
@Override
@@ -307,7 +400,10 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
public IWizardPage getStartingPage() {
if (getConfiguration().getCatalogDescriptor() != null) {
if (wantInitializeInitialSelection()) {
- return getFeatureSelectionWizardPage();
+ WizardState initialState = getInitialState();
+ if (initialState == null || !Boolean.FALSE.equals(initialState.getProceedWithInstallation())) {
+ return getFeatureSelectionWizardPage();
+ }
}
return getCatalogPage();
}
@@ -416,31 +512,18 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
}
public void openUrl(String url) {
- CatalogDescriptor catalogDescriptor = getConfiguration().getCatalogDescriptor();
- URL catalogUrl = catalogDescriptor.getUrl();
- URI catalogUri;
- try {
- catalogUri = catalogUrl.toURI();
- } catch (URISyntaxException e) {
- // should never happen
- throw new IllegalStateException(e);
- }
+ String catalogUrl = getCatalogUrl();
if (WorkbenchBrowserSupport.getInstance().isInternalWebBrowserAvailable()
- && url.toLowerCase().startsWith(catalogUri.toString().toLowerCase())) {
+ && url.toLowerCase().startsWith(catalogUrl.toLowerCase())) {
int style = IWorkbenchBrowserSupport.AS_EDITOR | IWorkbenchBrowserSupport.LOCATION_BAR
| IWorkbenchBrowserSupport.NAVIGATION_BAR;
- String browserId = "MPC-" + catalogUri.toString().replaceAll("[^a-zA-Z0-9_-]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ String browserId = "MPC-" + catalogUrl.replaceAll("[^a-zA-Z0-9_-]", "_"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
try {
+ CatalogDescriptor catalogDescriptor = getConfiguration().getCatalogDescriptor();
IWebBrowser browser = WorkbenchBrowserSupport.getInstance().createBrowser(style, browserId,
catalogDescriptor.getLabel(), catalogDescriptor.getDescription());
final String originalUrl = url;
- if (url.indexOf('?') == -1) {
- url += '?';
- } else {
- url += '&';
- }
- String state = new SelectionModelStateSerializer(getCatalog(), getSelectionModel()).serialize();
- url += "mpc=true&mpc_state=" + URLEncoder.encode(state, "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$
+ url = appendWizardState(url);
browser.openURL(new URL(url)); // ORDER DEPENDENCY
getContainer().getShell().close();
if (!hookLocationListener(browser)) { // ORDER DEPENDENCY
@@ -453,14 +536,40 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
IStatus status = new Status(IStatus.ERROR, MarketplaceClientUi.BUNDLE_ID, NLS.bind(
Messages.MarketplaceWizard_cannotOpenUrl, new Object[] { url, e.getMessage() }), e);
StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
- } catch (UnsupportedEncodingException e) {
- throw new IllegalStateException(e); // should never happen
}
} else {
WorkbenchUtil.openUrl(url, IWorkbenchBrowserSupport.AS_EXTERNAL);
}
}
+ private String getCatalogUrl() {
+ CatalogDescriptor catalogDescriptor = getConfiguration().getCatalogDescriptor();
+ URL catalogUrl = catalogDescriptor.getUrl();
+ URI catalogUri;
+ try {
+ catalogUri = catalogUrl.toURI();
+ } catch (URISyntaxException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
+ return catalogUri.toString();
+ }
+
+ private String appendWizardState(String url) {
+ try {
+ if (url.indexOf('?') == -1) {
+ url += '?';
+ } else {
+ url += '&';
+ }
+ String state = new SelectionModelStateSerializer(getCatalog(), getSelectionModel()).serialize();
+ url += "mpc=true&mpc_state=" + URLEncoder.encode(state, "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$
+ return url;
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(e); // should never happen
+ }
+ }
+
private boolean hookLocationListener(IWebBrowser webBrowser) {
try {
Field partField = findField(webBrowser.getClass(), "part", IWorkbenchPart.class); //$NON-NLS-1$
@@ -522,14 +631,14 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
if (getSelectionModel().computeProvisioningOperationViable()) {
ProfileChangeOperationComputer provisioningOperation = null;
try {
- final Map<CatalogItem, Operation> itemToOperation = getSelectionModel().getItemToOperation();
+ final Map<CatalogItem, Operation> itemToOperation = getSelectionModel().getItemToSelectedOperation();
final Set<CatalogItem> selectedItems = getSelectionModel().getSelectedCatalogItems();
OperationType operationType = null;
for (Map.Entry<CatalogItem, Operation> entry : itemToOperation.entrySet()) {
if (!selectedItems.contains(entry.getKey())) {
continue;
}
- OperationType entryOperationType = entry.getValue().getOperationType();
+ OperationType entryOperationType = OperationType.map(entry.getValue());
if (entryOperationType != null) {
if (operationType == null || operationType == OperationType.UPDATE) {
operationType = entryOperationType;
@@ -631,7 +740,7 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
Set<CatalogItem> items = new HashSet<CatalogItem>();
Map<CatalogItem, Collection<String>> iusByCatalogItem = new HashMap<CatalogItem, Collection<String>>();
for (CatalogItemEntry entry : getSelectionModel().getCatalogItemEntries()) {
- if (entry.getOperation() != Operation.INSTALL) {
+ if (entry.getSelectedOperation() != Operation.INSTALL) {
continue;
}
List<FeatureEntry> features = entry.getChildren();
@@ -664,26 +773,27 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
protected void updateNews() {
CatalogDescriptor catalogDescriptor = getConfiguration().getCatalogDescriptor();
- News news = null;
+ INews news = null;
if (Boolean.parseBoolean(Platform.getDebugOption(DEBUG_NEWS_FLAG))) {
// use debug override values
String debugNewsUrl = Platform.getDebugOption(DEBUG_NEWS_URL);
if (debugNewsUrl != null && debugNewsUrl.length() > 0) {
- news = new News();
- news.setUrl(debugNewsUrl);
+ News debugNews = new News();
+ news = debugNews;
+ debugNews.setUrl(debugNewsUrl);
String debugNewsTitle = Platform.getDebugOption(DEBUG_NEWS_TITLE);
if (debugNewsTitle == null || debugNewsTitle.length() == 0) {
- news.setShortTitle("Debug News"); //$NON-NLS-1$
+ debugNews.setShortTitle("Debug News"); //$NON-NLS-1$
} else {
- news.setShortTitle(debugNewsTitle);
+ debugNews.setShortTitle(debugNewsTitle);
}
- news.setTimestamp(System.currentTimeMillis());
+ debugNews.setTimestamp(System.currentTimeMillis());
}
}
if (news == null) {
// try requesting news from marketplace
try {
- final News[] result = new News[1];
+ final INews[] result = new INews[1];
getContainer().run(true, true, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@@ -712,4 +822,63 @@ public class MarketplaceWizard extends DiscoveryWizard implements InstallProfile
CatalogRegistry.getInstance().addCatalogNews(catalogDescriptor, news);
}
+ public Object suspendWizard() {
+ String catalogUrl = getCatalogUrl();
+ String key = appendWizardState(catalogUrl);
+ getContainer().getShell().close();
+ return key;
+ }
+
+ public void setInitialState(WizardState initialState) {
+ this.initialState = initialState;
+ }
+
+ public WizardState getInitialState() {
+ return initialState;
+ }
+
+ public static void resumeWizard(Display display, Object state, boolean proceedWithInstall) {
+ String catalogUrl = (String) state;
+ if (proceedWithInstall) {
+ org.eclipse.epp.mpc.ui.MarketplaceUrlHandler.SolutionInstallationInfo installInfo = MarketplaceUrlHandler.createSolutionInstallInfo(catalogUrl);
+ if (installInfo != null) {
+ MarketplaceUrlHandler.triggerInstall(installInfo);
+ return;
+ }
+ }
+ CatalogDescriptor descriptor = catalogUrl == null ? null : CatalogRegistry.getInstance().findCatalogDescriptor(
+ catalogUrl);
+ final MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ if (descriptor != null) {
+ descriptor = new CatalogDescriptor(descriptor);
+ descriptor.setLabel(MarketplaceUrlHandler.DESCRIPTOR_HINT);
+ command.setSelectedCatalogDescriptor(descriptor);
+ }
+ String mpcState = MarketplaceUrlHandler.getMPCState(catalogUrl);
+ if (mpcState != null && mpcState.length() > 0) {
+ try {
+ command.setWizardState(URLDecoder.decode(mpcState, "UTF-8")); //$NON-NLS-1$
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(e); // should never happen
+ }
+ if (!proceedWithInstall) {
+ WizardState wizardState = new WizardState();
+ wizardState.setProceedWithInstallation(false);
+ command.setWizardDialogState(wizardState);
+ }
+ }
+ display.asyncExec(new Runnable() {
+
+ public void run() {
+ try {
+ command.execute(new ExecutionEvent());
+ } catch (ExecutionException e) {
+ IStatus status = MarketplaceClientUi.computeStatus(e,
+ Messages.MarketplaceBrowserIntegration_cannotOpenMarketplaceWizard);
+ StatusManager.getManager().handle(status,
+ StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ }
+ }
+ });
+ }
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Messages.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Messages.java
index ac3e69db..8d5ad0dd 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Messages.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Messages.java
@@ -97,6 +97,10 @@ class Messages extends NLS {
public static String MarketplaceBrowserIntegration_cannotOpenMarketplaceWizard;
+ public static String MarketplaceCatalogConfiguration_invalidStateObject;
+
+ public static String MarketplaceClientService_noProvisioningOperation;
+
public static String MarketplaceDropAdapter_0;
public static String MarketplacePage_DefaultNewsTitle;
@@ -161,6 +165,8 @@ class Messages extends NLS {
public static String Operation_uninstall;
+ public static String Operation_unknownOperation;
+
public static String Operation_update;
public static String OverviewToolTip_cannotRenderImage_reason;
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsUrlHandler.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsUrlHandler.java
index f39b5af6..ddbd9337 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsUrlHandler.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsUrlHandler.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Yatta Solutions - initial API and implementation
+ * Yatta Solutions - initial API and implementation, public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -24,13 +24,14 @@ import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.epp.internal.mpc.core.service.Category;
-import org.eclipse.epp.internal.mpc.core.service.Market;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCategory;
import org.eclipse.epp.internal.mpc.ui.wizards.MarketplaceViewer.ContentType;
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.StructuredSelection;
@@ -146,8 +147,8 @@ public class NewsUrlHandler extends MarketplaceUrlHandler implements LocationLis
String filterParam = params.get("filter"); //$NON-NLS-1$
String[] filters = filterParam.split(" "); //$NON-NLS-1$
- Category searchCategory = null;
- Market searchMarket = null;
+ ICategory searchCategory = null;
+ IMarket searchMarket = null;
for (String filter : filters) {
if (filter.startsWith("tid:")) { //$NON-NLS-1$
String id = filter.substring("tid:".length()); //$NON-NLS-1$
@@ -155,13 +156,13 @@ public class NewsUrlHandler extends MarketplaceUrlHandler implements LocationLis
for (CatalogCategory catalogCategory : catalogCategories) {
if (catalogCategory instanceof MarketplaceCategory) {
MarketplaceCategory marketplaceCategory = (MarketplaceCategory) catalogCategory;
- List<Market> markets = marketplaceCategory.getMarkets();
- for (Market market : markets) {
+ List<? extends IMarket> markets = marketplaceCategory.getMarkets();
+ for (IMarket market : markets) {
if (id.equals(market.getId())) {
searchMarket = market;
} else {
- final List<Category> categories = market.getCategory();
- for (Category category : categories) {
+ final List<? extends ICategory> categories = market.getCategory();
+ for (ICategory category : categories) {
if (id.equals(category.getId())) {
searchCategory = category;
}
@@ -190,7 +191,7 @@ public class NewsUrlHandler extends MarketplaceUrlHandler implements LocationLis
}
@Override
- protected boolean handleNode(CatalogDescriptor descriptor, String url, Node node) {
+ protected boolean handleNode(CatalogDescriptor descriptor, String url, INode node) {
viewer.getWizard().getCatalogPage().show(descriptor, Collections.singleton(node));
return true;
}
@@ -217,9 +218,9 @@ public class NewsUrlHandler extends MarketplaceUrlHandler implements LocationLis
final SelectionModel selectionModel = viewer.getWizard().getSelectionModel();
SelectionModelStateSerializer stateSerializer = new SelectionModelStateSerializer(
wizard.getCatalog(), selectionModel);
- stateSerializer.deserialize(monitor, installId, nodeIdToOperation);
+ stateSerializer.deserialize(installId, nodeIdToOperation, monitor);
- if (selectionModel.getItemToOperation().size() > 0) {
+ if (selectionModel.getItemToSelectedOperation().size() > 0) {
Display display = wizard.getShell().getDisplay();
if (!display.isDisposed()) {
display.asyncExec(new Runnable() {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsViewer.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsViewer.java
index 276a8cf6..154de12d 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsViewer.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/NewsViewer.java
@@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Yatta Solutions - initial API and implementation
+ * Yatta Solutions - initial API and implementation, public API (bug 432803)
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -19,6 +19,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.epp.internal.mpc.core.service.News;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
+import org.eclipse.epp.mpc.core.model.INews;
import org.eclipse.epp.mpc.ui.CatalogDescriptor;
import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
import org.eclipse.jface.dialogs.IDialogConstants;
@@ -157,7 +158,7 @@ public class NewsViewer {
}
}
- public void showNews(News news) {
+ public void showNews(INews news) {
final String url = news.getUrl();
if (url != null && url.length() > 0) {
showUrl(url);
@@ -200,7 +201,7 @@ public class NewsViewer {
}
}
- public boolean isUpdated(News news) {
+ public boolean isUpdated(INews news) {
String url = news.getUrl();
if (url == null || url.length() == 0) {
return false;
@@ -214,7 +215,7 @@ public class NewsViewer {
return true;
}
- private String computeNewsStamp(News news) {
+ private String computeNewsStamp(INews news) {
return NLS.bind("[{0}]{1}", news.getTimestamp(), news.getUrl()); //$NON-NLS-1$
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Operation.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Operation.java
index b3388814..da756596 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Operation.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/Operation.java
@@ -7,29 +7,37 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
import org.eclipse.epp.internal.mpc.ui.operations.ProfileChangeOperationComputer.OperationType;
+import org.eclipse.osgi.util.NLS;
/**
* Represents kinds of provisioning operations supported by the wizard
- *
+ *
* @author David Green
+ * @deprecated will be replaced completely by {@link org.eclipse.epp.mpc.ui.Operation} in the future.
*/
+@Deprecated
public enum Operation {
- INSTALL(OperationType.INSTALL, Messages.Operation_install), //
- UNINSTALL(OperationType.UNINSTALL, Messages.Operation_uninstall), //
- CHECK_FOR_UPDATES(OperationType.UPDATE, Messages.Operation_update), //
- NONE(null, null);
+ INSTALL(OperationType.INSTALL, org.eclipse.epp.mpc.ui.Operation.INSTALL), //
+ UNINSTALL(OperationType.UNINSTALL, org.eclipse.epp.mpc.ui.Operation.UNINSTALL), //
+ CHECK_FOR_UPDATES(OperationType.UPDATE, org.eclipse.epp.mpc.ui.Operation.UPDATE), //
+ NONE(null, org.eclipse.epp.mpc.ui.Operation.NONE);
private final OperationType operationType;
- private final String label;
+ private final org.eclipse.epp.mpc.ui.Operation operation;
- private Operation(OperationType operationType, String label) {
+ private Operation(OperationType operationType, org.eclipse.epp.mpc.ui.Operation operation) {
this.operationType = operationType;
- this.label = label;
+ this.operation = operation;
}
public OperationType getOperationType() {
@@ -37,6 +45,70 @@ public enum Operation {
}
public String getLabel() {
- return label;
+ return operation.getLabel();
+ }
+
+ public org.eclipse.epp.mpc.ui.Operation getOperation() {
+ return operation;
+ }
+
+ public static Operation map(org.eclipse.epp.mpc.ui.Operation operation) {
+ if (operation == null) {
+ return null;
+ }
+ switch (operation) {
+ case INSTALL:
+ return INSTALL;
+ case UNINSTALL:
+ return UNINSTALL;
+ case UPDATE:
+ return CHECK_FOR_UPDATES;
+ case NONE:
+ return NONE;
+ default:
+ throw new IllegalArgumentException(NLS.bind(Messages.Operation_unknownOperation, operation));
+ }
+ }
+
+ public static org.eclipse.epp.mpc.ui.Operation mapBack(Operation operation) {
+ if (operation == null) {
+ return null;
+ }
+ switch (operation) {
+ case INSTALL:
+ return org.eclipse.epp.mpc.ui.Operation.INSTALL;
+ case UNINSTALL:
+ return org.eclipse.epp.mpc.ui.Operation.UNINSTALL;
+ case CHECK_FOR_UPDATES:
+ return org.eclipse.epp.mpc.ui.Operation.UPDATE;
+ case NONE:
+ return org.eclipse.epp.mpc.ui.Operation.NONE;
+ default:
+ throw new IllegalArgumentException(NLS.bind(Messages.Operation_unknownOperation, operation));
+ }
+ }
+
+ public static <T> Map<T, Operation> mapAll(Map<T, org.eclipse.epp.mpc.ui.Operation> operations) {
+ if (operations == null) {
+ return null;
+ }
+ Map<T, Operation> mappedOperations = new LinkedHashMap<T, Operation>();
+ Set<Map.Entry<T, org.eclipse.epp.mpc.ui.Operation>> entrySet = operations.entrySet();
+ for (Map.Entry<T, org.eclipse.epp.mpc.ui.Operation> entry : entrySet) {
+ mappedOperations.put(entry.getKey(), map(entry.getValue()));
+ }
+ return mappedOperations;
+ }
+
+ public static <T> Map<T, org.eclipse.epp.mpc.ui.Operation> mapAllBack(Map<T, Operation> operations) {
+ if (operations == null) {
+ return null;
+ }
+ Map<T, org.eclipse.epp.mpc.ui.Operation> mappedOperations = new LinkedHashMap<T, org.eclipse.epp.mpc.ui.Operation>();
+ Set<Map.Entry<T, Operation>> entrySet = operations.entrySet();
+ for (Map.Entry<T, Operation> entry : entrySet) {
+ mappedOperations.put(entry.getKey(), entry.getValue() == null ? null : entry.getValue().getOperation());
+ }
+ return mappedOperations;
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java
index 70c22883..473b3b7c 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ProvisioningJobListener.java
@@ -7,11 +7,11 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
-import java.io.InputStream;
-import java.net.URI;
+import java.net.URL;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
@@ -22,17 +22,16 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.service.Node;
-import org.eclipse.epp.internal.mpc.core.service.RemoteMarketplaceService;
-import org.eclipse.epp.internal.mpc.core.util.TransportFactory;
-import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceDiscoveryStrategy;
+import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
import org.eclipse.epp.internal.mpc.ui.util.ConcurrentTaskManager;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.service.IMarketplaceService;
+import org.eclipse.epp.mpc.core.service.ServiceHelper;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
/**
* A job listener that produces notifications of a successful install.
- *
+ *
* @author David Green
*/
class ProvisioningJobListener extends JobChangeAdapter {
@@ -53,41 +52,27 @@ class ProvisioningJobListener extends JobChangeAdapter {
}
@Override
- protected IStatus run(IProgressMonitor monitor) {
+ protected IStatus run(final IProgressMonitor monitor) {
ConcurrentTaskManager taskManager = new ConcurrentTaskManager(installItems.size(),
Messages.ProvisioningJobListener_notificationTaskName);
- for (final CatalogItem item : installItems) {
- taskManager.submit(new Runnable() {
- public void run() {
- Node node = (Node) item.getData();
- String url = node.getUrl();
- if (!url.endsWith("/")) { //$NON-NLS-1$
- url += "/"; //$NON-NLS-1$
- }
- url += "success"; //$NON-NLS-1$
-
- //FIXME workaround to access request metadata
- //move success reporting to MarketplaceService API once we are not in API freeze to make this hack unnecessary - see bug 417068
- RemoteMarketplaceService<?> marketplaceService = new DefaultMarketplaceService();
- marketplaceService.setRequestMetaParameters(MarketplaceDiscoveryStrategy.computeDefaultRequestMetaParameters());
- url = marketplaceService.addMetaParameters(url);
- try {
- InputStream stream = TransportFactory.instance()
- .getTransport()
- .stream(new URI(url), new NullProgressMonitor());
+ for (CatalogItem item : installItems) {
+ if (item instanceof MarketplaceNodeCatalogItem) {
+ final MarketplaceNodeCatalogItem nodeItem = (MarketplaceNodeCatalogItem) item;
- try {
- while (stream.read() != -1) {
- // nothing to do
+ taskManager.submit(new Runnable() {
+ public void run() {
+ INode node = nodeItem.getData();
+ URL marketplaceUrl = nodeItem.getMarketplaceUrl();
+ IMarketplaceService marketplaceService = ServiceHelper.getMarketplaceServiceLocator().getMarketplaceService(marketplaceUrl.toString());
+ marketplaceService.reportInstallSuccess(node, new NullProgressMonitor() {
+ @Override
+ public boolean isCanceled() {
+ return monitor.isCanceled();
}
- } finally {
- stream.close();
- }
- } catch (Throwable e) {
- //per bug 314028 logging this error is not useful.
+ });
}
- }
- });
+ });
+ }
}
try {
taskManager.waitUntilFinished(monitor);
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModel.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModel.java
index 200e7157..55fbffb0 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModel.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModel.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -24,13 +25,14 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.operations.FeatureDescriptor;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.osgi.util.NLS;
/**
* A model of selected items in the catalog. Provides feature-level selection fidelity, and stores the selected
* operation.
- *
+ *
* @author David Green
*/
public class SelectionModel {
@@ -47,7 +49,21 @@ public class SelectionModel {
/**
* Select the given item with the given operation.
- *
+ *
+ * @param item
+ * the item to select
+ * @param operation
+ * the operation to perform. Providing {@link Operation#NONE} removes the selection
+ * @deprecated use {@link #select(CatalogItem, Operation)} instead
+ */
+ @Deprecated
+ public void select(CatalogItem item, org.eclipse.epp.internal.mpc.ui.wizards.Operation operation) {
+ select(item, operation == null ? null : operation.getOperation());
+ }
+
+ /**
+ * Select the given item with the given operation.
+ *
* @param item
* the item to select
* @param operation
@@ -106,6 +122,15 @@ public class SelectionModel {
return entries;
}
+ /**
+ * @deprecated use {@link #createItemEntry(CatalogItem, Operation)} instead
+ */
+ @Deprecated
+ public CatalogItemEntry createItemEntry(CatalogItem item,
+ org.eclipse.epp.internal.mpc.ui.wizards.Operation operation) {
+ return createItemEntry(item, operation == null ? null : operation.getOperation());
+ }
+
public CatalogItemEntry createItemEntry(CatalogItem item, Operation operation) {
CatalogItemEntry itemEntry = new CatalogItemEntry(item, operation);
computeChildren(itemEntry);
@@ -131,7 +156,7 @@ public class SelectionModel {
private void computeInitialChecked(FeatureEntry entry) {
Operation operation = entry.parent.operation;
- if (operation == Operation.CHECK_FOR_UPDATES) {
+ if (operation == Operation.UPDATE) {
if (entry.isInstalled()) {
entry.checked = true;
}
@@ -156,7 +181,15 @@ public class SelectionModel {
return item;
}
- public Operation getOperation() {
+ /**
+ * @deprecated use {@link #getSelectedOperation()}
+ */
+ @Deprecated
+ public org.eclipse.epp.internal.mpc.ui.wizards.Operation getOperation() {
+ return org.eclipse.epp.internal.mpc.ui.wizards.Operation.map(operation);
+ }
+
+ public Operation getSelectedOperation() {
return operation;
}
@@ -285,7 +318,20 @@ public class SelectionModel {
}
- public Map<CatalogItem, Operation> getItemToOperation() {
+ /**
+ * @deprecated use {@link #getItemToSelectedOperation()} instead
+ */
+ @Deprecated
+ public Map<CatalogItem, org.eclipse.epp.internal.mpc.ui.wizards.Operation> getItemToOperation() {
+ Map<CatalogItem, org.eclipse.epp.internal.mpc.ui.wizards.Operation> itemToOperation = new HashMap<CatalogItem, org.eclipse.epp.internal.mpc.ui.wizards.Operation>();
+ Set<Entry<CatalogItem, Operation>> entrySet = this.itemToOperation.entrySet();
+ for (Entry<CatalogItem, Operation> entry : entrySet) {
+ itemToOperation.put(entry.getKey(), org.eclipse.epp.internal.mpc.ui.wizards.Operation.map(entry.getValue()));
+ }
+ return itemToOperation;
+ }
+
+ public Map<CatalogItem, Operation> getItemToSelectedOperation() {
return Collections.unmodifiableMap(itemToOperation);
}
@@ -321,7 +367,16 @@ public class SelectionModel {
return Collections.unmodifiableSet(items);
}
- public Operation getOperation(CatalogItem item) {
+ /**
+ * @deprecated use {@link #getSelectedOperation(CatalogItem)} instead
+ */
+ @Deprecated
+ public org.eclipse.epp.internal.mpc.ui.wizards.Operation getOperation(CatalogItem item) {
+ Operation operation = getSelectedOperation(item);
+ return org.eclipse.epp.internal.mpc.ui.wizards.Operation.map(operation);
+ }
+
+ public Operation getSelectedOperation(CatalogItem item) {
Operation operation = itemToOperation.get(item);
return operation == null ? Operation.NONE : operation;
}
@@ -345,7 +400,7 @@ public class SelectionModel {
/**
* Determine what message related to finishing the wizard should correspond to the current selection.
- *
+ *
* @return the message, or null if there should be no message.
*/
public IStatus computeProvisioningOperationViability() {
@@ -364,7 +419,7 @@ public class SelectionModel {
Messages.SelectionModel_countSolutions, entry.getValue().size()), entry.getKey()
.getLabel()));
} else if (operationToItem.size() == 2 && operationToItem.containsKey(Operation.INSTALL)
- && operationToItem.containsKey(Operation.CHECK_FOR_UPDATES)) {
+ && operationToItem.containsKey(Operation.UPDATE)) {
int count = 0;
for (List<CatalogItem> items : operationToItem.values()) {
count += items.size();
@@ -372,7 +427,7 @@ public class SelectionModel {
return new Status(IStatus.INFO, MarketplaceClientUi.BUNDLE_ID, NLS.bind(
Messages.SelectionModel_countSolutionsSelectedForInstallUpdate, count));
} else if (operationToItem.size() > 1) {
- if (!(operationToItem.size() == 2 && operationToItem.containsKey(Operation.INSTALL) && operationToItem.containsKey(Operation.CHECK_FOR_UPDATES))) {
+ if (!(operationToItem.size() == 2 && operationToItem.containsKey(Operation.INSTALL) && operationToItem.containsKey(Operation.UPDATE))) {
return new Status(IStatus.ERROR, MarketplaceClientUi.BUNDLE_ID,
Messages.SelectionModel_cannotInstallRemoveConcurrently);
}
@@ -381,7 +436,7 @@ public class SelectionModel {
}
private Map<Operation, List<CatalogItem>> computeOperationToItem() {
- Map<CatalogItem, Operation> itemToOperation = getItemToOperation();
+ Map<CatalogItem, Operation> itemToOperation = getItemToSelectedOperation();
Map<Operation, List<CatalogItem>> catalogItemByOperation = new HashMap<Operation, List<CatalogItem>>();
for (Map.Entry<CatalogItem, Operation> entry : itemToOperation.entrySet()) {
if (entry.getValue() == Operation.NONE) {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModelStateSerializer.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModelStateSerializer.java
index 81d0058e..0c887e8c 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModelStateSerializer.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/SelectionModelStateSerializer.java
@@ -7,23 +7,26 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceCatalog;
import org.eclipse.epp.internal.mpc.ui.catalog.MarketplaceNodeCatalogItem;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.ui.Operation;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
/**
* A mechanism for serializing/deserializing state
- *
+ *
* @author David Green
*/
public class SelectionModelStateSerializer {
@@ -39,12 +42,12 @@ public class SelectionModelStateSerializer {
public String serialize() {
StringBuilder state = new StringBuilder(1024);
- for (Map.Entry<CatalogItem, Operation> entry : selectionModel.getItemToOperation().entrySet()) {
+ for (Map.Entry<CatalogItem, Operation> entry : selectionModel.getItemToSelectedOperation().entrySet()) {
if (entry.getValue() != Operation.NONE) {
if (state.length() > 0) {
state.append(' ');
}
- Node data = (Node) entry.getKey().getData();
+ INode data = (INode) entry.getKey().getData();
state.append(data.getId());
state.append('=');
state.append(entry.getValue().name());
@@ -59,8 +62,27 @@ public class SelectionModelStateSerializer {
* the state to restore
* @param operationByNodeIdExtras
* additional operations to include
+ * @deprecated use {@link #deserialize(String, Map, IProgressMonitor)} instead
*/
- public void deserialize(IProgressMonitor monitor, String state, Map<String, Operation> operationByNodeIdExtras) {
+ @Deprecated
+ public void deserialize(IProgressMonitor monitor, String state,
+ Map<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> operationByNodeIdExtras) {
+ Map<String, Operation> operationByNodeId = new HashMap<String, Operation>();
+ for (Entry<String, org.eclipse.epp.internal.mpc.ui.wizards.Operation> entry : operationByNodeIdExtras.entrySet()) {
+ org.eclipse.epp.internal.mpc.ui.wizards.Operation op = entry.getValue();
+ operationByNodeId.put(entry.getKey(), op == null ? null : op.getOperation());
+ }
+ deserialize(state, operationByNodeId, monitor);
+ }
+
+ /**
+ * @param state
+ * the state to restore
+ * @param operationByNodeExtras
+ * additional operations to include
+ * @param monitor
+ */
+ public void deserialize(String state, Map<String, Operation> operationByNodeExtras, IProgressMonitor monitor) {
Map<String, Operation> operationByNodeId = new HashMap<String, Operation>();
if (state != null && state.length() > 0) {
@@ -75,8 +97,8 @@ public class SelectionModelStateSerializer {
operationByNodeId.put(nodeId, operation);
}
}
- if (operationByNodeIdExtras != null) {
- operationByNodeId.putAll(operationByNodeIdExtras);
+ if (operationByNodeExtras != null) {
+ operationByNodeId.putAll(operationByNodeExtras);
}
if (!operationByNodeId.isEmpty()) {
catalog.performQuery(monitor, operationByNodeId.keySet());
@@ -86,7 +108,7 @@ public class SelectionModelStateSerializer {
Operation operation = operationByNodeId.get(nodeItem.getData().getId());
if (operation != null && operation != Operation.NONE) {
if (nodeItem.isInstalled() && operation == Operation.INSTALL) {
- operation = Operation.CHECK_FOR_UPDATES;
+ operation = Operation.UPDATE;
}
selectionModel.select(nodeItem, operation);
}
@@ -95,7 +117,15 @@ public class SelectionModelStateSerializer {
}
}
+ /**
+ * @deprecated use {@link #deserialize(String, IProgressMonitor)} instead.
+ */
+ @Deprecated
public void deserialize(IProgressMonitor monitor, String state) {
- deserialize(monitor, state, null);
+ deserialize(state, monitor);
+ }
+
+ public void deserialize(String state, IProgressMonitor monitor) {
+ deserialize(state, null, monitor);
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ShareSolutionLink.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ShareSolutionLink.java
index 694ec540..e5309705 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ShareSolutionLink.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/ShareSolutionLink.java
@@ -7,6 +7,7 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.internal.mpc.ui.wizards;
@@ -15,10 +16,10 @@ import java.lang.reflect.Method;
import java.net.URI;
import org.eclipse.core.runtime.URIUtil;
-import org.eclipse.epp.internal.mpc.core.service.Node;
import org.eclipse.epp.internal.mpc.core.util.TextUtil;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
+import org.eclipse.epp.mpc.core.model.INode;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
import org.eclipse.jface.dialogs.MessageDialog;
@@ -139,7 +140,7 @@ public class ShareSolutionLink {
}
private String getUrl() {
- return ((Node) catalogItem.getData()).getUrl();
+ return ((INode) catalogItem.getData()).getUrl();
}
private void openMail(URI uri) throws Exception {
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/messages.properties b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/messages.properties
index de6e83ba..b570e30d 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/messages.properties
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/internal/mpc/ui/wizards/messages.properties
@@ -49,6 +49,8 @@ ItemButtonController_uninstallPending=Uninstall Pending
ItemButtonController_update=Update
ItemButtonController_updatePending=Update Pending
MarketplaceBrowserIntegration_cannotOpenMarketplaceWizard=Cannot open Eclipse Marketplace
+MarketplaceCatalogConfiguration_invalidStateObject=Invalid state object: {0}
+MarketplaceClientService_noProvisioningOperation=No provisioning operations specified
MarketplaceDropAdapter_0=Marketplace DND Initialization
MarketplacePage_DefaultNewsTitle=News
MarketplacePage_discardPendingSolutions=There are solutions pending for installation. Switching the marketplace will discard your selection. Proceed?
@@ -81,6 +83,7 @@ NewsViewer_No_embeddable_browser=No embeddable Browser component was found for y
NewsViewer_No_news=(No news available)
Operation_install=install
Operation_uninstall=uninstall
+Operation_unknownOperation=Unknown operation: {0}
Operation_update=update
OverviewToolTip_cannotRenderImage_reason=Cannot render image {0}: {1}
OverviewToolTip_learnMoreLink=<a>Learn more</a>
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/CatalogDescriptor.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/CatalogDescriptor.java
index 33ad532c..97a93137 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/CatalogDescriptor.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/CatalogDescriptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 The Eclipse Foundation and others.
+ * Copyright (c) 2010, 2014 The Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,18 +7,24 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.ui;
+import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
+import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
+import org.eclipse.epp.mpc.core.model.ICatalog;
+import org.eclipse.epp.mpc.core.model.ICatalogBranding;
import org.eclipse.jface.resource.ImageDescriptor;
/**
* A descriptor for identifying a solutions catalog, ie: a location that implements the Eclipse Marketplace API.
- *
+ *
* @author David Green
+ * @see org.eclipse.epp.mpc.core.model.ICatalog
* @see MarketplaceClient#addCatalogDescriptor(CatalogDescriptor)
*/
public final class CatalogDescriptor {
@@ -30,6 +36,8 @@ public final class CatalogDescriptor {
private ImageDescriptor icon;
+ private ICatalogBranding catalogBranding;
+
private boolean installFromAllRepositories;
private URL dependenciesRepository;
@@ -60,6 +68,21 @@ public final class CatalogDescriptor {
this.installFromAllRepositories = catalogDescriptor.installFromAllRepositories;
}
+ public CatalogDescriptor(ICatalog catalog) throws MalformedURLException {
+ setLabel(catalog.getName());
+ setUrl(new URL(catalog.getUrl()));
+ setIcon(ImageDescriptor.createFromURL(new URL(catalog.getImageUrl())));
+ setDescription(catalog.getDescription());
+ setInstallFromAllRepositories(!catalog.isSelfContained());
+ if (catalog.getDependencyRepository() != null) {
+ setDependenciesRepository(new URL(catalog.getDependencyRepository()));
+ }
+ setCatalogBranding(catalog.getBranding());
+ if (catalog.getNews() != null) {
+ CatalogRegistry.getInstance().addCatalogNews(this, catalog.getNews());
+ }
+ }
+
/**
* The URL of the catalog. The URL identifies the catalog location, which provides an API described by <a
* href="http://wiki.eclipse.org/Marketplace/REST">Marketplace REST</a>
@@ -74,7 +97,7 @@ public final class CatalogDescriptor {
/**
* A description of the catalog, presented to the user. Should be brief (ie: one or two sentences).
- *
+ *
* @return the description or null if there is no description
*/
public String getDescription() {
@@ -112,7 +135,7 @@ public final class CatalogDescriptor {
* configuration. When false installation resolves only against repositories of the selected catalog items including
* repositories considered as default for the catalog. Currently there is no way to define catalog default
* repositories, however it is expected that this may change in the future. The default value is false.
- *
+ *
* @return true if installation occurs from all repositories, otherwise false.
*/
public boolean isInstallFromAllRepositories() {
@@ -141,6 +164,20 @@ public final class CatalogDescriptor {
this.dependenciesRepository = dependenciesRepository;
}
+ /**
+ * Branding information controlling wizard title and icon and available tabs.
+ */
+ public ICatalogBranding getCatalogBranding() {
+ return catalogBranding;
+ }
+
+ /**
+ * @see #getCatalogBranding()
+ */
+ public void setCatalogBranding(ICatalogBranding catalogBranding) {
+ this.catalogBranding = catalogBranding;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
@@ -190,5 +227,4 @@ public final class CatalogDescriptor {
public String toString() {
return "CatalogDescriptor [url=" + url + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
-
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientConfiguration.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientConfiguration.java
new file mode 100644
index 00000000..c16e8de1
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientConfiguration.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, public API (bug 432803)
+ *******************************************************************************/
+package org.eclipse.epp.mpc.ui;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.epp.mpc.core.service.ICatalogService;
+
+/**
+ * Configuration for launching the Marketplace Wizard using {@link IMarketplaceClientService}.
+ *
+ * @see IMarketplaceClientService
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarketplaceClientConfiguration {
+ /**
+ * @see #getCatalogDescriptors()
+ */
+ void setCatalogDescriptors(List<CatalogDescriptor> descriptors);
+
+ /**
+ * @see #getCatalogDescriptor()
+ */
+ void setCatalogDescriptor(CatalogDescriptor initial);
+
+ /**
+ * Valid objects for the initial state are only created by the marketplace wizard internally. Clients wishing to
+ * start the wizard in a defined state should refer to {@link #setInitialOperations(Map)} instead.
+ *
+ * @see #getInitialState()
+ */
+ void setInitialState(Object state);
+
+ /**
+ * @see #getInitialOperations()
+ */
+ void setInitialOperations(Map<String, Operation> selection);
+
+ /**
+ * The initial selection state applied to marketplace entries by {@link INode#getId() node id}.
+ */
+ Map<String, Operation> getInitialOperations();
+
+ /**
+ * The initial state applied to the Wizard. This will be merged with any additional {@link #getInitialOperations()
+ * initial operations}.
+ * <p>
+ * This is used internally to suspend and resume the wizard, e.g. to switch to an embedded web browser to show
+ * marketplace pages.
+ * <p>
+ * Valid objects for the initial state are only created by the marketplace wizard internally. Clients wishing to
+ * start the wizard in a defined state should refer to {@link #setInitialOperations(Map)} instead.
+ */
+ Object getInitialState();
+
+ /**
+ * The initially active catalog. By default, either the last active catalog from a previous launch or the first
+ * {@link #setCatalogDescriptors(List) available catalog} will be selected.
+ */
+ CatalogDescriptor getCatalogDescriptor();
+
+ /**
+ * The list of available Marketplace catalogs. These will be shown in the wizard's catalog selector. If no
+ * descriptors are set explicitly, a default list will be retrieved using the {@link ICatalogService}.
+ */
+ List<CatalogDescriptor> getCatalogDescriptors();
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientService.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientService.java
new file mode 100644
index 00000000..fbcdcee5
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/IMarketplaceClientService.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Yatta Solutions - initial API and implementation, public API (bug 432803)
+ *******************************************************************************/
+package org.eclipse.epp.mpc.ui;
+
+import java.util.Set;
+
+import org.eclipse.epp.mpc.core.model.ICategory;
+import org.eclipse.epp.mpc.core.model.IMarket;
+import org.eclipse.epp.mpc.core.model.INode;
+
+/**
+ * This service allows opening the Eclipse Marketplace Wizard in a predefined state, e.g. to show a specific search,
+ * preselected items, or start the install of selected nodes.
+ * <p>
+ * An instance of this class can be acquired as an OSGi service or through the {@link MarketplaceClient}
+ * {@link MarketplaceClient#getMarketplaceClientService() convenience method}.
+ *
+ * @author Carsten Reckord
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarketplaceClientService {
+ /**
+ * @return an editable configuration object for the Marketplace Wizard
+ */
+ IMarketplaceClientConfiguration newConfiguration();
+
+ /**
+ * Open the Marketplace Wizard using the given configuration. Regardless of an
+ * {@link IMarketplaceClientConfiguration#setInitialOperations(java.util.Map) initial selection} defined in the
+ * configuration, this will always launch the wizard on the initial catalog page.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ */
+ void open(IMarketplaceClientConfiguration configuration);
+
+ /**
+ * Open the Marketplace Wizard showing the
+ * {@link IMarketplaceClientConfiguration#setInitialOperations(java.util.Map) initial selection} defined in the
+ * configuration.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ * @throws IllegalArgumentException
+ * if the configuration does not contain an initial selection either in
+ * {@link IMarketplaceClientConfiguration#getInitialOperations()} or
+ * {@link IMarketplaceClientConfiguration#getInitialState()}
+ */
+ void openSelected(IMarketplaceClientConfiguration configuration);
+
+ /**
+ * Open the Marketplace Wizard showing the "Installed" tab for the
+ * {@link IMarketplaceClientConfiguration#getCatalogDescriptor() active catalog}.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ */
+ void openInstalled(IMarketplaceClientConfiguration configuration);
+
+ /**
+ * Open the Marketplace Wizard showing the result of the given search on the
+ * {@link IMarketplaceClientConfiguration#getCatalogDescriptor() active catalog}.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ * @param market
+ * the market to search in or null to search in all markets
+ * @param category
+ * the category to search in or null to search in all categories
+ * @param query
+ * the search terms
+ */
+ void openSearch(IMarketplaceClientConfiguration configuration, IMarket market, ICategory category, String query);
+
+ /**
+ * Open the Marketplace Wizard showing the given list of nodes in the MPC's search view.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ * @param nodes
+ * the nodes to show
+ */
+ void open(IMarketplaceClientConfiguration configuration, Set<INode> nodes);
+
+ /**
+ * Trigger the specified {@link IMarketplaceClientConfiguration#getInitialOperations() provisioning operations} in
+ * the Marketplace Wizard. This will launch the Wizard on the feature selection page, as if selecting the respective
+ * operations on the catalog page and clicking "Install Now" afterwards.
+ *
+ * @param configuration
+ * the initial configuration applied to the MPC wizard
+ * @throws IllegalArgumentException
+ * if the configuration does not contain an initial selection either in
+ * {@link IMarketplaceClientConfiguration#getInitialOperations()} or
+ * {@link IMarketplaceClientConfiguration#getInitialState()}
+ */
+ void openProvisioning(IMarketplaceClientConfiguration configuration);
+
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceClient.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceClient.java
index fc9fd301..97e107dc 100644
--- a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceClient.java
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceClient.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 The Eclipse Foundation and others.
+ * Copyright (c) 2010, 2014 The Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,25 +7,26 @@
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
*******************************************************************************/
package org.eclipse.epp.mpc.ui;
import java.util.List;
-import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
-import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
+import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUiPlugin;
/**
* Provides a means to configure and launch the marketplace client.
- *
+ *
* @author David Green
+ * @author Carsten Reckord
*/
public class MarketplaceClient {
/**
* Add a catalog descriptor to those available to be the user when accessing the marketplace.
- *
+ *
* @param catalogDescriptor
* the descriptor, must not be null
* @see #removeCatalogDescriptor(CatalogDescriptor)
@@ -39,7 +40,7 @@ public class MarketplaceClient {
/**
* Remove a catalog descriptor from those available to the user when accessing the marketplace.
- *
+ *
* @see #addCatalogDescriptor(CatalogDescriptor)
*/
public static void removeCatalogDescriptor(CatalogDescriptor catalogDescriptor) {
@@ -56,7 +57,7 @@ public class MarketplaceClient {
* Upon return of this method the UI will have been displayed, however any provisioning operations instigated by the
* user may not have completed.
* </p>
- *
+ *
* @param catalogDescriptors
* the catalogs to query, or null if the default catalogs should be used.
* @throws IllegalArgumentException
@@ -79,9 +80,21 @@ public class MarketplaceClient {
}
}
}
- MarketplaceWizardCommand command = new MarketplaceWizardCommand();
- command.setCatalogDescriptors(catalogDescriptors);
+ IMarketplaceClientService clientService = getMarketplaceClientService();
+ IMarketplaceClientConfiguration config = clientService.newConfiguration();
+ if (catalogDescriptors != null) {
+ config.setCatalogDescriptors(catalogDescriptors);
+ }
+ clientService.open(config);
+ }
- command.execute(new ExecutionEvent());
+ /**
+ * Convenience method to retrieve a registered {@link IMarketplaceClientService client service} for opening the MPC
+ * wizard dialog.
+ *
+ * @return a client service from the OSGi service registry
+ */
+ public static IMarketplaceClientService getMarketplaceClientService() {
+ return MarketplaceClientUiPlugin.getInstance().getClientService();
}
}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceUrlHandler.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceUrlHandler.java
new file mode 100644
index 00000000..853325b8
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/MarketplaceUrlHandler.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright (c) 2011 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Yatta Solutions - news (bug 401721), public API (bug 432803)
+ *******************************************************************************/
+package org.eclipse.epp.mpc.ui;
+
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.epp.internal.mpc.core.service.DefaultMarketplaceService;
+import org.eclipse.epp.internal.mpc.core.service.Node;
+import org.eclipse.epp.internal.mpc.ui.CatalogRegistry;
+import org.eclipse.epp.internal.mpc.ui.MarketplaceClientUi;
+import org.eclipse.epp.internal.mpc.ui.commands.MarketplaceWizardCommand;
+import org.eclipse.epp.mpc.core.model.INode;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * Handler for Marketplace URLs. It supports parsing of Marketplace-related URLs through its {@link #handleUri(String)}
+ * method and will call the appropriate <code>handleXXX</code> methods depending on the URL. Clients can override the
+ * methods they wish to handle. Default behavior for handle methods is to do nothing unless specified otherwise on the
+ * handler method.
+ *
+ * @author David Green
+ * @author Benjamin Muskalla
+ * @author Carsten Reckord
+ */
+public abstract class MarketplaceUrlHandler {
+
+ public static final String DESCRIPTOR_HINT = "org.eclipse.epp.mpc.descriptorHint"; //$NON-NLS-1$
+
+ public static final String MPC_INSTALL_URI = "/mpc/install?"; //$NON-NLS-1$
+
+ public static final String SITE_SEARCH_URI = "/search/site"; //$NON-NLS-1$
+
+ private static final Pattern CONTENT_URL_PATTERN = Pattern.compile("(?:^|/)content/([^/#?]+)"); //$NON-NLS-1$
+
+ private static final Pattern NODE_URL_PATTERN = Pattern.compile("(?:^|/)node/([^/#?]+)"); //$NON-NLS-1$
+
+ public static class SolutionInstallationInfo {
+
+ private String requestUrl;
+
+ private String installId;
+
+ private String state;
+
+ private CatalogDescriptor catalogDescriptor;
+
+ public SolutionInstallationInfo() {
+ }
+
+ protected SolutionInstallationInfo(String installId, String state, CatalogDescriptor catalogDescriptor) {
+ super();
+ this.installId = installId;
+ this.state = state;
+ this.catalogDescriptor = catalogDescriptor;
+ }
+
+ public String getInstallId() {
+ return installId;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public CatalogDescriptor getCatalogDescriptor() {
+ return catalogDescriptor;
+ }
+
+ public void setRequestUrl(String requestUrl) {
+ this.requestUrl = requestUrl;
+ }
+
+ public String getRequestUrl() {
+ return requestUrl;
+ }
+ }
+
+ protected static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
+
+ private static final String PARAM_SPLIT_REGEX = "&"; //$NON-NLS-1$
+
+ private static final String EQUALS_REGEX = "="; //$NON-NLS-1$
+
+ private static final String MPC_STATE = "mpc_state"; //$NON-NLS-1$
+
+ private static final String MPC_INSTALL = "mpc_install"; //$NON-NLS-1$
+
+ public static SolutionInstallationInfo createSolutionInstallInfo(String url) {
+ String installId = null;
+ String state = null;
+ Map<String, String> query = parseQuery(url);
+ if (query != null) {
+ installId = query.get(MPC_INSTALL);
+ state = query.get(MPC_STATE);
+ }
+ if (installId != null) {
+ CatalogDescriptor descriptor = CatalogRegistry.getInstance().findCatalogDescriptor(url);
+ if (descriptor == null) {
+ try {
+ descriptor = new CatalogDescriptor(new URL(url), DESCRIPTOR_HINT);
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+ SolutionInstallationInfo info = new SolutionInstallationInfo(installId, state, descriptor);
+ info.setRequestUrl(url);
+ return info;
+ }
+ return null;
+ }
+
+ public static String getMPCState(String url) {
+ Map<String, String> query = parseQuery(url);
+ return query == null ? null : query.get(MPC_STATE);
+ }
+
+ private static Map<String, String> parseQuery(String url) {
+ String query;
+ try {
+ query = new URL(url).getQuery();
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ if (query == null) {
+ return null;
+ }
+ Map<String, String> values = new LinkedHashMap<String, String>();
+ String[] params = query.split(PARAM_SPLIT_REGEX);
+ for (String param : params) {
+ String[] keyValue = param.split(EQUALS_REGEX);
+ if (keyValue.length == 2) {
+ String key = keyValue[0];
+ String value = keyValue[1];
+ values.put(key, value);
+ }
+ }
+ return values;
+ }
+
+ public static boolean isPotentialSolution(String url) {
+ return url != null && url.contains(MPC_INSTALL);
+ }
+
+ public static void triggerInstall(SolutionInstallationInfo info) {
+ if (info.getRequestUrl() != null) {
+ MarketplaceClientUi.getLog().log(
+ new Status(IStatus.INFO, MarketplaceClientUi.BUNDLE_ID, NLS.bind(
+ Messages.MarketplaceUrlHandler_performInstallRequest, info.getRequestUrl())));
+ }
+ String installId = info.getInstallId();
+ String mpcState = info.getState();
+ CatalogDescriptor catalogDescriptor = info.getCatalogDescriptor();
+ MarketplaceWizardCommand command = new MarketplaceWizardCommand();
+ command.setSelectedCatalogDescriptor(catalogDescriptor);
+ try {
+ if (mpcState != null) {
+ command.setWizardState(URLDecoder.decode(mpcState, UTF_8));
+ }
+ Map<String, Operation> nodeToOperation = new HashMap<String, Operation>();
+ nodeToOperation.put(URLDecoder.decode(installId, UTF_8), Operation.INSTALL);
+ command.setOperations(nodeToOperation);
+ } catch (UnsupportedEncodingException e1) {
+ throw new IllegalStateException(e1);
+ }
+ try {
+ command.execute(new ExecutionEvent());
+ } catch (ExecutionException e) {
+ IStatus status = MarketplaceClientUi.computeStatus(e,
+ Messages.MarketplaceUrlHandler_cannotOpenMarketplaceWizard);
+ StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ }
+ }
+
+ public boolean handleUri(String uri) {
+ if (isPotentialSolution(uri)) {
+ SolutionInstallationInfo installInfo = createSolutionInstallInfo(uri);
+ if (installInfo != null) {
+ return handleInstallRequest(installInfo, uri);
+ }
+ }
+
+ CatalogDescriptor descriptor = CatalogRegistry.getInstance().findCatalogDescriptor(uri);
+ if (descriptor == null) {
+ descriptor = handleUnknownCatalog(uri);
+ if (descriptor == null) {
+ return false;
+ }
+ }
+
+ String baseUri;
+ try {
+ baseUri = descriptor.getUrl().toURI().toString();
+ if (!baseUri.endsWith("/")) { //$NON-NLS-1$
+ baseUri += '/';
+ }
+ } catch (URISyntaxException e) {
+ // should be unreachable
+ throw new IllegalStateException(e);
+ }
+
+ if (!uri.startsWith(baseUri)) {
+ uri = resolve(uri, baseUri, descriptor);
+ if (!uri.startsWith(baseUri)) {
+ return false;
+ }
+ }
+ String relativeUri = uri.substring(baseUri.length());
+ if (relativeUri.startsWith(DefaultMarketplaceService.API_FAVORITES_URI)) {
+ return handleFavorites(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_FEATURED_URI)) {
+ return handleFeatured(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_NODE_CONTENT_URI)) {
+ return handleNodeContent(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_NODE_URI)) {
+ return handleNode(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_POPULAR_URI)) {
+ return handlePopular(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_RECENT_URI)) {
+ return handleRecent(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(DefaultMarketplaceService.API_SEARCH_URI)
+ || relativeUri.startsWith(DefaultMarketplaceService.API_SEARCH_URI_FULL)) {
+ return handleSolrSearch(descriptor, relativeUri);
+ } else if (relativeUri.startsWith(SITE_SEARCH_URI.substring(1))) {
+ return handleSiteSearch(descriptor, relativeUri);
+ } else {
+ return handleUnknownPath(descriptor, relativeUri);
+ }
+ }
+
+ /**
+ * Resolve the given URL against the catalog's base URI. The default implementation changes the HTTP/HTTPS schema to
+ * match the catalog URI.
+ */
+ protected String resolve(String url, String baseUri, CatalogDescriptor descriptor) {
+ if (url.startsWith("https:") && baseUri.startsWith("http:")) { //$NON-NLS-1$ //$NON-NLS-2$
+ url = "http:" + url.substring("https:".length()); //$NON-NLS-1$ //$NON-NLS-2$
+ } else if (url.startsWith("http:") && baseUri.startsWith("https:")) { //$NON-NLS-1$ //$NON-NLS-2$
+ url = "https:" + url.substring("http:".length()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return url;
+ }
+
+ protected boolean handleUnknownPath(CatalogDescriptor descriptor, String url) {
+ return false;
+ }
+
+ private boolean handleSolrSearch(CatalogDescriptor descriptor, String url) {
+ try {
+ Map<String, String> params = new HashMap<String, String>();
+ String searchString = parseSearchQuery(descriptor, url, params);
+ return handleSearch(descriptor, url, searchString, params);
+ } catch (MalformedURLException e) {
+ // don't handle malformed URLs
+ return false;
+ } catch (URISyntaxException e) {
+ // don't handle malformed URLs
+ return false;
+ }
+ }
+
+ private boolean handleSiteSearch(CatalogDescriptor descriptor, String url) {
+ try {
+ Map<String, String> params = new HashMap<String, String>();
+ String searchString = parseSearchQuery(descriptor, url, params);
+
+ // convert queries of this format
+ // f[0]=im_taxonomy_vocabulary_1:38&f[1]=im_taxonomy_vocabulary_3:31
+ // to internal solr format
+ // filter=tid:38 tid:31
+ StringBuilder filter = new StringBuilder();
+ for (Iterator<String> i = params.values().iterator(); i.hasNext();) {
+ String str = i.next();
+ if (str.startsWith("im_taxonomy_vocabulary_")) { //$NON-NLS-1$
+ int sep = str.indexOf(':');
+ if (sep != -1) {
+ String tid = str.substring(sep + 1);
+ if (filter.length() > 0) {
+ filter.append(' ');
+ }
+ filter.append(tid);
+ i.remove();
+ }
+ }
+ }
+ return handleSearch(descriptor, url, searchString, params);
+ } catch (MalformedURLException e) {
+ // don't handle malformed URLs
+ return false;
+ } catch (URISyntaxException e) {
+ // don't handle malformed URLs
+ return false;
+ }
+ }
+
+ private String parseSearchQuery(CatalogDescriptor descriptor, String url, Map<String, String> params)
+ throws URISyntaxException, MalformedURLException {
+ URI searchUri = new URL(descriptor.getUrl(), url).toURI();
+ String path = searchUri.getPath();
+ if (path.endsWith("/")) { //$NON-NLS-1$
+ path = path.substring(0, path.length() - 1);
+ }
+ int sep = path.lastIndexOf('/');
+ String searchString = path.substring(sep + 1);
+ String query = searchUri.getQuery();
+ if (query != null) {
+ extractParams(query, params);
+ }
+ return searchString;
+ }
+
+ protected boolean handleSearch(CatalogDescriptor descriptor, String url, String searchString,
+ Map<String, String> params) {
+ return false;
+ }
+
+ private void extractParams(String query, Map<String, String> params) {
+ final String[] paramStrings = query.split("&"); //$NON-NLS-1$
+ for (String param : paramStrings) {
+ final String[] parts = param.split("="); //$NON-NLS-1$
+ if (parts.length == 2) {
+ params.put(parts[0], parts[1]);
+ }
+ }
+ }
+
+ protected boolean handleRecent(CatalogDescriptor descriptor, String url) {
+ return false;
+ }
+
+ protected boolean handlePopular(CatalogDescriptor descriptor, String url) {
+ return false;
+ }
+
+ private boolean handleNode(CatalogDescriptor descriptor, String url) {
+ Matcher matcher = NODE_URL_PATTERN.matcher(url);
+ String id = null;
+ if (matcher.find()) {
+ id = matcher.group(1);
+ }
+ Node node = new Node();
+ node.setId(id);
+ return handleNode(descriptor, url, node);
+ }
+
+ private boolean handleNodeContent(CatalogDescriptor descriptor, String url) {
+ Matcher matcher = CONTENT_URL_PATTERN.matcher(url);
+ String title = null;
+ if (matcher.find()) {
+ title = matcher.group(1);
+ }
+ Node node = new Node();
+ node.setUrl(url);
+ if (title != null) {
+ String base = descriptor.getUrl().toExternalForm();
+ if (!base.endsWith("/")) { //$NON-NLS-1$
+ base += "/"; //$NON-NLS-1$
+ }
+ int titleEnd = matcher.end();
+ if (titleEnd > -1) {
+ //clean the url of other query parameters
+ node.setUrl(base + url.substring(0, titleEnd));
+ } else {
+ //unknown format, leave as-is
+ node.setUrl(base + url);
+ }
+ }
+ return handleNode(descriptor, url, node);
+ }
+
+ protected boolean handleNode(CatalogDescriptor descriptor, String url, INode node) {
+ return false;
+ }
+
+ private boolean handleFeatured(CatalogDescriptor descriptor, String url) {
+ Matcher matcher = Pattern.compile("(?:^|/)featured/(\\d+)(?:,(\\d+))?").matcher(url); //$NON-NLS-1$
+ String cat = null;
+ String market = null;
+ if (matcher.find()) {
+ cat = matcher.group(1);
+ if (matcher.groupCount() > 1) {
+ market = matcher.group(2);
+ }
+ }
+ return handleFeatured(descriptor, url, cat, market);
+ }
+
+ protected boolean handleFeatured(CatalogDescriptor descriptor, String url, String category, String market) {
+ return false;
+ }
+
+ protected boolean handleFavorites(CatalogDescriptor descriptor, String url) {
+ return false;
+ }
+
+ /**
+ * Called if no known {@link CatalogDescriptor} is registered for the given URL. Clients may override to return a
+ * custom {@link CatalogDescriptor} or to perform additional lookup of registered catalogs.
+ * <p>
+ * The default implementation looks for catalogs registered for the same host but a different schema - if the url
+ * uses http, a catalog with an equivalent https url is searched and vice versa.
+ */
+ protected CatalogDescriptor handleUnknownCatalog(String url) {
+ if (url.startsWith("https:")) { //$NON-NLS-1$
+ url = "http:" + url.substring("https:".length()); //$NON-NLS-1$ //$NON-NLS-2$
+ return CatalogRegistry.getInstance().findCatalogDescriptor(url);
+ } else if (url.startsWith("http:")) { //$NON-NLS-1$
+ url = "https:" + url.substring("http:".length()); //$NON-NLS-1$ //$NON-NLS-2$
+ return CatalogRegistry.getInstance().findCatalogDescriptor(url);
+ }
+ return null;
+ }
+
+ protected boolean handleInstallRequest(SolutionInstallationInfo installInfo, String url) {
+ return false;
+ }
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Messages.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Messages.java
new file mode 100644
index 00000000..b37c0384
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Messages.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.epp.mpc.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.epp.mpc.ui.messages"; //$NON-NLS-1$
+
+ public static String MarketplaceUrlHandler_cannotOpenMarketplaceWizard;
+
+ public static String MarketplaceUrlHandler_performInstallRequest;
+
+ public static String Operation_install;
+
+ public static String Operation_uninstall;
+
+ public static String Operation_update;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Operation.java b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Operation.java
new file mode 100644
index 00000000..a9578601
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/Operation.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2014 The Eclipse Foundation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * The Eclipse Foundation - initial API and implementation
+ * Yatta Solutions - bug 432803: public API
+ *******************************************************************************/
+package org.eclipse.epp.mpc.ui;
+
+
+/**
+ * Represents kinds of provisioning operations supported by the wizard
+ */
+public enum Operation {
+ INSTALL(Messages.Operation_install), //
+ UNINSTALL(Messages.Operation_uninstall), //
+ UPDATE(Messages.Operation_update), //
+ NONE(null);
+
+ private final String label;
+
+ private Operation(String label) {
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
diff --git a/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/messages.properties b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/messages.properties
new file mode 100644
index 00000000..9a977dbd
--- /dev/null
+++ b/org.eclipse.epp.mpc.ui/src/org/eclipse/epp/mpc/ui/messages.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2014 The Eclipse Foundation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# The Eclipse Foundation - initial API and implementation
+###############################################################################
+MarketplaceUrlHandler_cannotOpenMarketplaceWizard=Cannot open Eclipse Marketplace
+MarketplaceUrlHandler_performInstallRequest=Performing Marketplace install request from {0}
+Operation_install=install
+Operation_uninstall=uninstall
+Operation_update=update

Back to the top