Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.gitignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.project34
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.core.prefs342
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.ui.prefs63
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.team.ui.prefs3
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.pde.prefs24
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF14
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/build.properties22
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.properties13
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.xml15
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/schema/connectorDiscovery.exsd434
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoverySource.java42
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoveryStrategy.java126
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/ConnectorDiscoveryExtensionReader.java266
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Directory.java70
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java135
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DiscoveryRegistryStrategy.java215
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/JarDiscoverySource.java53
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Messages.java79
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/RemoteBundleDiscoveryStrategy.java351
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/messages.properties34
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/DefaultSaxErrorHandler.java37
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/IOWithCauseException.java41
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/TransportUtil.java131
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery.compatibility/xsd/directory.xsd46
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.classpath11
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.gitignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.project34
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.core.prefs342
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.ui.prefs63
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.ltk.core.refactoring.prefs3
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.team.ui.prefs3
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.pde.prefs24
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/META-INF/MANIFEST.MF13
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/build.properties17
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/plugin.properties13
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractCatalogSource.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractDiscoveryStrategy.java79
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Catalog.java334
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/DiscoveryCore.java41
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Messages.java45
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Policy.java42
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/messages.properties17
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/AbstractCatalogItem.java29
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogCategory.java153
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogItem.java369
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Certification.java102
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/FeatureFilter.java69
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Group.java51
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Icon.java74
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Messages.java56
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Overview.java85
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Tag.java106
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/ValidationException.java31
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/messages.properties23
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogCategoryComparator.java51
-rw-r--r--bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogItemComparator.java74
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.classpath11
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.gitignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.project34
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.core.prefs342
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.ui.prefs63
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.team.ui.prefs3
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.pde.prefs24
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF18
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/build.properties19
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/plugin.properties17
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml83
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/AllDiscoveryTests.java38
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/DiscoveryTestConstants.java29
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/BundleDiscoveryStrategyTest.java97
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryRemoteTest.java85
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryTest.java161
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/DirectoryParserTest.java118
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/RemoteBundleDiscoveryStrategyTest.java74
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/AbstractMockFactory.java50
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogCategoryMockFactory.java66
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogItemMockFactory.java125
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockBundleDiscoveryStrategy.java41
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockCatalogSource.java32
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockDiscoveryStrategy.java89
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogCategoryComparatorTest.java80
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogConnectorComparatorTest.java84
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/.project17
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/build.properties1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/feature.xml20
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/.project17
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/build.properties1
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/feature.xml24
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/artifacts.jarbin0 -> 589 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/content.jarbin0 -> 994 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test1_1.0.0.201001200403.jarbin0 -> 387 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test2_1.0.0.201001200403.jarbin0 -> 407 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.gitignore1
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.project34
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.core.prefs339
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.ui.prefs63
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.team.ui.prefs3
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.pde.prefs24
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF26
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/build.properties19
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear-disabled.gifbin0 -> 314 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear.gifbin0 -> 322 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_disabled_obj.gifbin0 -> 237 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_obj.gifbin0 -> 585 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_update_obj.gifbin0 -> 332 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/message_info.gifbin0 -> 267 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/ovr32/message_warning.gifbin0 -> 591 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/icons/wizban/banner-discovery.pngbin0 -> 4291 bytes
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/plugin.properties13
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/plugin.xml36
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryImages.java101
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryUi.java65
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/Messages.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowBundleCatalogCommandHandler.java77
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowRepositoryCatalogCommandHandler.java70
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/messages.properties2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java353
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositoryDiscoveryStrategy.java240
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositorySource.java40
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/CommonColors.java186
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListItem.java282
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListViewer.java511
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/FilteredViewer.java328
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientCanvas.java341
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientToolTip.java81
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/Messages.java40
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/PatternFilter.java348
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/SelectionProviderAdapter.java78
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/WorkbenchUtil.java219
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/messages.properties14
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/AbstractDiscoveryItem.java113
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogConfiguration.java105
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogFilter.java23
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogPage.java101
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogViewer.java597
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CategoryItem.java94
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryItem.java268
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryResources.java132
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryWizard.java76
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/Messages.java84
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/OverviewToolTip.java215
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/messages.properties39
157 files changed, 12817 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.classpath b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.cvsignore b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.gitignore b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.gitignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.project b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.project
new file mode 100644
index 000000000..75f85193b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.p2.discovery.compatibility</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..1314ffa2f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,342 @@
+#Tue May 12 20:42:46 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=80
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..4cbefa939
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Tue May 12 20:42:43 PDT 2009
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Mylyn based on Eclipse
+formatter_settings_version=11
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*******************************************************************************\n * Copyright (c) 2010 Tasktop Technologies and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * Tasktop Technologies - initial API and implementation\n *******************************************************************************/\n\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ignore\n${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ignore</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.tasks.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..d8c6d26af
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.team.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 000000000..4ed1154fa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 16 15:42:51 PST 2010
+commit.comment.template=${connector.task.prefix} ${task.key} - ${task.description}
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..5937a85ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,24 @@
+#Tue May 20 17:39:22 PDT 2008
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=2
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..9188e6c8a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.equinox.p2.discovery.compatiblity;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.3.0",
+ org.eclipse.equinox.p2.core;bundle-version="2.0.0",
+ org.eclipse.equinox.p2.discovery;bundle-version="1.0.0",
+ org.eclipse.equinox.p2.repository;bundle-version="2.0.0"
+Export-Package: org.eclipse.equinox.internal.p2.discovery.compatibility;x-friends:="org.eclipse.equinox.p2.ui.discovery",
+ org.eclipse.equinox.internal.p2.discovery.compatibility.util;x-friends:="org.eclipse.equinox.p2.ui.discovery"
+Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/about.html b/bundles/org.eclipse.equinox.p2.discovery.compatibility/about.html
new file mode 100644
index 000000000..bc6e2b493
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>July 3, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
+
+
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/build.properties b/bundles/org.eclipse.equinox.p2.discovery.compatibility/build.properties
new file mode 100644
index 000000000..0f42be3b0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/build.properties
@@ -0,0 +1,22 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ schema/,\
+ plugin.properties,\
+ xsd/
+src.includes = about.html,\
+ schema/,\
+ xsd/
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.properties b/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.properties
new file mode 100644
index 000000000..38b4c3f0d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+extension-point.name = Connector Discovery
+Bundle-Vendor = Eclipse.org - Equinox
+Bundle-Name = Equinox Provisioning Discovery \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.xml b/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.xml
new file mode 100644
index 000000000..ea8a80782
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/plugin.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?><!--
+ Copyright (c) 2009 Tasktop Technologies 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
+ -->
+<plugin>
+ <extension-point id="org.eclipse.mylyn.discovery.core.connectorDiscovery" name="%extension-point.name" schema="schema/connectorDiscovery.exsd"/>
+
+</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/schema/connectorDiscovery.exsd b/bundles/org.eclipse.equinox.p2.discovery.compatibility/schema/connectorDiscovery.exsd
new file mode 100644
index 000000000..45056329f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/schema/connectorDiscovery.exsd
@@ -0,0 +1,434 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.mylyn.discovery.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.mylyn.discovery.core" id="connectorDiscovery" name="Connector Discovery"/>
+ </appinfo>
+ <documentation>
+ An extension point for contributing to the Mylyn connector discovery mechanism.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="connectorCategory" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="connectorDescriptor" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="certification" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="connectorDescriptor">
+ <annotation>
+ <documentation>
+ A description of a connector, including kinds, description, licensing and brand.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="featureFilter" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="icon" minOccurs="0" maxOccurs="1"/>
+ <element ref="overview" minOccurs="0" maxOccurs="1"/>
+ <element ref="iu" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="kind" type="string" use="required">
+ <annotation>
+ <documentation>
+ must be a comma-delimited list of the following values: &apos;document&apos;, &apos;task&apos;, &apos;vcs&apos;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ the name of the connector including the name of the organization that produces the repository if appropriate, for example &apos;Mozilla Bugzilla&apos;.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="provider" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the organization that supplies the connector.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="license" type="string" use="required">
+ <annotation>
+ <documentation>
+ The short name of the license, for example &apos;EPL 1.0&apos;, &apos;GPL 2.0&apos;, or &apos;Commercial&apos;.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ A description of the connector. Plug-ins should provide a description, especially if the description is not self-evident from the @name and @organization.
+
+Only the first 162 characters of the description are displayed in the UI and line breaks are ignored.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="siteUrl" type="string" use="required">
+ <annotation>
+ <documentation>
+ The URL of the update site containing the connector.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of the feature that installs this connector
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="categoryId" type="string" use="required">
+ <annotation>
+ <documentation>
+ the id of the connectorCategory in which this connector belongs
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.discovery.core.connectorDiscovery/connectorCategory/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="platformFilter" type="string">
+ <annotation>
+ <documentation>
+ E.g., &quot;(&amp; (osgi.os=macosx) (osgi.ws=carbon))&quot;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="groupId" type="string">
+ <annotation>
+ <documentation>
+ The id of the connectorCategory group. See group/@id for more details.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.discovery.core.connectorDiscovery/connectorDescriptor/@groupId"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="certificationId" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.discovery.core.connectorDiscovery/certification/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="connectorCategory">
+ <annotation>
+ <documentation>
+ a category of connectors, which is a way of organizing connectors in top-level groups.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="icon" minOccurs="0" maxOccurs="1"/>
+ <element ref="overview" minOccurs="0" maxOccurs="1"/>
+ <element ref="group" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ an id that uniquely identifies the category
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ the name of the category, as it is displayed in the ui.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string" use="required">
+ <annotation>
+ <documentation>
+ A description of the category
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="relevance" type="string">
+ <annotation>
+ <documentation>
+ A relevance, which is a number from 0 to 100. Categories with higher relevance are displayed with preference in the UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="icon">
+ <complexType>
+ <attribute name="image16" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="image32" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="image48" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="image64" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="image128" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="overview">
+ <annotation>
+ <documentation>
+ An overview that provides more detailed information, which may include a summary, url and screenshot.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="summary" type="string">
+ <annotation>
+ <documentation>
+ A description providing detailed information about the item. Newlines can be used to format the text into multiple paragraphs if necessary. Text must fit into an area 320x240, otherwise it will be truncated in the UI. More lengthy descriptions can be provided on a web page if required, see @url.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="url" type="string">
+ <annotation>
+ <documentation>
+ An URL that points to a web page with more information relevant to the connector or category.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="screenshot" type="string">
+ <annotation>
+ <documentation>
+ 320x240 PNG, JPEG or GIF
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="featureFilter">
+ <annotation>
+ <documentation>
+ A means of specifying that a feature must be present in order for the connectorDescriptor to be presented to the user.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="featureId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of the feature to test
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="version" type="string" use="required">
+ <annotation>
+ <documentation>
+ A version specifier, specified in the same manner as version dependencies are specified in an OSGi manifest. For example: &quot;[3.0,4.0)&quot;
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="group">
+ <annotation>
+ <documentation>
+ groups provide a way to anchor connectors in a grouping with other like entries.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ An identifier that identifies the group. Must be unique for a particular connectorCategory.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="certification">
+ <complexType>
+ <sequence>
+ <element ref="icon" minOccurs="0" maxOccurs="1"/>
+ <element ref="description"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ An id that uniquely identifies the certification.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ The name of the certification, as it is displayed in the ui.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="url" type="string">
+ <annotation>
+ <documentation>
+ An URL that points to a web page with more information relevant to the certification.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="description" type="string">
+ <annotation>
+ <appinfo>
+ <meta.element translatable="true"/>
+ </appinfo>
+ <documentation>
+ A textual description.
+ </documentation>
+ </annotation>
+ </element>
+
+ <element name="iu">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of the feature that is to be installed.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 3.2
+ </documentation>
+ </annotation>
+
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2009 Tasktop Technologies 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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoverySource.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoverySource.java
new file mode 100644
index 000000000..4bf939f12
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoverySource.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.net.URL;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author David Green
+ */
+public class BundleDiscoverySource extends AbstractCatalogSource {
+
+ private final Bundle bundle;
+
+ public BundleDiscoverySource(Bundle bundle) {
+ if (bundle == null) {
+ throw new IllegalArgumentException();
+ }
+ this.bundle = bundle;
+ }
+
+ @Override
+ public Object getId() {
+ return "bundle:" + bundle.getSymbolicName(); //$NON-NLS-1$
+ }
+
+ @Override
+ public URL getResource(String relativeUrl) {
+ return bundle.getEntry(relativeUrl);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoveryStrategy.java
new file mode 100644
index 000000000..9abbca19d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/BundleDiscoveryStrategy.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.AbstractDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.discovery.Policy;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.internal.p2.discovery.model.ValidationException;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+
+/**
+ * A strategy for discovering via installed platform {@link Bundle bundles}.
+ *
+ * @author David Green
+ */
+public class BundleDiscoveryStrategy extends AbstractDiscoveryStrategy {
+
+ @Override
+ public void performDiscovery(IProgressMonitor monitor) throws CoreException {
+ if (items == null || categories == null) {
+ throw new IllegalStateException();
+ }
+ IExtensionPoint extensionPoint = getExtensionRegistry().getExtensionPoint(
+ ConnectorDiscoveryExtensionReader.EXTENSION_POINT_ID);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ monitor.beginTask(Messages.BundleDiscoveryStrategy_task_loading_local_extensions, extensions.length == 0 ? 1
+ : extensions.length);
+ try {
+ if (extensions.length > 0) {
+ processExtensions(new SubProgressMonitor(monitor, extensions.length), extensions);
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ protected void processExtensions(IProgressMonitor monitor, IExtension[] extensions) {
+ monitor.beginTask(Messages.BundleDiscoveryStrategy_task_processing_extensions, extensions.length == 0 ? 1
+ : extensions.length);
+ try {
+ ConnectorDiscoveryExtensionReader extensionReader = new ConnectorDiscoveryExtensionReader();
+
+ for (IExtension extension : extensions) {
+ AbstractCatalogSource discoverySource = computeDiscoverySource(extension.getContributor());
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if (monitor.isCanceled()) {
+ return;
+ }
+ try {
+ if (ConnectorDiscoveryExtensionReader.CONNECTOR_DESCRIPTOR.equals(element.getName())) {
+ CatalogItem descriptor = extensionReader.readConnectorDescriptor(element, CatalogItem.class);
+ descriptor.setSource(discoverySource);
+ items.add(descriptor);
+ } else if (ConnectorDiscoveryExtensionReader.CONNECTOR_CATEGORY.equals(element.getName())) {
+ CatalogCategory category = extensionReader.readConnectorCategory(element,
+ CatalogCategory.class);
+ category.setSource(discoverySource);
+ if (!discoverySource.getPolicy().isPermitCategories()) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.BundleDiscoveryStrategy_categoryDisallowed, new Object[] {
+ category.getName(), category.getId(),
+ element.getContributor().getName() }), null));
+ } else {
+ categories.add(category);
+ }
+ } else if (ConnectorDiscoveryExtensionReader.CERTIFICATION.equals(element.getName())) {
+ Certification certification = extensionReader.readCertification(element,
+ Certification.class);
+ certification.setSource(discoverySource);
+ certifications.add(certification);
+ } else {
+ throw new ValidationException(NLS.bind(Messages.BundleDiscoveryStrategy_unexpected_element,
+ element.getName()));
+ }
+ } catch (ValidationException e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ NLS.bind(Messages.BundleDiscoveryStrategy_3, element.getContributor().getName(),
+ e.getMessage()), e));
+ }
+ }
+ monitor.worked(1);
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ protected AbstractCatalogSource computeDiscoverySource(IContributor contributor) {
+ Policy policy = new Policy(true);
+ BundleDiscoverySource bundleDiscoverySource = new BundleDiscoverySource(
+ Platform.getBundle(contributor.getName()));
+ bundleDiscoverySource.setPolicy(policy);
+ return bundleDiscoverySource;
+ }
+
+ protected IExtensionRegistry getExtensionRegistry() {
+ return Platform.getExtensionRegistry();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/ConnectorDiscoveryExtensionReader.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/ConnectorDiscoveryExtensionReader.java
new file mode 100644
index 000000000..724434bb7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/ConnectorDiscoveryExtensionReader.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Task top Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.internal.p2.discovery.model.FeatureFilter;
+import org.eclipse.equinox.internal.p2.discovery.model.Group;
+import org.eclipse.equinox.internal.p2.discovery.model.Icon;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+import org.eclipse.equinox.internal.p2.discovery.model.ValidationException;
+
+/**
+ * Connector Discovery extension point reader, for extension points of type
+ * <tt>org.eclipse.mylyn.discovery.core.connectorDiscovery</tt>
+ *
+ * @author David Green
+ */
+public class ConnectorDiscoveryExtensionReader {
+
+ public static final String EXTENSION_POINT_ID = "org.eclipse.mylyn.discovery.core.connectorDiscovery"; //$NON-NLS-1$
+
+ public static final String CONNECTOR_DESCRIPTOR = "connectorDescriptor"; //$NON-NLS-1$
+
+ public static final String CONNECTOR_CATEGORY = "connectorCategory"; //$NON-NLS-1$
+
+ public static final String CERTIFICATION = "certification"; //$NON-NLS-1$
+
+ public static final String ICON = "icon"; //$NON-NLS-1$
+
+ public static final String OVERVIEW = "overview"; //$NON-NLS-1$
+
+ public static final String FEATURE_FILTER = "featureFilter"; //$NON-NLS-1$
+
+ public static final String GROUP = "group"; //$NON-NLS-1$
+
+ public static Tag DOCUMENT = new Tag("document", Messages.ConnectorDiscoveryExtensionReader_Documents); //$NON-NLS-1$
+
+ public static Tag TASK = new Tag("task", Messages.ConnectorDiscoveryExtensionReader_Tasks); //$NON-NLS-1$
+
+ public static Tag VCS = new Tag("vcs", Messages.ConnectorDiscoveryExtensionReader_Version_Control); //$NON-NLS-1$
+
+ public static final Tag[] TAGS = new Tag[] { DOCUMENT, TASK, VCS };
+
+ /**
+ * return the enum constant whose {@link #getValue() value} is the same as the given value.
+ *
+ * @param value
+ * the string value, or null
+ * @return the corresponding enum constant or null if the given value was null
+ * @throws IllegalArgumentException
+ * if the given value does not correspond to any enum constant
+ */
+ public static Tag fromValue(String value) throws IllegalArgumentException {
+ if (value == null) {
+ return null;
+ }
+ for (Tag tag : TAGS) {
+ if (tag.getValue().equals(value)) {
+ return tag;
+ }
+ }
+ throw new IllegalArgumentException(value);
+ }
+
+ public CatalogItem readConnectorDescriptor(IConfigurationElement element) throws ValidationException {
+ return readConnectorDescriptor(element, CatalogItem.class);
+ }
+
+ public <T extends CatalogItem> T readConnectorDescriptor(IConfigurationElement element, Class<T> clazz)
+ throws ValidationException {
+ T connectorDescriptor;
+ try {
+ connectorDescriptor = clazz.newInstance();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ try {
+ String kinds = element.getAttribute("kind"); //$NON-NLS-1$
+ if (kinds != null) {
+ String[] akinds = kinds.split("\\s*,\\s*"); //$NON-NLS-1$
+ for (String kind : akinds) {
+ connectorDescriptor.addTag(fromValue(kind));
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_value_kind);
+ }
+ connectorDescriptor.setName(element.getAttribute("name")); //$NON-NLS-1$
+ connectorDescriptor.setProvider(element.getAttribute("provider")); //$NON-NLS-1$
+ connectorDescriptor.setLicense(element.getAttribute("license")); //$NON-NLS-1$
+ connectorDescriptor.setDescription(element.getAttribute("description")); //$NON-NLS-1$
+ connectorDescriptor.setSiteUrl(element.getAttribute("siteUrl")); //$NON-NLS-1$
+ connectorDescriptor.setId(element.getAttribute("id")); //$NON-NLS-1$
+ connectorDescriptor.setCategoryId(element.getAttribute("categoryId")); //$NON-NLS-1$
+ connectorDescriptor.setCertificationId(element.getAttribute("certificationId")); //$NON-NLS-1$
+ connectorDescriptor.setPlatformFilter(element.getAttribute("platformFilter")); //$NON-NLS-1$
+ connectorDescriptor.setGroupId(element.getAttribute("groupId")); //$NON-NLS-1$
+
+ IConfigurationElement[] children = element.getChildren("iu"); //$NON-NLS-1$
+ if (children.length > 0) {
+ for (IConfigurationElement child : children) {
+ connectorDescriptor.getInstallableUnits().add(child.getAttribute("id")); //$NON-NLS-1$
+ }
+ } else {
+ // no particular iu specified, use connector id
+ connectorDescriptor.getInstallableUnits().add(connectorDescriptor.getId());
+ }
+ for (IConfigurationElement child : element.getChildren("featureFilter")) { //$NON-NLS-1$
+ FeatureFilter featureFilterItem = readFeatureFilter(child);
+ featureFilterItem.setItem(connectorDescriptor);
+ connectorDescriptor.getFeatureFilter().add(featureFilterItem);
+ }
+ for (IConfigurationElement child : element.getChildren("icon")) { //$NON-NLS-1$
+ Icon iconItem = readIcon(child);
+ if (connectorDescriptor.getIcon() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_icon);
+ }
+ connectorDescriptor.setIcon(iconItem);
+ }
+ for (IConfigurationElement child : element.getChildren("overview")) { //$NON-NLS-1$
+ Overview overviewItem = readOverview(child);
+ overviewItem.setItem(connectorDescriptor);
+ if (connectorDescriptor.getOverview() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_overview);
+ }
+ connectorDescriptor.setOverview(overviewItem);
+ }
+
+ connectorDescriptor.validate();
+
+ return connectorDescriptor;
+ }
+
+ public CatalogCategory readConnectorCategory(IConfigurationElement element) throws ValidationException {
+ return readConnectorCategory(element, CatalogCategory.class);
+ }
+
+ public <T extends CatalogCategory> T readConnectorCategory(IConfigurationElement element, Class<T> clazz)
+ throws ValidationException {
+ T connectorCategory;
+ try {
+ connectorCategory = clazz.newInstance();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ connectorCategory.setId(element.getAttribute("id")); //$NON-NLS-1$
+ connectorCategory.setName(element.getAttribute("name")); //$NON-NLS-1$
+ connectorCategory.setDescription(element.getAttribute("description")); //$NON-NLS-1$
+ connectorCategory.setRelevance(element.getAttribute("relevance")); //$NON-NLS-1$
+
+ for (IConfigurationElement child : element.getChildren("icon")) { //$NON-NLS-1$
+ Icon iconItem = readIcon(child);
+ if (connectorCategory.getIcon() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_icon);
+ }
+ connectorCategory.setIcon(iconItem);
+ }
+ for (IConfigurationElement child : element.getChildren("overview")) { //$NON-NLS-1$
+ Overview overviewItem = readOverview(child);
+ overviewItem.setCategory(connectorCategory);
+ if (connectorCategory.getOverview() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_overview);
+ }
+ connectorCategory.setOverview(overviewItem);
+ }
+ for (IConfigurationElement child : element.getChildren("group")) { //$NON-NLS-1$
+ Group groupItem = readGroup(child);
+ groupItem.setCategory(connectorCategory);
+ connectorCategory.getGroup().add(groupItem);
+ }
+
+ connectorCategory.validate();
+
+ return connectorCategory;
+ }
+
+ public <T extends Certification> T readCertification(IConfigurationElement element, Class<T> clazz)
+ throws ValidationException {
+ T certification;
+ try {
+ certification = clazz.newInstance();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+
+ certification.setId(element.getAttribute("id")); //$NON-NLS-1$
+ certification.setName(element.getAttribute("name")); //$NON-NLS-1$
+ certification.setUrl(element.getAttribute("url")); //$NON-NLS-1$
+
+ for (IConfigurationElement child : element.getChildren("icon")) { //$NON-NLS-1$
+ Icon iconItem = readIcon(child);
+ if (certification.getIcon() != null) {
+ throw new ValidationException(Messages.ConnectorDiscoveryExtensionReader_unexpected_element_icon);
+ }
+ certification.setIcon(iconItem);
+ }
+ for (IConfigurationElement child : element.getChildren("description")) { //$NON-NLS-1$
+ certification.setDescription(child.getValue());
+ }
+ certification.validate();
+
+ return certification;
+ }
+
+ public Icon readIcon(IConfigurationElement element) throws ValidationException {
+ Icon icon = new Icon();
+
+ icon.setImage16(element.getAttribute("image16")); //$NON-NLS-1$
+ icon.setImage32(element.getAttribute("image32")); //$NON-NLS-1$
+ icon.setImage48(element.getAttribute("image48")); //$NON-NLS-1$
+ icon.setImage64(element.getAttribute("image64")); //$NON-NLS-1$
+ icon.setImage128(element.getAttribute("image128")); //$NON-NLS-1$
+
+ icon.validate();
+
+ return icon;
+ }
+
+ public Overview readOverview(IConfigurationElement element) throws ValidationException {
+ Overview overview = new Overview();
+
+ overview.setSummary(element.getAttribute("summary")); //$NON-NLS-1$
+ overview.setUrl(element.getAttribute("url")); //$NON-NLS-1$
+ overview.setScreenshot(element.getAttribute("screenshot")); //$NON-NLS-1$
+
+ overview.validate();
+
+ return overview;
+ }
+
+ public FeatureFilter readFeatureFilter(IConfigurationElement element) throws ValidationException {
+ FeatureFilter featureFilter = new FeatureFilter();
+
+ featureFilter.setFeatureId(element.getAttribute("featureId")); //$NON-NLS-1$
+ featureFilter.setVersion(element.getAttribute("version")); //$NON-NLS-1$
+
+ featureFilter.validate();
+
+ return featureFilter;
+ }
+
+ public Group readGroup(IConfigurationElement element) throws ValidationException {
+ Group group = new Group();
+
+ group.setId(element.getAttribute("id")); //$NON-NLS-1$
+
+ group.validate();
+
+ return group;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Directory.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Directory.java
new file mode 100644
index 000000000..04322881f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Directory.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A directory representing locations of discovery sources.
+ *
+ * @author David Green
+ */
+public class Directory {
+
+ /**
+ * an entry in the directory, which represents a specific discovery source. Future versions of this class may
+ * include policy or other attributes declared by the directory.
+ */
+ public static final class Entry {
+ private String location;
+
+ private boolean permitCategories;
+
+ public Entry() {
+ }
+
+ /**
+ * the location of the entry (an URL)
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * the location of the entry (an URL)
+ */
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ /**
+ * indicate if creation of categories by this location is permitted
+ */
+ public boolean isPermitCategories() {
+ return permitCategories;
+ }
+
+ /**
+ * indicate if creation of categories by this location is permitted
+ */
+ public void setPermitCategories(boolean permitCategories) {
+ this.permitCategories = permitCategories;
+ }
+ }
+
+ private final List<Entry> entries = new ArrayList<Entry>();
+
+ public List<Entry> getEntries() {
+ return entries;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java
new file mode 100644
index 000000000..86e2ef938
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DirectoryParser.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.eclipse.equinox.internal.p2.discovery.compatibility.Directory.Entry;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.util.DefaultSaxErrorHandler;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.util.IOWithCauseException;
+import org.eclipse.osgi.util.NLS;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * A parser for {@link Directory directories}.
+ *
+ * @author David Green
+ */
+public class DirectoryParser {
+ /**
+ * parse the contents of a directory. The caller must close the given reader.
+ *
+ * @param directoryContents
+ * the contents of the directory
+ * @return a directory with 0 or more entries
+ * @throws IOException
+ * if the directory cannot be read.
+ */
+ public Directory parse(Reader directoryContents) throws IOException {
+ XMLReader xmlReader;
+ try {
+ xmlReader = XMLReaderFactory.createXMLReader();
+ } catch (SAXException e) {
+ throw new IOWithCauseException(e.getMessage(), e);
+ }
+ xmlReader.setErrorHandler(new DefaultSaxErrorHandler());
+
+ DirectoryContentHandler contentHandler = new DirectoryContentHandler();
+ xmlReader.setContentHandler(contentHandler);
+
+ try {
+ xmlReader.parse(new InputSource(directoryContents));
+ } catch (SAXException e) {
+ throw new IOWithCauseException(e.getMessage(), e);
+ }
+
+ if (contentHandler.directory == null) {
+ throw new IOException(Messages.DirectoryParser_no_directory);
+ }
+
+ return contentHandler.directory;
+ }
+
+ private class DirectoryContentHandler implements ContentHandler {
+
+ Directory directory;
+
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ // ignore
+ }
+
+ public void endDocument() throws SAXException {
+ // ignore
+ }
+
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ // ignore
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ // ignore
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ // ignore
+ }
+
+ public void processingInstruction(String target, String data) throws SAXException {
+ // ignore
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ // ignore
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ // ignore
+ }
+
+ public void startDocument() throws SAXException {
+ // ignore
+ }
+
+ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+ if ("directory".equals(localName)) { //$NON-NLS-1$
+ if (directory != null) {
+ unexpectedElement(localName);
+ }
+ directory = new Directory();
+ } else if (directory != null && "entry".equals(localName)) { //$NON-NLS-1$
+ String url = atts.getValue("", "url"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (url != null && url.length() > 0) {
+ Entry entry = new Entry();
+ entry.setLocation(url);
+ entry.setPermitCategories(Boolean.parseBoolean(atts.getValue("permitCategories"))); //$NON-NLS-1$
+ directory.getEntries().add(entry);
+ }
+ }
+ // else ignore
+ }
+
+ private void unexpectedElement(String localName) throws SAXException {
+ throw new SAXException(NLS.bind(Messages.DirectoryParser_unexpected_element, localName));
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ // ignore
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DiscoveryRegistryStrategy.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DiscoveryRegistryStrategy.java
new file mode 100644
index 000000000..893aaa8ae
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/DiscoveryRegistryStrategy.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.spi.IDynamicExtensionRegistry;
+import org.eclipse.core.runtime.spi.RegistryContributor;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.Directory.Entry;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author David Green
+ */
+class DiscoveryRegistryStrategy extends RegistryStrategy {
+
+ private final List<JarFile> jars = new ArrayList<JarFile>();
+
+ private final Map<IContributor, File> contributorToJarFile = new HashMap<IContributor, File>();
+
+ private final Map<IContributor, Entry> contributorToDirectoryEntry = new HashMap<IContributor, Entry>();
+
+ private final Object token;
+
+ private Map<File, Entry> bundleFileToDirectoryEntry;
+
+ public DiscoveryRegistryStrategy(File[] storageDirs, boolean[] cacheReadOnly, Object token) {
+ super(storageDirs, cacheReadOnly);
+ this.token = token;
+ }
+
+ @Override
+ public void onStart(IExtensionRegistry registry, boolean loadedFromCache) {
+ super.onStart(registry, loadedFromCache);
+ if (!loadedFromCache) {
+ processDiscoveryCoreBundle(registry);
+ processBundles(registry);
+ }
+ }
+
+ private void processDiscoveryCoreBundle(IExtensionRegistry registry) {
+ // we must add a contribution from the core bundle so that we get the
+ // extension point itself
+ try {
+ Bundle bundle = Platform.getBundle("org.eclipse.equinox.p2.discovery.compatiblity"); //$NON-NLS-1$
+ IContributor contributor = new RegistryContributor(bundle.getSymbolicName(), bundle.getSymbolicName(),
+ null, null);
+
+ InputStream inputStream = bundle.getEntry("plugin.xml").openStream(); //$NON-NLS-1$
+ try {
+ registry.addContribution(inputStream, contributor, false, bundle.getSymbolicName(), null, token);
+ } finally {
+ inputStream.close();
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException();
+ }
+ }
+
+ private void processBundles(IExtensionRegistry registry) {
+ if (bundleFileToDirectoryEntry == null) {
+ throw new IllegalStateException();
+ }
+ for (java.util.Map.Entry<File, Entry> bundleFile : bundleFileToDirectoryEntry.entrySet()) {
+ try {
+ processBundle(registry, bundleFile.getValue(), bundleFile.getKey());
+ } catch (Exception e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.DiscoveryRegistryStrategy_cannot_load_bundle, new Object[] {
+ bundleFile.getKey().getName(), bundleFile.getValue().getLocation(), e.getMessage() }),
+ e));
+ }
+ }
+ }
+
+ private void processBundle(IExtensionRegistry registry, Directory.Entry entry, File bundleFile) throws IOException {
+ JarFile jarFile = new JarFile(bundleFile);
+ jars.add(jarFile);
+
+ ZipEntry pluginXmlEntry = jarFile.getEntry("plugin.xml"); //$NON-NLS-1$
+ if (pluginXmlEntry == null) {
+ throw new IOException(Messages.DiscoveryRegistryStrategy_missing_pluginxml);
+ }
+ IContributor contributor = new RegistryContributor(bundleFile.getName(), bundleFile.getName(), null, null);
+ if (((IDynamicExtensionRegistry) registry).hasContributor(contributor)) {
+ jarFile.close();
+ return;
+ }
+ contributorToJarFile.put(contributor, bundleFile);
+ contributorToDirectoryEntry.put(contributor, entry);
+
+ ResourceBundle translationBundle = loadTranslationBundle(jarFile);
+
+ InputStream inputStream = jarFile.getInputStream(pluginXmlEntry);
+ try {
+ registry.addContribution(inputStream, contributor, false, bundleFile.getPath(), translationBundle, token);
+ } finally {
+ inputStream.close();
+ }
+ }
+
+ private ResourceBundle loadTranslationBundle(JarFile jarFile) throws IOException {
+ List<String> bundleNames = computeBundleNames("plugin"); //$NON-NLS-1$
+ for (String bundleName : bundleNames) {
+ ZipEntry entry = jarFile.getEntry(bundleName);
+ if (entry != null) {
+ InputStream inputStream = jarFile.getInputStream(entry);
+ try {
+ PropertyResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
+ return resourceBundle;
+ } finally {
+ inputStream.close();
+ }
+ }
+ }
+ return null;
+ }
+
+ private List<String> computeBundleNames(String baseName) {
+ String suffix = ".properties"; //$NON-NLS-1$
+ String name = baseName;
+ List<String> bundleNames = new ArrayList<String>();
+ Locale locale = Locale.getDefault();
+ bundleNames.add(name + suffix);
+ if (locale.getLanguage() != null && locale.getLanguage().length() > 0) {
+ name = name + '_' + locale.getLanguage();
+ bundleNames.add(0, name + suffix);
+ }
+ if (locale.getCountry() != null && locale.getCountry().length() > 0) {
+ name = name + '_' + locale.getCountry();
+ bundleNames.add(0, name + suffix);
+ }
+ if (locale.getVariant() != null && locale.getVariant().length() > 0) {
+ name = name + '_' + locale.getVariant();
+ bundleNames.add(0, name + suffix);
+ }
+ return bundleNames;
+ }
+
+ @Override
+ public void onStop(IExtensionRegistry registry) {
+ try {
+ super.onStop(registry);
+ } finally {
+ for (JarFile jar : jars) {
+ try {
+ jar.close();
+ } catch (Exception e) {
+ }
+ }
+ jars.clear();
+ }
+ }
+
+ /**
+ * get the jar file that corresponds to the given contributor.
+ *
+ * @throws IllegalArgumentException
+ * if the given contributor is unknown
+ */
+ public File getJarFile(IContributor contributor) {
+ File file = contributorToJarFile.get(contributor);
+ if (file == null) {
+ throw new IllegalArgumentException(contributor.getName());
+ }
+ return file;
+ }
+
+ /**
+ * get the directory entry that corresponds to the given contributor.
+ *
+ * @throws IllegalArgumentException
+ * if the given contributor is unknown
+ */
+ public Entry getDirectoryEntry(IContributor contributor) {
+ Entry entry = contributorToDirectoryEntry.get(contributor);
+ if (entry == null) {
+ throw new IllegalArgumentException(contributor.getName());
+ }
+ return entry;
+ }
+
+ public void setBundles(Map<File, Entry> bundleFileToDirectoryEntry) {
+ this.bundleFileToDirectoryEntry = bundleFileToDirectoryEntry;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/JarDiscoverySource.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/JarDiscoverySource.java
new file mode 100644
index 000000000..a5da28528
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/JarDiscoverySource.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+
+/**
+ * @author David Green
+ */
+public class JarDiscoverySource extends AbstractCatalogSource {
+
+ private final String id;
+
+ private final File jarFile;
+
+ public JarDiscoverySource(String id, File jarFile) {
+ this.id = id;
+ this.jarFile = jarFile;
+ }
+
+ @Override
+ public Object getId() {
+ return id;
+ }
+
+ @Override
+ public URL getResource(String resourceName) {
+ try {
+ String prefix = jarFile.toURI().toURL().toExternalForm();
+
+ return new URL("jar:" + prefix + "!/" + URLEncoder.encode(resourceName, "utf-8")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ } catch (MalformedURLException e) {
+ throw new IllegalStateException(e);
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Messages.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Messages.java
new file mode 100644
index 000000000..824601623
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/Messages.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.discovery.compatibility.messages"; //$NON-NLS-1$
+
+ public static String BundleDiscoveryStrategy_3;
+
+ public static String BundleDiscoveryStrategy_categoryDisallowed;
+
+ public static String BundleDiscoveryStrategy_task_loading_local_extensions;
+
+ public static String BundleDiscoveryStrategy_task_processing_extensions;
+
+ public static String BundleDiscoveryStrategy_unexpected_element;
+
+ public static String ConnectorDiscoveryExtensionReader_Documents;
+
+ public static String ConnectorDiscoveryExtensionReader_Tasks;
+
+ public static String ConnectorDiscoveryExtensionReader_unexpected_element_icon;
+
+ public static String ConnectorDiscoveryExtensionReader_unexpected_element_overview;
+
+ public static String ConnectorDiscoveryExtensionReader_unexpected_value_kind;
+
+ public static String ConnectorDiscoveryExtensionReader_Version_Control;
+
+ public static String DirectoryParser_no_directory;
+
+ public static String DirectoryParser_unexpected_element;
+
+ public static String DiscoveryRegistryStrategy_cannot_load_bundle;
+
+ public static String DiscoveryRegistryStrategy_missing_pluginxml;
+
+ public static String RemoteBundleDiscoveryStrategy_cannot_download_bundle;
+
+ public static String RemoteBundleDiscoveryStrategy_empty_directory;
+
+ public static String RemoteBundleDiscoveryStrategy_Invalid_source_specified_Error;
+
+ public static String RemoteBundleDiscoveryStrategy_io_failure_discovery_directory;
+
+ public static String RemoteBundleDiscoveryStrategy_io_failure_temp_storage;
+
+ public static String RemoteBundleDiscoveryStrategy_task_remote_discovery;
+
+ public static String RemoteBundleDiscoveryStrategy_unexpectedError;
+
+ public static String RemoteBundleDiscoveryStrategy_unknown_host_discovery_directory;
+
+ public static String RemoteBundleDiscoveryStrategy_unrecognized_discovery_url;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/RemoteBundleDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/RemoteBundleDiscoveryStrategy.java
new file mode 100644
index 000000000..0894b0115
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/RemoteBundleDiscoveryStrategy.java
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.eclipse.core.internal.registry.ExtensionRegistry;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.discovery.Policy;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.Directory.Entry;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.util.TransportUtil;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.util.TransportUtil.TextContentProcessor;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A discovery strategy that downloads a simple directory of remote jars. The directory is first downloaded, then each
+ * remote jar is downloaded.
+ *
+ * @author David Green
+ */
+@SuppressWarnings("restriction")
+public class RemoteBundleDiscoveryStrategy extends BundleDiscoveryStrategy {
+
+ private String directoryUrl;
+
+ private DiscoveryRegistryStrategy registryStrategy;
+
+ private File temporaryStorage;
+
+ private int maxDiscoveryJarDownloadAttempts = 1;
+
+ @Override
+ public void performDiscovery(IProgressMonitor monitor) throws CoreException {
+ if (items == null || categories == null || directoryUrl == null) {
+ throw new IllegalStateException();
+ }
+ if (registryStrategy != null) {
+ throw new IllegalStateException();
+ }
+
+ final int totalTicks = 100000;
+ final int ticksTenPercent = totalTicks / 10;
+ monitor.beginTask(Messages.RemoteBundleDiscoveryStrategy_task_remote_discovery, totalTicks);
+ try {
+ File registryCacheFolder;
+ try {
+ if (temporaryStorage != null && temporaryStorage.exists()) {
+ delete(temporaryStorage);
+ }
+ temporaryStorage = File.createTempFile(RemoteBundleDiscoveryStrategy.class.getSimpleName(), ".tmp"); //$NON-NLS-1$
+ temporaryStorage.delete();
+ if (!temporaryStorage.mkdirs()) {
+ throw new IOException();
+ }
+ registryCacheFolder = new File(temporaryStorage, ".rcache"); //$NON-NLS-1$
+ if (!registryCacheFolder.mkdirs()) {
+ throw new IOException();
+ }
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ Messages.RemoteBundleDiscoveryStrategy_io_failure_temp_storage, e));
+ }
+ if (monitor.isCanceled()) {
+ return;
+ }
+
+ Directory directory;
+ try {
+ final Directory[] temp = new Directory[1];
+ TransportUtil.readResource(new URI(directoryUrl), new TextContentProcessor() {
+ public void process(Reader reader) throws IOException {
+ DirectoryParser parser = new DirectoryParser();
+ temp[0] = parser.parse(reader);
+ }
+ }, new SubProgressMonitor(monitor, ticksTenPercent));
+ directory = temp[0];
+ if (directory == null) {
+ throw new IllegalStateException();
+ }
+ } catch (UnknownHostException e) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.RemoteBundleDiscoveryStrategy_unknown_host_discovery_directory, e.getMessage()), e));
+ } catch (URISyntaxException e) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.RemoteBundleDiscoveryStrategy_Invalid_source_specified_Error, directoryUrl), e));
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ Messages.RemoteBundleDiscoveryStrategy_io_failure_discovery_directory, e));
+ }
+ if (monitor.isCanceled()) {
+ return;
+ }
+ if (directory.getEntries().isEmpty()) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ Messages.RemoteBundleDiscoveryStrategy_empty_directory));
+ }
+
+ Map<File, Directory.Entry> bundleFileToDirectoryEntry = new HashMap<File, Directory.Entry>();
+
+ ExecutorService executorService = createExecutorService(directory.getEntries().size());
+ try {
+ List<Future<DownloadBundleJob>> futures = new ArrayList<Future<DownloadBundleJob>>();
+ // submit jobs
+ for (Directory.Entry entry : directory.getEntries()) {
+ futures.add(executorService.submit(new DownloadBundleJob(entry, monitor)));
+ }
+ int futureSize = ticksTenPercent * 4 / directory.getEntries().size();
+ // collect job results
+ for (Future<DownloadBundleJob> job : futures) {
+ try {
+ DownloadBundleJob bundleJob;
+ for (;;) {
+ try {
+ bundleJob = job.get(1L, TimeUnit.SECONDS);
+ break;
+ } catch (TimeoutException e) {
+ if (monitor.isCanceled()) {
+ return;
+ }
+ }
+ }
+ if (bundleJob.file != null) {
+ bundleFileToDirectoryEntry.put(bundleJob.file, bundleJob.entry);
+ }
+ monitor.worked(futureSize);
+ } catch (ExecutionException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof OperationCanceledException) {
+ monitor.setCanceled(true);
+ return;
+ }
+ IStatus status;
+ if (cause instanceof CoreException) {
+ status = ((CoreException) cause).getStatus();
+ } else {
+ status = new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ Messages.RemoteBundleDiscoveryStrategy_unexpectedError, cause);
+ }
+ // log errors but continue on
+ LogHelper.log(status);
+ } catch (InterruptedException e) {
+ monitor.setCanceled(true);
+ return;
+ }
+ }
+ } finally {
+ executorService.shutdownNow();
+ }
+
+ try {
+ registryStrategy = new DiscoveryRegistryStrategy(new File[] { registryCacheFolder },
+ new boolean[] { false }, this);
+ registryStrategy.setBundles(bundleFileToDirectoryEntry);
+ IExtensionRegistry extensionRegistry = new ExtensionRegistry(registryStrategy, this, this);
+ try {
+ IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(ConnectorDiscoveryExtensionReader.EXTENSION_POINT_ID);
+ if (extensionPoint != null) {
+ IExtension[] extensions = extensionPoint.getExtensions();
+ if (extensions.length > 0) {
+ processExtensions(new SubProgressMonitor(monitor, ticksTenPercent * 3), extensions);
+ }
+ }
+ } finally {
+ extensionRegistry.stop(this);
+ }
+ } finally {
+ registryStrategy = null;
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private class DownloadBundleJob implements Callable<DownloadBundleJob> {
+ private final IProgressMonitor monitor;
+
+ private final Entry entry;
+
+ private File file;
+
+ public DownloadBundleJob(Entry entry, IProgressMonitor monitor) {
+ this.entry = entry;
+ this.monitor = monitor;
+ }
+
+ public DownloadBundleJob call() {
+
+ String bundleUrl = entry.getLocation();
+ for (int attemptCount = 0; attemptCount < maxDiscoveryJarDownloadAttempts; ++attemptCount) {
+ try {
+ if (!bundleUrl.startsWith("http://") && !bundleUrl.startsWith("https://")) { //$NON-NLS-1$//$NON-NLS-2$
+ LogHelper.log(new Status(IStatus.WARNING, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.RemoteBundleDiscoveryStrategy_unrecognized_discovery_url, bundleUrl)));
+ continue;
+ }
+ String lastPathElement = bundleUrl.lastIndexOf('/') == -1 ? bundleUrl
+ : bundleUrl.substring(bundleUrl.lastIndexOf('/'));
+ File target = File.createTempFile(
+ lastPathElement.replaceAll("^[a-zA-Z0-9_.]", "_") + "_", ".jar", temporaryStorage); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+
+ if (monitor.isCanceled()) {
+ break;
+ }
+
+ TransportUtil.downloadResource(new URI(bundleUrl), target, new NullProgressMonitor() {
+ @Override
+ public boolean isCanceled() {
+ return super.isCanceled() || monitor.isCanceled();
+ }
+ }/*don't use sub progress monitor here*/);
+ file = target;
+ } catch (URISyntaxException e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.RemoteBundleDiscoveryStrategy_Invalid_source_specified_Error, bundleUrl), e));
+ } catch (IOException e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.RemoteBundleDiscoveryStrategy_cannot_download_bundle, bundleUrl, e.getMessage()),
+ e));
+ if (isUnknownHostException(e)) {
+ break;
+ }
+ }
+ }
+ return this;
+ }
+ }
+
+ private ExecutorService createExecutorService(int size) {
+ final int maxThreads = 4;
+ return Executors.newFixedThreadPool(Math.min(size, maxThreads));
+ }
+
+ /**
+ * walk the exception chain to determine if the given exception or any of its underlying causes are an
+ * {@link UnknownHostException}.
+ *
+ * @return true if the exception or one of its causes are {@link UnknownHostException}.
+ */
+ private boolean isUnknownHostException(Throwable t) {
+ while (t != null) {
+ if (t instanceof UnknownHostException) {
+ return true;
+ }
+ Throwable t2 = t.getCause();
+ if (t2 == t) {
+ break;
+ }
+ t = t2;
+ }
+ return false;
+ }
+
+ private void delete(File file) {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ delete(child);
+ }
+ }
+ }
+ if (!file.delete()) {
+ // fail quietly
+ }
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (temporaryStorage != null) {
+ delete(temporaryStorage);
+ }
+ }
+
+ public String getDirectoryUrl() {
+ return directoryUrl;
+ }
+
+ public void setDirectoryUrl(String directoryUrl) {
+ this.directoryUrl = directoryUrl;
+ }
+
+ @Override
+ protected AbstractCatalogSource computeDiscoverySource(IContributor contributor) {
+ Entry directoryEntry = registryStrategy.getDirectoryEntry(contributor);
+ Policy policy = new Policy(directoryEntry.isPermitCategories());
+ JarDiscoverySource discoverySource = new JarDiscoverySource(contributor.getName(),
+ registryStrategy.getJarFile(contributor));
+ discoverySource.setPolicy(policy);
+ return discoverySource;
+ }
+
+ /**
+ * indicate how many times discovyer jar downloads should be attempted
+ */
+ public int getMaxDiscoveryJarDownloadAttempts() {
+ return maxDiscoveryJarDownloadAttempts;
+ }
+
+ /**
+ * indicate how many times discovyer jar downloads should be attempted
+ *
+ * @param maxDiscoveryJarDownloadAttempts
+ * a number >= 1
+ */
+ public void setMaxDiscoveryJarDownloadAttempts(int maxDiscoveryJarDownloadAttempts) {
+ if (maxDiscoveryJarDownloadAttempts < 1 || maxDiscoveryJarDownloadAttempts > 2) {
+ throw new IllegalArgumentException();
+ }
+ this.maxDiscoveryJarDownloadAttempts = maxDiscoveryJarDownloadAttempts;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/messages.properties b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/messages.properties
new file mode 100644
index 000000000..9a10066b5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/messages.properties
@@ -0,0 +1,34 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+BundleDiscoveryStrategy_3={0}: {1}
+BundleDiscoveryStrategy_categoryDisallowed=Cannot create category ''{0}'' with id ''{1}'' from {2}: disallowed
+BundleDiscoveryStrategy_task_loading_local_extensions=Loading local extensions
+BundleDiscoveryStrategy_task_processing_extensions=Processing extensions
+BundleDiscoveryStrategy_unexpected_element=unexpected element ''{0}''
+ConnectorDiscoveryExtensionReader_Documents=Documents
+ConnectorDiscoveryExtensionReader_Tasks=Tasks
+ConnectorDiscoveryExtensionReader_unexpected_element_icon=Unexpected element icon
+ConnectorDiscoveryExtensionReader_unexpected_element_overview=Unexpected element overview
+ConnectorDiscoveryExtensionReader_unexpected_value_kind=Unexpected value for kind
+ConnectorDiscoveryExtensionReader_Version_Control=Version Control
+DirectoryParser_no_directory=Unexpected content: no directory available
+DirectoryParser_unexpected_element=Unexpected element ''{0}''
+DiscoveryRegistryStrategy_cannot_load_bundle=Cannot load bundle {0} from url {1}: {2}
+DiscoveryRegistryStrategy_missing_pluginxml=no plugin.xml in bundle
+RemoteBundleDiscoveryStrategy_cannot_download_bundle=Cannot download bundle at {0}: {1}
+RemoteBundleDiscoveryStrategy_empty_directory=Discovery directory is empty
+RemoteBundleDiscoveryStrategy_Invalid_source_specified_Error=Invalid source location specified: ''{0}''
+RemoteBundleDiscoveryStrategy_io_failure_discovery_directory=IO failure: cannot load discovery directory
+RemoteBundleDiscoveryStrategy_io_failure_temp_storage=IO failure: cannot create temporary storage area
+RemoteBundleDiscoveryStrategy_task_remote_discovery=remote discovery
+RemoteBundleDiscoveryStrategy_unexpectedError=Unexpected error
+RemoteBundleDiscoveryStrategy_unknown_host_discovery_directory=Cannot access {0}: unknown host: please check your Internet connection and try again.
+RemoteBundleDiscoveryStrategy_unrecognized_discovery_url=Unrecognized discovery bundle URL: {0}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/DefaultSaxErrorHandler.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/DefaultSaxErrorHandler.java
new file mode 100644
index 000000000..cfc278707
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/DefaultSaxErrorHandler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.compatibility.util;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * A default implementation of an error handler that throws exceptions on all errors.
+ *
+ * @author David Green
+ */
+public class DefaultSaxErrorHandler implements ErrorHandler {
+
+ public void warning(SAXParseException exception) throws SAXException {
+ // ignore
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ throw exception;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/IOWithCauseException.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/IOWithCauseException.java
new file mode 100644
index 000000000..89b911bdd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/IOWithCauseException.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.compatibility.util;
+
+import java.io.IOException;
+
+/**
+ * An IO Exception that allows for {@link #getCause() a cause}.
+ *
+ * @author David Green
+ */
+public class IOWithCauseException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Throwable cause;
+
+ public IOWithCauseException(String message, Throwable cause) {
+ super(message);
+ this.cause = cause;
+ }
+
+ public IOWithCauseException(Throwable cause) {
+ this.cause = cause;
+ }
+
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/TransportUtil.java b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/TransportUtil.java
new file mode 100644
index 000000000..144548df2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/src/org/eclipse/equinox/internal/p2/discovery/compatibility/util/TransportUtil.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.compatibility.util;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.internal.p2.repository.AuthenticationFailedException;
+import org.eclipse.equinox.internal.p2.repository.RepositoryTransport;
+
+/**
+ * A utility for accessing web resources
+ *
+ * @author David Green
+ */
+public class TransportUtil {
+
+ /**
+ * Extend to process character content.
+ *
+ * @see TransportUtil#readResource(AbstractWebLocation, TextContentProcessor, IProgressMonitor)
+ */
+ public interface TextContentProcessor {
+
+ public void process(Reader reader) throws IOException;
+
+ }
+
+ /**
+ * Download an HTTP-based resource
+ *
+ * @param target
+ * the target file to which the content is saved
+ * @param location
+ * the web location of the content
+ * @param monitor
+ * the monitor
+ * @throws IOException
+ * if a network or IO problem occurs
+ */
+ public static void downloadResource(URI uri, File target, IProgressMonitor monitor) throws IOException {
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(target));
+ try {
+ RepositoryTransport.getInstance().download(uri, out, monitor);
+ } finally {
+ out.close();
+ }
+ }
+
+ /**
+ * Read a web-based resource at the specified location using the given processor.
+ *
+ * @param location
+ * the web location of the content
+ * @param processor
+ * the processor that will handle content
+ * @param monitor
+ * the monitor
+ * @throws IOException
+ * if a network or IO problem occurs
+ * @throws CoreException
+ */
+ public static void readResource(URI uri, TextContentProcessor processor, IProgressMonitor monitor)
+ throws IOException, CoreException {
+ InputStream in = RepositoryTransport.getInstance().stream(uri, monitor);
+ try {
+ // FIXME how can the charset be determined?
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8")); //$NON-NLS-1$
+ processor.process(reader);
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Verify availability of resources at the given web locations. Normally this would be done using an HTTP HEAD.
+ *
+ * @param locations
+ * the locations of the resource to verify
+ * @param one
+ * indicate if only one of the resources must exist
+ * @param monitor
+ * the monitor
+ * @return true if the resource exists
+ * @throws CoreException
+ * @throws AuthenticationFailedException
+ */
+ public static boolean verifyAvailability(List<? extends URI> locations, boolean one, IProgressMonitor monitor)
+ throws IOException, CoreException {
+ if (locations.isEmpty() || locations.size() > 5) {
+ throw new IllegalArgumentException();
+ }
+ int countFound = 0;
+ for (URI location : locations) {
+ try {
+ RepositoryTransport.getInstance().getLastModified(location, monitor);
+ if (one) {
+ return true;
+ }
+ ++countFound;
+ } catch (FileNotFoundException e) {
+ if (!one) {
+ return false;
+ }
+ continue;
+ }
+ }
+ return countFound == locations.size();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery.compatibility/xsd/directory.xsd b/bundles/org.eclipse.equinox.p2.discovery.compatibility/xsd/directory.xsd
new file mode 100644
index 000000000..8ffd96c16
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery.compatibility/xsd/directory.xsd
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns:tns="http://www.eclipse.org/mylyn/discovery/directory/"
+ xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://www.eclipse.org/mylyn/discovery/directory/">
+
+ <annotation>
+ <documentation>
+ Describes the XML format used by a Mylyn discovery directory.
+ </documentation>
+ </annotation>
+
+ <complexType name="OpenAttrsComplex">
+ <annotation>
+ <documentation>extend this type to allow for attributes from other namespaces</documentation>
+ </annotation>
+ <complexContent>
+ <restriction base="anyType">
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+
+ <element name="directory">
+ <complexType>
+ <complexContent>
+ <extension base="tns:OpenAttrsComplex">
+ <sequence>
+ <element ref="tns:entry" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+ </element>
+
+ <element name="entry">
+ <complexType>
+ <complexContent>
+ <extension base="tns:OpenAttrsComplex">
+ <attribute name="url" type="anyURI"/>
+ <attribute name="permitCategories" type="boolean"/>
+ </extension>
+ </complexContent>
+ </complexType>
+ </element>
+</schema> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.classpath b/bundles/org.eclipse.equinox.p2.discovery/.classpath
new file mode 100644
index 000000000..93640193e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/equinox/internal/p2/core/**"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.cvsignore b/bundles/org.eclipse.equinox.p2.discovery/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.gitignore b/bundles/org.eclipse.equinox.p2.discovery/.gitignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.project b/bundles/org.eclipse.equinox.p2.discovery/.project
new file mode 100644
index 000000000..997b422bf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.p2.discovery</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..1314ffa2f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,342 @@
+#Tue May 12 20:42:46 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=80
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..4cbefa939
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Tue May 12 20:42:43 PDT 2009
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Mylyn based on Eclipse
+formatter_settings_version=11
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*******************************************************************************\n * Copyright (c) 2010 Tasktop Technologies and others.\n * All rights reserved. This program and the accompanying materials\n * are made available under the terms of the Eclipse Public License v1.0\n * which accompanies this distribution, and is available at\n * http\://www.eclipse.org/legal/epl-v10.html\n *\n * Contributors\:\n * Tasktop Technologies - initial API and implementation\n *******************************************************************************/\n\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ignore\n${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ignore</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.ltk.core.refactoring.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 000000000..ec06d1d86
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 16 15:42:45 PST 2010
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..d8c6d26af
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.team.ui.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 000000000..1935f1ab0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 16 15:42:45 PST 2010
+commit.comment.template=${connector.task.prefix} ${task.key} - ${task.description}
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..5937a85ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,24 @@
+#Tue May 20 17:39:22 PDT 2008
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=2
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.discovery/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.discovery/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..a4d03cd75
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.equinox.p2.discovery;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.3.0",
+ org.eclipse.equinox.p2.core;bundle-version="2.0.0"
+Export-Package: org.eclipse.equinox.internal.p2.discovery;x-friends:="org.eclipse.equinox.p2.discovery.compatiblity,org.eclipse.equinox.p2.ui.discovery,org.eclipse.equinox.p2.discovery.repository",
+ org.eclipse.equinox.internal.p2.discovery.model;x-friends:="org.eclipse.equinox.p2.discovery.compatiblity,org.eclipse.equinox.p2.ui.discovery,org.eclipse.equinox.p2.discovery.repository",
+ org.eclipse.equinox.internal.p2.discovery.util;x-friends:="org.eclipse.equinox.p2.discovery.compatiblity,org.eclipse.equinox.p2.ui.discovery,org.eclipse.equinox.p2.discovery.repository"
+Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.discovery/about.html b/bundles/org.eclipse.equinox.p2.discovery/about.html
new file mode 100644
index 000000000..bc6e2b493
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>July 3, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
+
+
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.p2.discovery/build.properties b/bundles/org.eclipse.equinox.p2.discovery/build.properties
new file mode 100644
index 000000000..40577979b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/build.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.properties
+src.includes = about.html \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.discovery/plugin.properties b/bundles/org.eclipse.equinox.p2.discovery/plugin.properties
new file mode 100644
index 000000000..38b4c3f0d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+extension-point.name = Connector Discovery
+Bundle-Vendor = Eclipse.org - Equinox
+Bundle-Name = Equinox Provisioning Discovery \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractCatalogSource.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractCatalogSource.java
new file mode 100644
index 000000000..49bc9d9de
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractCatalogSource.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery;
+
+import java.net.URL;
+
+
+/**
+ * @author David Green
+ */
+public abstract class AbstractCatalogSource {
+
+ private Policy policy = Policy.defaultPolicy();
+
+ /**
+ * an identifier that can be used to determine the origin of the source, typically for logging purposes.
+ */
+ public abstract Object getId();
+
+ /**
+ * get a resource by an URL relative to the root of the source.
+ *
+ * @param relativeUrl
+ * the relative resource name
+ * @return an URL to the resource, or null if it is known that the resource does not exist.
+ */
+ public abstract URL getResource(String resourceName);
+
+ public Policy getPolicy() {
+ return policy;
+ }
+
+ public void setPolicy(Policy policy) {
+ this.policy = policy;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractDiscoveryStrategy.java
new file mode 100644
index 000000000..6ea71cd57
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/AbstractDiscoveryStrategy.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+
+/**
+ * An abstraction of a strategy for discovering connectors and categories. Strategy design pattern. Note that strategies
+ * are not reusable and must be disposed.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public abstract class AbstractDiscoveryStrategy {
+
+ protected List<CatalogCategory> categories;
+
+ protected List<Certification> certifications;
+
+ protected List<CatalogItem> items;
+
+ protected List<Tag> tags;
+
+ public void dispose() {
+ }
+
+ public List<CatalogCategory> getCategories() {
+ return categories;
+ }
+
+ public List<Certification> getCertifications() {
+ return certifications;
+ }
+
+ public List<CatalogItem> getItems() {
+ return items;
+ }
+
+ public List<Tag> getTags() {
+ return tags;
+ }
+
+ /**
+ * Perform discovery and add discovered items to {@link #getCategories() categories} and {@link #getItems()}.
+ */
+ public abstract void performDiscovery(IProgressMonitor monitor) throws CoreException;
+
+ public void setCategories(List<CatalogCategory> categories) {
+ this.categories = categories;
+ }
+
+ public void setCertifications(List<Certification> certifications) {
+ this.certifications = certifications;
+ }
+
+ public void setItems(List<CatalogItem> connectors) {
+ this.items = connectors;
+ }
+
+ public void setTags(List<Tag> itemKinds) {
+ this.tags = itemKinds;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Catalog.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Catalog.java
new file mode 100644
index 000000000..c95dad39c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Catalog.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IBundleGroup;
+import org.eclipse.core.runtime.IBundleGroupProvider;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.discovery.model.AbstractCatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.internal.p2.discovery.model.FeatureFilter;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+/**
+ * A means of discovering connectors.
+ *
+ * @author David Green
+ */
+public class Catalog {
+
+ private List<CatalogItem> items = Collections.emptyList();
+
+ private List<CatalogCategory> categories = Collections.emptyList();
+
+ private List<Certification> certifications = Collections.emptyList();
+
+ private List<CatalogItem> filteredItems = Collections.emptyList();
+
+ private final List<AbstractDiscoveryStrategy> discoveryStrategies = new ArrayList<AbstractDiscoveryStrategy>();
+
+ private List<Tag> tags = Collections.emptyList();
+
+ private Dictionary<Object, Object> environment = System.getProperties();
+
+ private boolean verifyUpdateSiteAvailability = false;
+
+ private Map<String, Version> featureToVersion = null;
+
+ public Catalog() {
+ }
+
+ /**
+ * get the discovery strategies to use.
+ */
+ public List<AbstractDiscoveryStrategy> getDiscoveryStrategies() {
+ return discoveryStrategies;
+ }
+
+ /**
+ * Initialize this by performing discovery. Discovery may take a long time as it involves network access.
+ * PRECONDITION: must add at least one {@link #getDiscoveryStrategies() discovery strategy} prior to calling.
+ *
+ * @return
+ */
+ public IStatus performDiscovery(IProgressMonitor monitor) {
+ MultiStatus status = new MultiStatus(DiscoveryCore.ID_PLUGIN, 0,
+ Messages.Catalog_Failed_to_discovery_all_Error, null);
+ if (discoveryStrategies.isEmpty()) {
+ throw new IllegalStateException();
+ }
+ items = new ArrayList<CatalogItem>();
+ filteredItems = new ArrayList<CatalogItem>();
+ categories = new ArrayList<CatalogCategory>();
+ certifications = new ArrayList<Certification>();
+
+ final int totalTicks = 100000;
+ final int discoveryTicks = totalTicks - (totalTicks / 10);
+ monitor.beginTask(Messages.Catalog_task_discovering_connectors, totalTicks);
+ try {
+ for (AbstractDiscoveryStrategy discoveryStrategy : discoveryStrategies) {
+ discoveryStrategy.setCategories(categories);
+ discoveryStrategy.setItems(items);
+ discoveryStrategy.setCertifications(certifications);
+ discoveryStrategy.setTags(tags);
+ try {
+ discoveryStrategy.performDiscovery(new SubProgressMonitor(monitor, discoveryTicks
+ / discoveryStrategies.size()));
+ } catch (CoreException e) {
+ status.add(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.Catalog_Strategy_failed_Error, discoveryStrategy.getClass().getSimpleName()), e));
+ }
+ }
+
+ filterDescriptors();
+ connectCategoriesToDescriptors();
+ connectCertificationsToDescriptors();
+ } finally {
+ monitor.done();
+ }
+ return status;
+ }
+
+ /**
+ * get the top-level categories
+ *
+ * @return the categories, or an empty list if there are none.
+ */
+ public List<CatalogCategory> getCategories() {
+ return categories;
+ }
+
+ /**
+ * get the connectors that were discovered and not filtered
+ *
+ * @return the connectors, or an empty list if there are none.
+ */
+ public List<CatalogItem> getItems() {
+ return items;
+ }
+
+ public List<Tag> getTags() {
+ return tags;
+ }
+
+ /**
+ * get the connectors that were discovered but filtered
+ *
+ * @return the filtered connectors, or an empty list if there were none.
+ */
+ public List<CatalogItem> getFilteredItems() {
+ return filteredItems;
+ }
+
+ /**
+ * The environment used to resolve {@link AbstractCatalogItem#getPlatformFilter() platform filters}. Defaults to the
+ * current environment.
+ */
+ public Dictionary<Object, Object> getEnvironment() {
+ return environment;
+ }
+
+ /**
+ * The environment used to resolve {@link AbstractCatalogItem#getPlatformFilter() platform filters}. Defaults to the
+ * current environment.
+ */
+ public void setEnvironment(Dictionary<Object, Object> environment) {
+ if (environment == null) {
+ throw new IllegalArgumentException();
+ }
+ this.environment = environment;
+ }
+
+ /**
+ * indicate if update site availability should be verified. The default is false.
+ *
+ * @see CatalogItem#getAvailable()
+ * @see #verifySiteAvailability(IProgressMonitor)
+ */
+ public boolean isVerifyUpdateSiteAvailability() {
+ return verifyUpdateSiteAvailability;
+ }
+
+ /**
+ * indicate if update site availability should be verified. The default is false.
+ *
+ * @see CatalogItem#getAvailable()
+ * @see #verifySiteAvailability(IProgressMonitor)
+ */
+ public void setVerifyUpdateSiteAvailability(boolean verifyUpdateSiteAvailability) {
+ this.verifyUpdateSiteAvailability = verifyUpdateSiteAvailability;
+ }
+
+ /**
+ * <em>not for general use: public for testing purposes only</em> A map of installed features to their version. Used
+ * to resolve {@link AbstractCatalogItem#getFeatureFilter() feature filters}.
+ */
+ public Map<String, Version> getFeatureToVersion() {
+ return featureToVersion;
+ }
+
+ /**
+ * <em>not for general use: public for testing purposes only</em> A map of installed features to their version. Used
+ * to resolve {@link AbstractCatalogItem#getFeatureFilter() feature filters}.
+ */
+ public void setFeatureToVersion(Map<String, Version> featureToVersion) {
+ this.featureToVersion = featureToVersion;
+ }
+
+ private void connectCertificationsToDescriptors() {
+ Map<String, Certification> idToCertification = new HashMap<String, Certification>();
+ for (Certification certification : certifications) {
+ Certification previous = idToCertification.put(certification.getId(), certification);
+ if (previous != null) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ "Duplicate certification id ''{0}'': declaring sources: {1}, {2}", //$NON-NLS-1$
+ new Object[] { certification.getId(), certification.getSource().getId(),
+ previous.getSource().getId() })));
+ }
+ }
+
+ for (CatalogItem connector : items) {
+ if (connector.getCertificationId() != null) {
+ Certification certification = idToCertification.get(connector.getCertificationId());
+ if (certification != null) {
+ connector.setCertification(certification);
+ } else {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ "Unknown category ''{0}'' referenced by connector ''{1}'' declared in {2}", new Object[] { //$NON-NLS-1$
+ connector.getCertificationId(), connector.getId(), connector.getSource().getId() })));
+ }
+ }
+ }
+ }
+
+ private void connectCategoriesToDescriptors() {
+ Map<String, CatalogCategory> idToCategory = new HashMap<String, CatalogCategory>();
+ for (CatalogCategory category : categories) {
+ CatalogCategory previous = idToCategory.put(category.getId(), category);
+ if (previous != null) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.Catalog_duplicate_category_id, new Object[] { category.getId(),
+ category.getSource().getId(), previous.getSource().getId() })));
+ }
+ }
+
+ for (CatalogItem connector : items) {
+ CatalogCategory category = idToCategory.get(connector.getCategoryId());
+ if (category != null) {
+ category.getItems().add(connector);
+ connector.setCategory(category);
+ } else {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.Catalog_bundle_references_unknown_category, new Object[] { connector.getCategoryId(),
+ connector.getId(), connector.getSource().getId() })));
+ }
+ }
+ }
+
+ /**
+ * eliminate any connectors whose {@link AbstractCatalogItem#getPlatformFilter() platform filters} don't match
+ */
+ private void filterDescriptors() {
+ for (CatalogItem connector : new ArrayList<CatalogItem>(items)) {
+ if (connector.getPlatformFilter() != null && connector.getPlatformFilter().trim().length() > 0) {
+ boolean match = false;
+ try {
+ Filter filter = FrameworkUtil.createFilter(connector.getPlatformFilter());
+ match = filter.match(environment);
+ } catch (InvalidSyntaxException e) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, NLS.bind(
+ Messages.Catalog_illegal_filter_syntax, new Object[] { connector.getPlatformFilter(),
+ connector.getId(), connector.getSource().getId() })));
+ }
+ if (!match) {
+ items.remove(connector);
+ filteredItems.add(connector);
+ }
+ }
+ for (FeatureFilter featureFilter : connector.getFeatureFilter()) {
+ if (featureToVersion == null) {
+ featureToVersion = computeFeatureToVersion();
+ }
+ boolean match = false;
+ Version version = featureToVersion.get(featureFilter.getFeatureId());
+ if (version != null) {
+ VersionRange versionRange = new VersionRange(featureFilter.getVersion());
+ if (versionRange.isIncluded(version)) {
+ match = true;
+ }
+ }
+ if (!match) {
+ items.remove(connector);
+ filteredItems.add(connector);
+ break;
+ }
+ }
+ }
+ }
+
+ private Map<String, Version> computeFeatureToVersion() {
+ Map<String, Version> featureToVersion = new HashMap<String, Version>();
+ for (IBundleGroupProvider provider : Platform.getBundleGroupProviders()) {
+ for (IBundleGroup bundleGroup : provider.getBundleGroups()) {
+ for (Bundle bundle : bundleGroup.getBundles()) {
+ featureToVersion.put(bundle.getSymbolicName(), bundle.getVersion());
+ }
+ }
+ }
+ return featureToVersion;
+ }
+
+ public void dispose() {
+ for (final AbstractDiscoveryStrategy strategy : discoveryStrategies) {
+ SafeRunner.run(new ISafeRunnable() {
+
+ public void run() throws Exception {
+ strategy.dispose();
+ }
+
+ public void handleException(Throwable exception) {
+ LogHelper.log(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN,
+ Messages.Catalog_exception_disposing + strategy.getClass().getName(), exception));
+ }
+ });
+ }
+ }
+
+ public void setTags(List<Tag> tags) {
+ this.tags = new ArrayList<Tag>(tags);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/DiscoveryCore.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/DiscoveryCore.java
new file mode 100644
index 000000000..bcc6db461
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/DiscoveryCore.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.IProduct;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * @author David Green
+ */
+public abstract class DiscoveryCore {
+
+ public static final String ID_PLUGIN = "org.eclipse.equinox.p2.discovery"; //$NON-NLS-1$
+
+ private DiscoveryCore() {
+ }
+
+ public static Dictionary<Object, Object> createEnvironment() {
+ Dictionary<Object, Object> environment = new Hashtable<Object, Object>(System.getProperties());
+ // add the installed Mylyn version to the environment so that we can
+ // have
+ // connectors that are filtered based on version of Mylyn
+ IProduct product = Platform.getProduct();
+ if (product != null) {
+ environment.put("org.eclipse.product.id", product.getId()); //$NON-NLS-1$
+ }
+ return environment;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Messages.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Messages.java
new file mode 100644
index 000000000..a6bbe4fa4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Messages.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.discovery.messages"; //$NON-NLS-1$
+
+ public static String Catalog_bundle_references_unknown_category;
+
+ public static String Catalog_duplicate_category_id;
+
+ public static String Catalog_exception_disposing;
+
+ public static String Catalog_Failed_to_discovery_all_Error;
+
+ public static String Catalog_illegal_filter_syntax;
+
+ public static String Catalog_Strategy_failed_Error;
+
+ public static String Catalog_task_discovering_connectors;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Policy.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Policy.java
new file mode 100644
index 000000000..63b3d64b1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/Policy.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery;
+
+/**
+ * A policy defines what is permitted.
+ *
+ * @author David Green
+ */
+public class Policy {
+
+ /**
+ * Define system property <code>org.eclipse.mylyn.internal.discovery.core.model.Policy.permissive=true</code> to
+ * allow for categories to be permitted by anyone. For testing purposes.
+ */
+ private static final boolean PERMISSIVE = Boolean.getBoolean(Policy.class.getName() + ".permissive"); //$NON-NLS-1$
+
+ private static final Policy DEFAULT = new Policy(false);
+
+ private final boolean permitCategories;
+
+ public Policy(boolean permitCategories) {
+ this.permitCategories = permitCategories;
+ }
+
+ public boolean isPermitCategories() {
+ return permitCategories || PERMISSIVE;
+ }
+
+ public static Policy defaultPolicy() {
+ return DEFAULT;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/messages.properties b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/messages.properties
new file mode 100644
index 000000000..c0f5d077a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/messages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+Catalog_bundle_references_unknown_category=Unknown category ''{0}'' referenced by connector ''{1}'' declared in {2}
+Catalog_duplicate_category_id=Duplicate category id ''{0}'': declaring sources: {1}, {2}
+Catalog_exception_disposing=exception disposing
+Catalog_Failed_to_discovery_all_Error=Failed to discover all connectors.
+Catalog_illegal_filter_syntax=Illegal filter syntax ''{0}'' in connector ''{1}'' declared in {2}
+Catalog_Strategy_failed_Error={0} failed with an error
+Catalog_task_discovering_connectors=Retrieving listing
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/AbstractCatalogItem.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/AbstractCatalogItem.java
new file mode 100644
index 000000000..f70a962ad
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/AbstractCatalogItem.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * @author Steffen Pingel
+ */
+public class AbstractCatalogItem {
+
+ private Object data;
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogCategory.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogCategory.java
new file mode 100644
index 000000000..cf49711ea
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogCategory.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+
+/**
+ * @author David Green
+ */
+public class CatalogCategory extends AbstractCatalogItem {
+
+ private AbstractCatalogSource source;
+
+ private final List<CatalogItem> items = new ArrayList<CatalogItem>();
+
+ protected String id;
+
+ protected String name;
+
+ protected String description;
+
+ protected String relevance;
+
+ protected Icon icon;
+
+ protected Overview overview;
+
+ protected java.util.List<Group> group = new java.util.ArrayList<Group>();
+
+ public List<CatalogItem> getItems() {
+ return items;
+ }
+
+ public AbstractCatalogSource getSource() {
+ return source;
+ }
+
+ public void setSource(AbstractCatalogSource source) {
+ this.source = source;
+ }
+
+ /**
+ * an id that uniquely identifies the category
+ */
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * the name of the category, as it is displayed in the ui.
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * A description of the category
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * A relevance, which is a number from 0 to 100. Categories with higher relevance are displayed with preference in
+ * the UI.
+ */
+ public String getRelevance() {
+ return relevance;
+ }
+
+ public void setRelevance(String relevance) {
+ this.relevance = relevance;
+ }
+
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Icon icon) {
+ this.icon = icon;
+ }
+
+ public Overview getOverview() {
+ return overview;
+ }
+
+ public void setOverview(Overview overview) {
+ this.overview = overview;
+ }
+
+ public java.util.List<Group> getGroup() {
+ return group;
+ }
+
+ public void setGroup(java.util.List<Group> group) {
+ this.group = group;
+ }
+
+ public void validate() throws ValidationException {
+ if (id == null || id.length() == 0) {
+ throw new ValidationException(Messages.CatalogCategory_must_specify_CatalogCategory_id);
+ }
+ if (name == null || name.length() == 0) {
+ throw new ValidationException(Messages.CatalogCategory_must_specify_CatalogCategory_name);
+ }
+ if (description == null || description.length() == 0) {
+ throw new ValidationException("Must specify connectorCategory/@description"); //$NON-NLS-1$
+ }
+ if (icon != null) {
+ icon.validate();
+ }
+ if (relevance != null) {
+ try {
+ int r = Integer.parseInt(relevance, 10);
+ if (r < 0 || r > 100) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException e) {
+ throw new ValidationException(Messages.CatalogCategory_CatalogCategory_relevance_invalid);
+ }
+ }
+ if (overview != null) {
+ overview.validate();
+ }
+ for (Group groupItem : group) {
+ groupItem.validate();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogItem.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogItem.java
new file mode 100644
index 000000000..a3738614e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/CatalogItem.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.net.MalformedURLException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+
+/**
+ * @author David Green
+ */
+public class CatalogItem extends AbstractCatalogItem {
+
+ private AbstractCatalogSource source;
+
+ private CatalogCategory category;
+
+ private boolean selected;
+
+ private Boolean available;
+
+ private Certification certification;
+
+ private final PropertyChangeSupport changeSupport;
+
+ private boolean installed;
+
+ private Set<Tag> tags;
+
+ protected String name;
+
+ protected String provider;
+
+ protected String license;
+
+ protected String description;
+
+ protected String siteUrl;
+
+ protected String id;
+
+ protected String categoryId;
+
+ protected String platformFilter;
+
+ protected String groupId;
+
+ protected java.util.List<FeatureFilter> featureFilter = new java.util.ArrayList<FeatureFilter>();
+
+ protected java.util.List<String> installableUnits = new java.util.ArrayList<String>();
+
+ protected Icon icon;
+
+ protected Overview overview;
+
+ protected String certificationId;
+
+ public CatalogItem() {
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ public CatalogCategory getCategory() {
+ return category;
+ }
+
+ public void setCategory(CatalogCategory category) {
+ this.category = category;
+ }
+
+ public AbstractCatalogSource getSource() {
+ return source;
+ }
+
+ public void setSource(AbstractCatalogSource source) {
+ this.source = source;
+ }
+
+ public Certification getCertification() {
+ return certification;
+ }
+
+ public void setCertification(Certification certification) {
+ this.certification = certification;
+ }
+
+ /**
+ * support selection
+ *
+ * @return true if the item is selected, otherwise false
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * support selection
+ *
+ * @param selected
+ * true if the item is selected, otherwise false
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * indicate if this connector is available
+ *
+ * @return true if available, false if not, or null if availability is unknown
+ */
+ public Boolean getAvailable() {
+ return available;
+ }
+
+ /**
+ * indicate if this connector is available
+ *
+ * @param available
+ * true if available, false if not, or null if availability is unknown
+ */
+ public void setAvailable(Boolean available) {
+ if (available != this.available || (available != null && !available.equals(this.available))) {
+ Boolean previous = this.available;
+ this.available = available;
+ changeSupport.firePropertyChange("available", previous, this.available); //$NON-NLS-1$
+ }
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(propertyName, listener);
+ }
+
+ /**
+ * the name of the connector including the name of the organization that produces the repository if appropriate, for
+ * example 'Mozilla Bugzilla'.
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * The name of the organization that supplies the connector.
+ */
+ public String getProvider() {
+ return provider;
+ }
+
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * The short name of the license, for example 'EPL 1.0', 'GPL 2.0', or 'Commercial'.
+ */
+ public String getLicense() {
+ return license;
+ }
+
+ public void setLicense(String license) {
+ this.license = license;
+ }
+
+ /**
+ * A description of the connector. Plug-ins should provide a description, especially if the description is not
+ * self-evident from the @name and
+ *
+ * @organization.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * The URL of the update site containing the connector.
+ */
+ public String getSiteUrl() {
+ return siteUrl;
+ }
+
+ public void setSiteUrl(String siteUrl) {
+ this.siteUrl = siteUrl;
+ }
+
+ /**
+ * The id of the feature that installs this connector
+ */
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * the id of the connectorCategory in which this connector belongs
+ */
+ public String getCategoryId() {
+ return categoryId;
+ }
+
+ public void setCategoryId(String categoryId) {
+ this.categoryId = categoryId;
+ }
+
+ public String getCertificationId() {
+ return certificationId;
+ }
+
+ public void setCertificationId(String certificationId) {
+ this.certificationId = certificationId;
+ }
+
+ /**
+ * E.g., "(& (osgi.os=macosx) (osgi.ws=carbon))"
+ */
+ public String getPlatformFilter() {
+ return platformFilter;
+ }
+
+ public void setPlatformFilter(String platformFilter) {
+ this.platformFilter = platformFilter;
+ }
+
+ /**
+ * The id of the connectorCategory group. See group/@id for more details.
+ */
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public java.util.List<FeatureFilter> getFeatureFilter() {
+ return featureFilter;
+ }
+
+ public void setFeatureFilter(java.util.List<FeatureFilter> featureFilter) {
+ this.featureFilter = featureFilter;
+ }
+
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Icon icon) {
+ this.icon = icon;
+ }
+
+ public Overview getOverview() {
+ return overview;
+ }
+
+ public void setOverview(Overview overview) {
+ this.overview = overview;
+ }
+
+ public void validate() throws ValidationException {
+ if (name == null || name.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_name);
+ }
+ if (provider == null || provider.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_provider);
+ }
+ if (license == null || license.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_license);
+ }
+ if (siteUrl == null || siteUrl.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_siteUrl);
+ }
+ try {
+ new java.net.URL(siteUrl);
+ } catch (MalformedURLException e) {
+ throw new ValidationException(Messages.CatalogItem_invalid_CatalogItem_siteUrl);
+ }
+ if (id == null || id.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_id);
+ }
+ if (categoryId == null || categoryId.length() == 0) {
+ throw new ValidationException(Messages.CatalogItem_must_specify_CatalogItem_categoryId);
+ }
+ for (FeatureFilter featureFilterItem : featureFilter) {
+ featureFilterItem.validate();
+ }
+ if (icon != null) {
+ icon.validate();
+ }
+ if (overview != null) {
+ overview.validate();
+ }
+ }
+
+ public java.util.List<String> getInstallableUnits() {
+ return installableUnits;
+ }
+
+ public void setInstallableUnits(java.util.List<String> installableUnits) {
+ this.installableUnits = installableUnits;
+ }
+
+ public boolean isInstalled() {
+ return installed;
+ }
+
+ public void setInstalled(boolean installed) {
+ this.installed = installed;
+ }
+
+ public Set<Tag> getTags() {
+ if (tags == null) {
+ return Collections.emptySet();
+ } else {
+ return Collections.unmodifiableSet(tags);
+ }
+ }
+
+ public boolean hasTag(Tag tag) {
+ return tags == null ? false : tags.contains(tag);
+ }
+
+ public void addTag(Tag tag) {
+ if (tags == null) {
+ tags = new HashSet<Tag>();
+ }
+ tags.add(tag);
+ }
+
+ public boolean removeTag(Tag tag) {
+ if (tags == null) {
+ return false;
+ }
+ return tags.remove(tag);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Certification.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Certification.java
new file mode 100644
index 000000000..4122aa824
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Certification.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+
+/**
+ * @author Steffen Pingel
+ */
+public class Certification {
+
+ private AbstractCatalogSource source;
+
+ protected String id;
+
+ protected String name;
+
+ protected String description;
+
+ protected Icon icon;
+
+ protected String url;
+
+ public AbstractCatalogSource getSource() {
+ return source;
+ }
+
+ public void setSource(AbstractCatalogSource source) {
+ this.source = source;
+ }
+
+ /**
+ * an id that uniquely identifies the category
+ */
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * the name of the category, as it is displayed in the ui.
+ */
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * A description of the category
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Icon icon) {
+ this.icon = icon;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public void validate() throws ValidationException {
+ if (id == null || id.length() == 0) {
+ throw new ValidationException(Messages.CatalogCategory_must_specify_CatalogCategory_id);
+ }
+ if (name == null || name.length() == 0) {
+ throw new ValidationException(Messages.CatalogCategory_must_specify_CatalogCategory_name);
+ }
+ if (icon != null) {
+ icon.validate();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/FeatureFilter.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/FeatureFilter.java
new file mode 100644
index 000000000..4e9d50b05
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/FeatureFilter.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * A means of specifying that a feature must be present in order for the connectorDescriptor to be presented to the
+ * user.
+ *
+ * @author David Green
+ */
+public class FeatureFilter {
+
+ protected String featureId;
+
+ protected String version;
+
+ protected CatalogItem item;
+
+ public FeatureFilter() {
+ }
+
+ /**
+ * The id of the feature to test
+ */
+ public String getFeatureId() {
+ return featureId;
+ }
+
+ public void setFeatureId(String featureId) {
+ this.featureId = featureId;
+ }
+
+ /**
+ * A version specifier, specified in the same manner as version dependencies are specified in an OSGi manifest. For
+ * example: "[3.0,4.0)"
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public CatalogItem getItem() {
+ return item;
+ }
+
+ public void setItem(CatalogItem catalogItem) {
+ this.item = catalogItem;
+ }
+
+ public void validate() throws ValidationException {
+ if (featureId == null || featureId.length() == 0) {
+ throw new ValidationException(Messages.FeatureFilter_must_specify_featureFilter_featureId);
+ }
+ if (version == null || version.length() == 0) {
+ throw new ValidationException(Messages.FeatureFilter_must_specify_featureFilter_version);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Group.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Group.java
new file mode 100644
index 000000000..d59aa8e38
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Group.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Task top Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * groups provide a way to anchor connectors in a grouping with other like entries.
+ *
+ * @author David Green
+ */
+public class Group {
+
+ protected String id;
+
+ protected CatalogCategory category;
+
+ public Group() {
+ }
+
+ /**
+ * An identifier that identifies the group. Must be unique for a particular connectorCategory.
+ */
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public CatalogCategory getCategory() {
+ return category;
+ }
+
+ public void setCategory(CatalogCategory category) {
+ this.category = category;
+ }
+
+ public void validate() throws ValidationException {
+ if (id == null || id.length() == 0) {
+ throw new ValidationException(Messages.Group_must_specify_group_id);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Icon.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Icon.java
new file mode 100644
index 000000000..dc3edb6ff
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Icon.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * @author David Green
+ */
+public class Icon {
+
+ protected String image16;
+
+ protected String image32;
+
+ protected String image48;
+
+ protected String image64;
+
+ protected String image128;
+
+ public Icon() {
+ }
+
+ public String getImage16() {
+ return image16;
+ }
+
+ public void setImage16(String image16) {
+ this.image16 = image16;
+ }
+
+ public String getImage32() {
+ return image32;
+ }
+
+ public void setImage32(String image32) {
+ this.image32 = image32;
+ }
+
+ public String getImage48() {
+ return image48;
+ }
+
+ public void setImage48(String image48) {
+ this.image48 = image48;
+ }
+
+ public String getImage64() {
+ return image64;
+ }
+
+ public void setImage64(String image64) {
+ this.image64 = image64;
+ }
+
+ public String getImage128() {
+ return image128;
+ }
+
+ public void setImage128(String image128) {
+ this.image128 = image128;
+ }
+
+ public void validate() throws ValidationException {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Messages.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Messages.java
new file mode 100644
index 000000000..3446f4e04
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Messages.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.discovery.model.messages"; //$NON-NLS-1$
+
+ public static String CatalogCategory_CatalogCategory_relevance_invalid;
+
+ public static String CatalogCategory_must_specify_CatalogCategory_id;
+
+ public static String CatalogCategory_must_specify_CatalogCategory_name;
+
+ public static String CatalogItem_invalid_CatalogItem_siteUrl;
+
+ public static String CatalogItem_must_specify_CatalogItem_categoryId;
+
+ public static String CatalogItem_must_specify_CatalogItem_id;
+
+ public static String CatalogItem_must_specify_CatalogItem_license;
+
+ public static String CatalogItem_must_specify_CatalogItem_name;
+
+ public static String CatalogItem_must_specify_CatalogItem_provider;
+
+ public static String CatalogItem_must_specify_CatalogItem_siteUrl;
+
+ public static String FeatureFilter_must_specify_featureFilter_featureId;
+
+ public static String FeatureFilter_must_specify_featureFilter_version;
+
+ public static String Group_must_specify_group_id;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Overview.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Overview.java
new file mode 100644
index 000000000..f1ab32c04
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Overview.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * @author David Green
+ */
+public class Overview {
+
+ protected String summary;
+
+ protected String url;
+
+ protected String screenshot;
+
+ protected CatalogItem item;
+
+ protected CatalogCategory category;
+
+ public Overview() {
+ }
+
+ /**
+ * A description providing detailed information about the item. Newlines can be used to format the text into
+ * multiple paragraphs if necessary. Text must fit into an area 320x240, otherwise it will be truncated in the UI.
+ * More lengthy descriptions can be provided on a web page if required, see @url.
+ */
+ public String getSummary() {
+ return summary;
+ }
+
+ public void setSummary(String summary) {
+ this.summary = summary;
+ }
+
+ /**
+ * An URL that points to a web page with more information relevant to the connector or category.
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * 320x240 PNG, JPEG or GIF
+ */
+ public String getScreenshot() {
+ return screenshot;
+ }
+
+ public void setScreenshot(String screenshot) {
+ this.screenshot = screenshot;
+ }
+
+ public CatalogItem getItem() {
+ return item;
+ }
+
+ public void setItem(CatalogItem item) {
+ this.item = item;
+ }
+
+ public CatalogCategory getCategory() {
+ return category;
+ }
+
+ public void setCategory(CatalogCategory category) {
+ this.category = category;
+ }
+
+ public void validate() throws ValidationException {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Tag.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Tag.java
new file mode 100644
index 000000000..f4f1f8bc2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/Tag.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+/**
+ * Provides means to tag items in the catalog.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class Tag extends AbstractCatalogItem {
+
+ private final Object classifier;
+
+ private final String value;
+
+ private final String label;
+
+ public Tag(String value, String label) {
+ this(null, value, label);
+ }
+
+ public Tag(Object tagClassifier, String value, String label) {
+ this.classifier = tagClassifier;
+ this.value = value;
+ this.label = label;
+ }
+
+ /**
+ * the classifier, which places the tag in a logical category
+ *
+ * @return the classifier or null if this tag is not in any category
+ */
+ public Object getTagClassifier() {
+ return classifier;
+ }
+
+ /**
+ * Returns the value of the tag, not intended for display.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Returns a short user-visible value that is used by the user to identify the tag.
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ @Override
+ public String toString() {
+ return "Tag [classifier=" + classifier + ", value=" + value + ", label=" + label + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ @Override
+ public int hashCode() {
+ // we don't include the label here
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((classifier == null) ? 0 : classifier.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ // we don't consider the label when comparing equality
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ Tag other = (Tag) obj;
+ if (classifier == null) {
+ if (other.classifier != null) {
+ return false;
+ }
+ } else if (!classifier.equals(other.classifier)) {
+ return false;
+ }
+ if (value == null) {
+ if (other.value != null) {
+ return false;
+ }
+ } else if (!value.equals(other.value)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/ValidationException.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/ValidationException.java
new file mode 100644
index 000000000..189970cae
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/ValidationException.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.model;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+
+/**
+ * Indicate that a validation has occurred on the model.
+ *
+ * @author David Green
+ */
+public class ValidationException extends CoreException {
+
+ private static final long serialVersionUID = -7542361242327905294L;
+
+ public ValidationException(String message) {
+ super(new Status(IStatus.ERROR, DiscoveryCore.ID_PLUGIN, message));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/messages.properties b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/messages.properties
new file mode 100644
index 000000000..8b0f42857
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/model/messages.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+CatalogCategory_CatalogCategory_relevance_invalid=connectorCategory/@relevance must be an integer >= 0 and <= 100
+CatalogCategory_must_specify_CatalogCategory_id=Must specify connectorCategory/@id
+CatalogCategory_must_specify_CatalogCategory_name=Must specify connectorCategory/@name
+CatalogItem_invalid_CatalogItem_siteUrl=Invalid connectorDescriptor/@siteUrl
+CatalogItem_must_specify_CatalogItem_categoryId=Must specify connectorDescriptor/@categoryId
+CatalogItem_must_specify_CatalogItem_id=Must specify connectorDescriptor/@id
+CatalogItem_must_specify_CatalogItem_license=Must specify connectorDescriptor/@license
+CatalogItem_must_specify_CatalogItem_name=Must specify connectorDescriptor/@name
+CatalogItem_must_specify_CatalogItem_provider=Must specify connectorDescriptor/@provider
+CatalogItem_must_specify_CatalogItem_siteUrl=Must specify connectorDescriptor/@siteUrl
+FeatureFilter_must_specify_featureFilter_featureId=Must specify featureFilter/@featureId
+FeatureFilter_must_specify_featureFilter_version=Must specify featureFilter/@version
+Group_must_specify_group_id=Must specify group/@id
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogCategoryComparator.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogCategoryComparator.java
new file mode 100644
index 000000000..14055bd39
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogCategoryComparator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.discovery.util;
+
+import java.util.Comparator;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+
+/**
+ * A comparator that orders categories by relevance and name.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class CatalogCategoryComparator implements Comparator<CatalogCategory> {
+
+ public int compare(CatalogCategory o1, CatalogCategory o2) {
+ if (o1 == o2) {
+ return 0;
+ }
+ String r1 = o1.getRelevance();
+ String r2 = o2.getRelevance();
+ int i = 0;
+ if (r1 != null && r2 != null) {
+ // don't have to worry about format, since they were already validated
+ // note that higher relevance appears first, thus the reverse order of
+ // the comparison.
+ i = new Integer(r2).compareTo(new Integer(r1));
+ } else if (r1 == null && r2 != null) {
+ return 1;
+ } else if (r2 == null && r1 != null) {
+ return -1;
+ }
+ if (i == 0) {
+ i = o1.getName().compareToIgnoreCase(o2.getName());
+ if (i == 0) {
+ i = o1.getId().compareTo(o2.getId());
+ }
+ }
+ return i;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogItemComparator.java b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogItemComparator.java
new file mode 100644
index 000000000..ffffabe8f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.discovery/src/org/eclipse/equinox/internal/p2/discovery/util/CatalogItemComparator.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.discovery.util;
+
+import java.util.Comparator;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Group;
+
+/**
+ * A comparator that orders connectors by group and alphabetically by their name.
+ *
+ * @author David Green
+ */
+public class CatalogItemComparator implements Comparator<CatalogItem> {
+
+ /**
+ * compute the index of the group id
+ *
+ * @param groupId
+ * the group id or null
+ * @return the index, or -1 if not found
+ */
+ private int computeGroupIndex(CatalogCategory category, String groupId) {
+ if (groupId != null) {
+ int index = -1;
+ for (Group group : category.getGroup()) {
+ ++index;
+ if (group.getId().equals(groupId)) {
+ return index;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public int compare(CatalogItem o1, CatalogItem o2) {
+ if (o1.getCategory() != o2.getCategory()) {
+ throw new IllegalArgumentException();
+ }
+ if (o1 == o2) {
+ return 0;
+ }
+ int g1 = computeGroupIndex(o1.getCategory(), o1.getGroupId());
+ int g2 = computeGroupIndex(o2.getCategory(), o2.getGroupId());
+ int i;
+ if (g1 != g2) {
+ if (g1 == -1) {
+ i = 1;
+ } else if (g2 == -1) {
+ i = -1;
+ } else {
+ i = g1 - g2;
+ }
+ } else {
+ i = o1.getName().compareToIgnoreCase(o2.getName());
+ if (i == 0) {
+ i = o1.getId().compareTo(o2.getId());
+ }
+ }
+ return i;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.classpath b/bundles/org.eclipse.equinox.p2.tests.discovery/.classpath
new file mode 100644
index 000000000..c5eb0e976
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="**/internal/**"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.cvsignore b/bundles/org.eclipse.equinox.p2.tests.discovery/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.gitignore b/bundles/org.eclipse.equinox.p2.tests.discovery/.gitignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.project b/bundles/org.eclipse.equinox.p2.tests.discovery/.project
new file mode 100644
index 000000000..319ac847b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.p2.tests.discovery</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..6c30227a0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,342 @@
+#Tue May 12 20:42:43 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=80
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..8d68e732b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Thu Sep 11 16:27:18 PDT 2008
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Mylyn based on Eclipse
+formatter_settings_version=11
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*******************************************************************************\r\n * Copyright (c) 2010 Tasktop Technologies and others.\r\n * All rights reserved. This program and the accompanying materials\r\n * are made available under the terms of the Eclipse Public License v1.0\r\n * which accompanies this distribution, and is available at\r\n * http\://www.eclipse.org/legal/epl-v10.html\r\n *\r\n * Contributors\:\r\n * Tasktop Technologies - initial API and implementation\r\n *******************************************************************************/\r\n\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ignore\r\n${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ignore</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..d8c6d26af
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.team.ui.prefs b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 000000000..2fa52d061
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 16 15:42:58 PST 2010
+commit.comment.template=${connector.task.prefix} ${task.key} - ${task.description}
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..5937a85ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,24 @@
+#Tue May 20 17:39:22 PDT 2008
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=2
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..e5f8331d0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.equinox.p2.tests.discovery;singleton:=true
+Bundle-Version: 3.4.0.qualifier
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.equinox.p2.discovery;bundle-version="1.0.0",
+ org.eclipse.equinox.p2.discovery.compatiblity;bundle-version="1.0.0",
+ org.eclipse.equinox.p2.ui.discovery;bundle-version="1.0.0",
+ org.junit,
+ org.eclipse.core.runtime;bundle-version="3.1.0",
+ org.eclipse.ui;bundle-version="3.1.0"
+Export-Package: org.eclipse.equinox.p2.discovery.tests;x-internal:=true,
+ org.eclipse.equinox.p2.discovery.tests.core;x-internal:=true,
+ org.eclipse.equinox.p2.discovery.tests.core.mock;x-internal:=true,
+ org.eclipse.equinox.p2.discovery.tests.core.util;x-internal:=true
+Bundle-Vendor: %Bundle-Provider
+Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/about.html b/bundles/org.eclipse.equinox.p2.tests.discovery/about.html
new file mode 100644
index 000000000..bc6e2b493
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>July 3, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
+
+
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/build.properties b/bundles/org.eclipse.equinox.p2.tests.discovery/build.properties
new file mode 100644
index 000000000..16fc97f5d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.xml,\
+ plugin.properties,\
+ testdata/
+
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.properties b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.properties
new file mode 100644
index 000000000..6d6397f85
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+Bundle-Vendor = Eclipse.org - Equinox
+Bundle-Name = Equinox Provisioning Discovery Tests
+connectorCategory.description = a category for testing purposes
+connectorCategory.name = Test Category
+certification.name = Test Certification
+certification.url = http://eclipse.org/mylyn
+certification.description = Description
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml
new file mode 100644
index 000000000..78af283ee
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/plugin.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?><!--
+ Copyright (c) 2009 Tasktop Technologies 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
+ -->
+
+<plugin>
+ <extension
+ point="org.eclipse.mylyn.discovery.core.connectorDiscovery">
+ <connectorCategory
+ description="%connectorCategory.description"
+ id="org.eclipse.mylyn.discovery.tests.connectorCategory1"
+ name="%connectorCategory.name">
+ </connectorCategory>
+ <connectorDescriptor
+ categoryId="org.eclipse.mylyn.discovery.tests.connectorCategory1"
+ description="a fictitious test connector that does nothing"
+ id="org.eclipse.mylyn.discovery.tests.connectorDescriptor1"
+ kind="task"
+ license="UTL (Unit Test License)"
+ name="Test Connector"
+ provider="UnitTesting"
+ siteUrl="http://foo.nodomain/site">
+ </connectorDescriptor>
+ <connectorDescriptor
+ categoryId="org.eclipse.mylyn.discovery.tests.connectorCategory1"
+ description="Trac Connector"
+ id="org.eclipse.mylyn.discovery.test1"
+ kind="task"
+ license="License"
+ name="Installable Test Connector"
+ provider="Eclipse Mylyn"
+ siteUrl="http://localhost/discovery/">
+ </connectorDescriptor>
+ <connectorDescriptor
+ categoryId="org.eclipse.mylyn.discovery.tests.connectorCategory1"
+ description="Trac Connector"
+ id="org.eclipse.mylyn.discovery.2tests"
+ kind="task"
+ license="License"
+ name="2 Installable Test Connector"
+ provider="Eclipse Mylyn"
+ siteUrl="http://localhost/discovery/">
+ <iu
+ id="org.eclipse.mylyn.discovery.test1">
+ </iu>
+ <iu
+ id="org.eclipse.mylyn.discovery.test2">
+ </iu>
+ </connectorDescriptor>
+ <certification
+ id="org.eclipse.mylyn.discovery.tests.certification1"
+ name="%certification.name"
+ url="%certification.url">
+ <description>
+ %certification.description
+ </description>
+ </certification>
+ </extension>
+ <extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="menu:help?after=additions">
+ <command
+ commandId="org.eclipse.equinox.p2.ui.discovery.commands.ShowBundleCatalog"
+ label="Show Bundle Catalog..."
+ style="push">
+ </command>
+ <command
+ commandId="org.eclipse.equinox.p2.ui.discovery.commands.ShowRepositoryCatalog"
+ label="Show Repository Catalog..."
+ style="push">
+ </command>
+ </menuContribution>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/AllDiscoveryTests.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/AllDiscoveryTests.java
new file mode 100644
index 000000000..4cd29eb0f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/AllDiscoveryTests.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.equinox.p2.discovery.tests.core.BundleDiscoveryStrategyTest;
+import org.eclipse.equinox.p2.discovery.tests.core.ConnectorDiscoveryRemoteTest;
+import org.eclipse.equinox.p2.discovery.tests.core.ConnectorDiscoveryTest;
+import org.eclipse.equinox.p2.discovery.tests.core.DirectoryParserTest;
+import org.eclipse.equinox.p2.discovery.tests.core.RemoteBundleDiscoveryStrategyTest;
+
+/**
+ * @author Steffen Pingel
+ */
+public class AllDiscoveryTests {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Tests for org.eclipse.mylyn.discovery");
+ suite.addTestSuite(ConnectorDiscoveryTest.class);
+ suite.addTestSuite(DirectoryParserTest.class);
+ suite.addTestSuite(BundleDiscoveryStrategyTest.class);
+ suite.addTestSuite(RemoteBundleDiscoveryStrategyTest.class);
+ suite.addTestSuite(ConnectorDiscoveryRemoteTest.class);
+ return suite;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/DiscoveryTestConstants.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/DiscoveryTestConstants.java
new file mode 100644
index 000000000..3da5ab452
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/DiscoveryTestConstants.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests;
+
+/**
+ * @author David Green
+ */
+public abstract class DiscoveryTestConstants {
+
+ /**
+ * The URL of the mylyn discovery directory, may be overridden using the system property
+ * <tt>mylyn.discovery.directory</tt>.
+ */
+ public static final String DISCOVERY_URL = System.getProperty("mylyn.discovery.directory",
+ "http://www.eclipse.org/mylyn/discovery/directory-3.3.xml");
+
+ private DiscoveryTestConstants() {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/BundleDiscoveryStrategyTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/BundleDiscoveryStrategyTest.java
new file mode 100644
index 000000000..01f8915c7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/BundleDiscoveryStrategyTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.Policy;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.p2.discovery.tests.core.mock.MockBundleDiscoveryStrategy;
+
+/**
+ * @author David Green
+ */
+public class BundleDiscoveryStrategyTest extends TestCase {
+
+ private MockBundleDiscoveryStrategy discoveryStrategy;
+
+ private final List<CatalogCategory> categories = new ArrayList<CatalogCategory>();
+
+ private final List<CatalogItem> connectors = new ArrayList<CatalogItem>();
+
+ private final List<Certification> certifications = new ArrayList<Certification>();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ discoveryStrategy = new MockBundleDiscoveryStrategy();
+ discoveryStrategy.setPolicy(new Policy(true));
+ discoveryStrategy.setCategories(categories);
+ discoveryStrategy.setItems(connectors);
+ discoveryStrategy.setCertifications(certifications);
+ }
+
+ public void testDiscovery() throws CoreException {
+ discoveryStrategy.performDiscovery(new NullProgressMonitor());
+
+ assertFalse(categories.isEmpty());
+ assertFalse(connectors.isEmpty());
+ CatalogCategory category = findCategoryById("org.eclipse.mylyn.discovery.tests.connectorCategory1");
+ assertNotNull(category);
+ CatalogItem connector = findConnectorById("org.eclipse.mylyn.discovery.tests.connectorDescriptor1");
+ assertNotNull(connector);
+ Certification certification = findCertificationById("org.eclipse.mylyn.discovery.tests.certification1");
+ assertNotNull(certification);
+ }
+
+ public void testDiscoveryNoCategoriesPolicy() throws CoreException {
+ discoveryStrategy.setPolicy(new Policy(false));
+ discoveryStrategy.performDiscovery(new NullProgressMonitor());
+
+ assertTrue(categories.isEmpty());
+ }
+
+ private CatalogItem findConnectorById(String id) {
+ for (CatalogItem descriptor : connectors) {
+ if (id.equals(descriptor.getId())) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+ private CatalogCategory findCategoryById(String id) {
+ for (CatalogCategory descriptor : categories) {
+ if (id.equals(descriptor.getId())) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+ private Certification findCertificationById(String id) {
+ for (Certification descriptor : certifications) {
+ if (id.equals(descriptor.getId())) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryRemoteTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryRemoteTest.java
new file mode 100644
index 000000000..df01213ea
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryRemoteTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.RemoteBundleDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.p2.discovery.tests.DiscoveryTestConstants;
+
+/**
+ * A test that uses the real discovery directory and verifies that it works, and that all referenced update sites appear
+ * to be available.
+ *
+ * @author David Green
+ */
+public class ConnectorDiscoveryRemoteTest extends TestCase {
+
+ private Catalog connectorDiscovery;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ connectorDiscovery = new Catalog();
+ connectorDiscovery.setVerifyUpdateSiteAvailability(false);
+
+ connectorDiscovery.getDiscoveryStrategies().clear();
+ RemoteBundleDiscoveryStrategy remoteStrategy = new RemoteBundleDiscoveryStrategy();
+ remoteStrategy.setDirectoryUrl(DiscoveryTestConstants.DISCOVERY_URL);
+ connectorDiscovery.getDiscoveryStrategies().add(remoteStrategy);
+ }
+
+ public void testRemoteDirectory() throws CoreException {
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertFalse(connectorDiscovery.getCategories().isEmpty());
+ assertFalse(connectorDiscovery.getItems().isEmpty());
+ }
+
+// public void testVerifyAvailability() throws CoreException {
+// connectorDiscovery.performDiscovery(new NullProgressMonitor());
+// for (CatalogItem connector : connectorDiscovery.getConnectors()) {
+// assertNull(connector.getAvailable());
+// }
+// connectorDiscovery.verifySiteAvailability(new NullProgressMonitor());
+//
+// assertFalse(connectorDiscovery.getConnectors().isEmpty());
+//
+// int unavailableCount = 0;
+// for (CatalogItem connector : connectorDiscovery.getConnectors()) {
+// assertNotNull(connector.getAvailable());
+// if (!connector.getAvailable()) {
+// ++unavailableCount;
+// }
+// }
+// if (unavailableCount > 0) {
+// fail(String.format("%s unavailable: %s", unavailableCount, computeUnavailableConnetorDescriptorNames()));
+// }
+// }
+
+ private String computeUnavailableConnetorDescriptorNames() {
+ String message = "";
+ for (CatalogItem connector : connectorDiscovery.getItems()) {
+ if (!connector.getAvailable()) {
+ if (message.length() > 0) {
+ message += ", ";
+ }
+ message += connector.getName();
+ }
+ }
+ return message;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryTest.java
new file mode 100644
index 000000000..3a8eb6f84
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/ConnectorDiscoveryTest.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.p2.discovery.tests.core.mock.CatalogItemMockFactory;
+import org.eclipse.equinox.p2.discovery.tests.core.mock.MockDiscoveryStrategy;
+import org.osgi.framework.Version;
+
+/**
+ * @author David Green
+ */
+public class ConnectorDiscoveryTest extends TestCase {
+
+ private Catalog connectorDiscovery;
+
+ private MockDiscoveryStrategy mockDiscoveryStrategy;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ connectorDiscovery = new Catalog();
+ mockDiscoveryStrategy = new MockDiscoveryStrategy();
+ connectorDiscovery.getDiscoveryStrategies().add(mockDiscoveryStrategy);
+ }
+
+ public void testPlatformFilter_None() throws CoreException {
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+ assertEquals(mockDiscoveryStrategy.getConnectorCount(), connectorDiscovery.getItems().size());
+ }
+
+ public void testPlatformFilter_NegativeMatch() throws CoreException {
+ mockDiscoveryStrategy.setConnectorMockFactory(new CatalogItemMockFactory() {
+ @Override
+ protected void populateMockData() {
+ super.populateMockData();
+ platformFilter("(& (osgi.os=macosx) (osgi.ws=carbon))");
+ }
+ });
+ // test to ensure that all non-matching platform filters are not discovered
+ Dictionary<Object, Object> environment = new Properties();
+ environment.put("osgi.os", "win32");
+ environment.put("osgi.ws", "windows");
+ connectorDiscovery.setEnvironment(environment);
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertTrue(connectorDiscovery.getItems().isEmpty());
+ }
+
+ public void testPlatformFilter_PositiveMatch() throws CoreException {
+ mockDiscoveryStrategy.setConnectorMockFactory(new CatalogItemMockFactory() {
+ @Override
+ protected void populateMockData() {
+ super.populateMockData();
+ platformFilter("(& (osgi.os=macosx) (osgi.ws=carbon))");
+ }
+ });
+ Dictionary<Object, Object> environment = new Properties();
+
+ // test to ensure that all matching platform filters are discovered
+ environment.put("osgi.os", "macosx");
+ environment.put("osgi.ws", "carbon");
+ connectorDiscovery.setEnvironment(environment);
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertFalse(connectorDiscovery.getItems().isEmpty());
+ assertEquals(mockDiscoveryStrategy.getConnectorCount(), connectorDiscovery.getItems().size());
+ }
+
+ public void testFeatureFilter_PositiveMatch() throws CoreException {
+ mockDiscoveryStrategy.setConnectorMockFactory(new CatalogItemMockFactory() {
+ @Override
+ protected void populateMockData() {
+ super.populateMockData();
+ featureFilter("com.foo.bar.feature", "[1.0,2.0)");
+ }
+ });
+ Map<String, Version> featureToVersion = new HashMap<String, Version>();
+ featureToVersion.put("com.foo.bar.feature", new Version("1.1"));
+ connectorDiscovery.setFeatureToVersion(featureToVersion);
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertFalse(connectorDiscovery.getItems().isEmpty());
+ assertEquals(mockDiscoveryStrategy.getConnectorCount(), connectorDiscovery.getItems().size());
+ }
+
+ public void testFeatureFilter_NegativeMatch_VersionMismatch() throws CoreException {
+ mockDiscoveryStrategy.setConnectorMockFactory(new CatalogItemMockFactory() {
+ @Override
+ protected void populateMockData() {
+ super.populateMockData();
+ featureFilter("com.foo.bar.feature", "[1.2,2.0)");
+ }
+ });
+ Map<String, Version> featureToVersion = new HashMap<String, Version>();
+ featureToVersion.put("com.foo.bar.feature", new Version("1.1"));
+ connectorDiscovery.setFeatureToVersion(featureToVersion);
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertTrue(connectorDiscovery.getItems().isEmpty());
+ }
+
+ public void testFeatureFilter_NegativeMatch_NotPresent() throws CoreException {
+ mockDiscoveryStrategy.setConnectorMockFactory(new CatalogItemMockFactory() {
+ @Override
+ protected void populateMockData() {
+ super.populateMockData();
+ featureFilter("com.foo.bar.feature", "[1.2,2.0)");
+ }
+ });
+ Map<String, Version> featureToVersion = new HashMap<String, Version>();
+ connectorDiscovery.setFeatureToVersion(featureToVersion);
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertTrue(connectorDiscovery.getItems().isEmpty());
+ }
+
+ public void testCategorization() throws CoreException {
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+ assertTrue(!connectorDiscovery.getItems().isEmpty());
+ assertTrue(!connectorDiscovery.getCategories().isEmpty());
+
+ for (CatalogItem connector : connectorDiscovery.getItems()) {
+ assertNotNull(connector.getCategory());
+ assertEquals(connector.getCategoryId(), connector.getCategory().getId());
+ assertTrue(connector.getCategory().getItems().contains(connector));
+ }
+ }
+
+ public void testMultipleStrategies() throws CoreException {
+ MockDiscoveryStrategy strategy = new MockDiscoveryStrategy();
+ strategy.setConnectorMockFactory(mockDiscoveryStrategy.getConnectorMockFactory());
+ strategy.setCategoryMockFactory(mockDiscoveryStrategy.getCategoryMockFactory());
+ connectorDiscovery.getDiscoveryStrategies().add(strategy);
+
+ connectorDiscovery.performDiscovery(new NullProgressMonitor());
+
+ assertEquals(mockDiscoveryStrategy.getConnectorMockFactory().getCreatedCount(),
+ connectorDiscovery.getItems().size());
+ assertEquals(mockDiscoveryStrategy.getCategoryMockFactory().getCreatedCount(),
+ connectorDiscovery.getCategories().size());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/DirectoryParserTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/DirectoryParserTest.java
new file mode 100644
index 000000000..2172df478
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/DirectoryParserTest.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import junit.framework.TestCase;
+
+import org.eclipse.equinox.internal.p2.discovery.compatibility.Directory;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.DirectoryParser;
+
+/**
+ * @author David Green
+ */
+public class DirectoryParserTest extends TestCase {
+
+ private DirectoryParser parser;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ parser = new DirectoryParser();
+ }
+
+ public void testParse() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals("http://foo.bar.nodomain/baz.jar", directory.getEntries().get(0).getLocation());
+ }
+
+ public void testParseBadFormat() throws IOException {
+ try {
+ parser.parse(new StringReader(
+ "<directory2 xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\"/></directory2>"));
+ fail("Expected exception");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ public void testParseMalformed() throws IOException {
+ try {
+ parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\">"));
+ fail("Expected exception");
+ } catch (IOException e) {
+ // expected
+ }
+ }
+
+ public void testParseUnexpectedElementsAndAttributes() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\" id=\"asdf\"><baz/></entry><foo/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals("http://foo.bar.nodomain/baz.jar", directory.getEntries().get(0).getLocation());
+ }
+
+ public void testParseNoNS() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory><entry url=\"http://foo.bar.nodomain/baz.jar\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals("http://foo.bar.nodomain/baz.jar", directory.getEntries().get(0).getLocation());
+ }
+
+ public void testParsePermitCategoriesTrue() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\" permitCategories=\"true\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals(true, directory.getEntries().get(0).isPermitCategories());
+ }
+
+ public void testParsePermitCategoriesFalse() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\" permitCategories=\"false\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals(false, directory.getEntries().get(0).isPermitCategories());
+ }
+
+ public void testParsePermitCategoriesNotSpecified() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals(false, directory.getEntries().get(0).isPermitCategories());
+ }
+
+ public void testParsePermitCategoriesSpecifiedBadly() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\" permitCategories=\"\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals(false, directory.getEntries().get(0).isPermitCategories());
+ }
+
+ public void testParsePermitCategoriesSpecifiedBadly2() throws IOException {
+ Directory directory = parser.parse(new StringReader(
+ "<directory xmlns=\"http://www.eclipse.org/mylyn/discovery/directory/\"><entry url=\"http://foo.bar.nodomain/baz.jar\" permitCategories=\"asdf\"/></directory>"));
+ assertNotNull(directory);
+ assertEquals(1, directory.getEntries().size());
+ assertEquals(false, directory.getEntries().get(0).isPermitCategories());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/RemoteBundleDiscoveryStrategyTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/RemoteBundleDiscoveryStrategyTest.java
new file mode 100644
index 000000000..80a4f478f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/RemoteBundleDiscoveryStrategyTest.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.RemoteBundleDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Certification;
+import org.eclipse.equinox.p2.discovery.tests.DiscoveryTestConstants;
+
+/**
+ * @author David Green
+ */
+public class RemoteBundleDiscoveryStrategyTest extends TestCase {
+
+ private RemoteBundleDiscoveryStrategy discoveryStrategy;
+
+ @Override
+ protected void setUp() throws Exception {
+ discoveryStrategy = new RemoteBundleDiscoveryStrategy();
+ discoveryStrategy.setDirectoryUrl(DiscoveryTestConstants.DISCOVERY_URL);
+ discoveryStrategy.setCategories(new ArrayList<CatalogCategory>());
+ discoveryStrategy.setItems(new ArrayList<CatalogItem>());
+ discoveryStrategy.setCertifications(new ArrayList<Certification>());
+ }
+
+ public void testPerformDiscovery() throws CoreException, IOException {
+ discoveryStrategy.performDiscovery(new NullProgressMonitor());
+ assertFalse(discoveryStrategy.getCategories().isEmpty());
+ for (CatalogCategory category : discoveryStrategy.getCategories()) {
+// System.out.println(String.format("%s: %s: %s", category.getId(), category.getName(),
+// category.getDescription()));
+ assertNotNull(category.getId());
+ assertNotNull(category.getName());
+ assertNotNull(category.getDescription());
+ }
+ assertFalse(discoveryStrategy.getItems().isEmpty());
+ for (CatalogItem connector : discoveryStrategy.getItems()) {
+// System.out.println(String.format("%s: %s: %s", connector.getId(), connector.getName(),
+// connector.getDescription()));
+ assertNotNull(connector.getId());
+ assertNotNull(connector.getTags());
+ assertNotNull(connector.getName());
+ assertNotNull(connector.getDescription());
+
+ // we _know_ that the bundle must have a plugin.xml... so verify that the source is working correctly
+ assertNotNull(connector.getSource());
+ URL pluginXmlUrl = connector.getSource().getResource("plugin.xml");
+// System.out.println("URL: " + pluginXmlUrl);
+ InputStream in = pluginXmlUrl.openStream();
+ assertNotNull(in);
+ in.close();
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/AbstractMockFactory.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/AbstractMockFactory.java
new file mode 100644
index 000000000..dc398199f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/AbstractMockFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+/**
+ *
+ * @author David Green
+ */
+public abstract class AbstractMockFactory<MockType> {
+
+ protected int seed = 0;
+
+ private MockType mockObject;
+
+ protected MockCatalogSource source = new MockCatalogSource();
+
+ public final MockType get() {
+ MockType object = getMockObject();
+ mockObject = null;
+ return object;
+ }
+
+ public final MockType getMockObject() {
+ if (mockObject == null) {
+ ++seed;
+ mockObject = createMockObject();
+ populateMockData();
+ }
+ return mockObject;
+ }
+
+ protected abstract void populateMockData();
+
+ protected abstract MockType createMockObject();
+
+ /**
+ * get the number of objects created by this factory
+ */
+ public int getCreatedCount() {
+ return seed;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogCategoryMockFactory.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogCategoryMockFactory.java
new file mode 100644
index 000000000..2f4e60ac1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogCategoryMockFactory.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.Icon;
+
+/**
+ * @author David Green
+ */
+public class CatalogCategoryMockFactory extends AbstractMockFactory<CatalogCategory> {
+
+ CatalogCategory category;
+
+ @Override
+ protected CatalogCategory createMockObject() {
+ return new CatalogCategory();
+ }
+
+ @Override
+ protected void populateMockData() {
+ // mock up some data
+
+ getMockObject().setSource(source);
+
+ name("Category " + seed).id(CatalogCategoryMockFactory.class.getPackage().getName() + ".connector" + seed)
+ .description("A category of things, " + seed);
+
+ Icon icon = new Icon();
+ icon.setImage128("images/ico128.png");
+ icon.setImage16("images/ico16.png");
+ icon.setImage32("images/ico32.png");
+ icon.setImage64("images/ico64.png");
+
+ getMockObject().setIcon(icon);
+ }
+
+ public CatalogCategoryMockFactory description(String description) {
+ getMockObject().setDescription(description);
+ return this;
+ }
+
+ public CatalogCategoryMockFactory icon(Icon icon) {
+ getMockObject().setIcon(icon);
+ return this;
+ }
+
+ public CatalogCategoryMockFactory id(String id) {
+ getMockObject().setId(id);
+ return this;
+ }
+
+ public CatalogCategoryMockFactory name(String name) {
+ getMockObject().setName(name);
+ return this;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogItemMockFactory.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogItemMockFactory.java
new file mode 100644
index 000000000..0fd641fc7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/CatalogItemMockFactory.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.FeatureFilter;
+import org.eclipse.equinox.internal.p2.discovery.model.Icon;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+
+/**
+ * @author David Green
+ */
+public class CatalogItemMockFactory extends AbstractMockFactory<CatalogItem> {
+
+ public CatalogItemMockFactory() {
+ }
+
+ @Override
+ protected void populateMockData() {
+
+ // mock up some data
+
+ getMockObject().setSource(source);
+
+ name("Connector " + seed).id(CatalogItemMockFactory.class.getPackage().getName() + ".connector" + seed)
+ .siteUrl("http://example.nodomain/some/path/updateSite3.x/")
+ .tag(new Tag("", ""))
+ .license(seed % 2 == 0 ? "EPL 1.0" : "APL 2.0")
+ .description("a connector for the Example Task System versions 1.0 - 5.3")
+ .categoryId("example")
+ .provider("Testing 123 Inc.");
+
+ Icon icon = new Icon();
+ icon.setImage128("images/ico128.png");
+ icon.setImage16("images/ico16.png");
+ icon.setImage32("images/ico32.png");
+ icon.setImage64("images/ico64.png");
+
+ Overview overview = new Overview();
+ overview.setScreenshot("images/screenshot-main.png");
+ overview.setSummary("some long text that summarizes the connector");
+ overview.setUrl("http://example.nodomain/some/path/updateSite3.x/overview.html");
+
+ icon(icon).overview(overview);
+ overview.setItem(getMockObject());
+ }
+
+ @Override
+ protected CatalogItem createMockObject() {
+ return new CatalogItem();
+ }
+
+ public CatalogItemMockFactory categoryId(String categoryId) {
+ getMockObject().setCategoryId(categoryId);
+ return this;
+ }
+
+ public CatalogItemMockFactory description(String description) {
+ getMockObject().setDescription(description);
+ return this;
+ }
+
+ public CatalogItemMockFactory icon(Icon icon) {
+ getMockObject().setIcon(icon);
+ return this;
+ }
+
+ public CatalogItemMockFactory id(String id) {
+ getMockObject().setId(id);
+ return this;
+ }
+
+ public CatalogItemMockFactory tag(Tag tag) {
+ getMockObject().addTag(tag);
+ return this;
+ }
+
+ public CatalogItemMockFactory license(String license) {
+ getMockObject().setLicense(license);
+ return this;
+ }
+
+ public CatalogItemMockFactory name(String name) {
+ getMockObject().setName(name);
+ return this;
+ }
+
+ public CatalogItemMockFactory overview(Overview overview) {
+ getMockObject().setOverview(overview);
+ return this;
+ }
+
+ public CatalogItemMockFactory platformFilter(String platformFilter) {
+ getMockObject().setPlatformFilter(platformFilter);
+ return this;
+ }
+
+ public CatalogItemMockFactory provider(String provider) {
+ getMockObject().setProvider(provider);
+ return this;
+ }
+
+ public CatalogItemMockFactory siteUrl(String siteUrl) {
+ getMockObject().setSiteUrl(siteUrl);
+ return this;
+ }
+
+ public CatalogItemMockFactory featureFilter(String featureId, String versionRange) {
+ FeatureFilter featureFilter = new FeatureFilter();
+ featureFilter.setItem(getMockObject());
+ featureFilter.setFeatureId(featureId);
+ featureFilter.setVersion(versionRange);
+ getMockObject().getFeatureFilter().add(featureFilter);
+ return this;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockBundleDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockBundleDiscoveryStrategy.java
new file mode 100644
index 000000000..ac6069da1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockBundleDiscoveryStrategy.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+import org.eclipse.core.runtime.IContributor;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.Policy;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.BundleDiscoveryStrategy;
+
+/**
+ * a discovery strategy for bundles where the policy can be arbitrarily set
+ *
+ * @author David Green
+ */
+public class MockBundleDiscoveryStrategy extends BundleDiscoveryStrategy {
+ private Policy policy = Policy.defaultPolicy();
+
+ @Override
+ protected AbstractCatalogSource computeDiscoverySource(IContributor contributor) {
+ AbstractCatalogSource discoverySource = super.computeDiscoverySource(contributor);
+ discoverySource.setPolicy(policy);
+ return discoverySource;
+ }
+
+ public Policy getPolicy() {
+ return policy;
+ }
+
+ public void setPolicy(Policy policy) {
+ this.policy = policy;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockCatalogSource.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockCatalogSource.java
new file mode 100644
index 000000000..ad140a808
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockCatalogSource.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+import java.net.URL;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+
+/**
+ * @author David Green
+ */
+public class MockCatalogSource extends AbstractCatalogSource {
+
+ @Override
+ public Object getId() {
+ return "mock:mock";
+ }
+
+ @Override
+ public URL getResource(String resourceName) {
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockDiscoveryStrategy.java
new file mode 100644
index 000000000..137b43668
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/mock/MockDiscoveryStrategy.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.p2.discovery.tests.core.mock;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+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;
+
+/**
+ * @author David Green
+ */
+public class MockDiscoveryStrategy extends AbstractDiscoveryStrategy {
+
+ private int connectorCount = 15;
+
+ private int categoryCount = 5;
+
+ protected CatalogItemMockFactory connectorMockFactory = new CatalogItemMockFactory();
+
+ protected CatalogCategoryMockFactory categoryMockFactory = new CatalogCategoryMockFactory();
+
+ @Override
+ public void performDiscovery(IProgressMonitor monitor) throws CoreException {
+ for (int x = 0; x < categoryCount; ++x) {
+ CatalogCategory mockCategory = createDiscoveryCategory();
+ getCategories().add(mockCategory);
+ }
+ for (int x = 0; x < connectorCount; ++x) {
+ CatalogItem mockConnector = createDiscoveryConnector();
+ // put the connector in a category
+ if (!getCategories().isEmpty()) {
+ int categoryIndex = x % getCategories().size();
+ mockConnector.setCategoryId(getCategories().get(categoryIndex).getId());
+ }
+ getItems().add(mockConnector);
+ }
+ }
+
+ protected CatalogCategory createDiscoveryCategory() {
+ return categoryMockFactory.get();
+ }
+
+ protected CatalogItem createDiscoveryConnector() {
+ return connectorMockFactory.get();
+ }
+
+ public CatalogCategoryMockFactory getCategoryMockFactory() {
+ return categoryMockFactory;
+ }
+
+ public void setCategoryMockFactory(CatalogCategoryMockFactory categoryMockFactory) {
+ this.categoryMockFactory = categoryMockFactory;
+ }
+
+ public CatalogItemMockFactory getConnectorMockFactory() {
+ return connectorMockFactory;
+ }
+
+ public void setConnectorMockFactory(CatalogItemMockFactory connectorMockFactory) {
+ this.connectorMockFactory = connectorMockFactory;
+ }
+
+ public int getConnectorCount() {
+ return connectorCount;
+ }
+
+ public void setConnectorCount(int connectorCount) {
+ this.connectorCount = connectorCount;
+ }
+
+ public int getCategoryCount() {
+ return categoryCount;
+ }
+
+ public void setCategoryCount(int categoryCount) {
+ this.categoryCount = categoryCount;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogCategoryComparatorTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogCategoryComparatorTest.java
new file mode 100644
index 000000000..40f9cbf98
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogCategoryComparatorTest.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core.util;
+
+import junit.framework.TestCase;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.util.CatalogCategoryComparator;
+
+public class CatalogCategoryComparatorTest extends TestCase {
+
+ private CatalogCategoryComparator comparator;
+
+ private CatalogCategory category1;
+
+ private CatalogCategory category2;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ comparator = new CatalogCategoryComparator();
+ category1 = new CatalogCategory();
+ category2 = new CatalogCategory();
+ }
+
+ public void testSortByRelevanceInequal() {
+ category1.setRelevance("100");
+ category2.setRelevance("50");
+ assertEquals(-1, comparator.compare(category1, category2));
+ assertEquals(1, comparator.compare(category2, category1));
+ }
+
+ public void testSortByRelevanceOneNotSpecified() {
+ category1.setRelevance("10");
+ assertEquals(-1, comparator.compare(category1, category2));
+ assertEquals(1, comparator.compare(category2, category1));
+ }
+
+ public void testSortByRelevanceSame() {
+ category1.setRelevance("10");
+ category1.setName("test");
+ category1.setId("1");
+ category2.setRelevance("10");
+ category2.setName("test");
+ category2.setId("1");
+ assertEquals(0, comparator.compare(category1, category2));
+ assertEquals(0, comparator.compare(category2, category1));
+ }
+
+ public void testSortByRelevanceSameIdsDiffer() {
+ category1.setRelevance("10");
+ category1.setName("test");
+ category1.setId("a");
+ category2.setRelevance("10");
+ category2.setName("test");
+ category2.setId("b");
+ assertEquals(-1, comparator.compare(category1, category2));
+ assertEquals(1, comparator.compare(category2, category1));
+ }
+
+ public void testSortByRelevanceSameNamesDiffer() {
+ category1.setRelevance("10");
+ category1.setName("a");
+ category1.setId("a");
+ category2.setRelevance("10");
+ category2.setName("b");
+ category2.setId("a");
+ assertEquals(-1, comparator.compare(category1, category2));
+ assertEquals(1, comparator.compare(category2, category1));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogConnectorComparatorTest.java b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogConnectorComparatorTest.java
new file mode 100644
index 000000000..57e82c464
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/src/org/eclipse/equinox/p2/discovery/tests/core/util/CatalogConnectorComparatorTest.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.discovery.tests.core.util;
+
+import junit.framework.TestCase;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Group;
+import org.eclipse.equinox.internal.p2.discovery.util.CatalogItemComparator;
+
+public class CatalogConnectorComparatorTest extends TestCase {
+
+ private CatalogCategory category;
+
+ private CatalogItemComparator comparator;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ category = new CatalogCategory();
+ comparator = new CatalogItemComparator();
+ }
+
+ private Group addGroup(String id) {
+ Group group = new Group();
+ group.setId(id);
+ category.getGroup().add(group);
+ return group;
+ }
+
+ private CatalogItem addConnectorDescriptor(String id, String name, String groupId) {
+ CatalogItem connector = new CatalogItem();
+ connector.setId(id);
+ connector.setName(name);
+ connector.setGroupId(groupId);
+ connector.setCategory(category);
+ category.getItems().add(connector);
+ return connector;
+ }
+
+ public void testOrderByGroup() {
+ addGroup("1");
+ addGroup("2");
+ CatalogItem t1 = addConnectorDescriptor("b", "btest", "2");
+ CatalogItem t2 = addConnectorDescriptor("a", "atest", "2");
+ CatalogItem t3 = addConnectorDescriptor("c", "ctest", "1");
+ CatalogItem t4 = addConnectorDescriptor("d", "dtest", "1");
+ CatalogItem t5 = addConnectorDescriptor("0", "0test", null);
+
+ assertEquals(-1, comparator.compare(t2, t1));
+ assertEquals(1, comparator.compare(t1, t2));
+ assertEquals(-1, comparator.compare(t3, t4));
+ assertEquals(1, comparator.compare(t4, t3));
+
+ assertEquals(-1, comparator.compare(t1, t5));
+ assertEquals(1, comparator.compare(t5, t1));
+ assertEquals(-1, comparator.compare(t2, t5));
+ assertEquals(1, comparator.compare(t5, t2));
+ assertEquals(-1, comparator.compare(t3, t5));
+ assertEquals(1, comparator.compare(t5, t3));
+ assertEquals(-1, comparator.compare(t4, t5));
+ assertEquals(1, comparator.compare(t5, t4));
+
+ assertEquals(-1, comparator.compare(t3, t1));
+ assertEquals(1, comparator.compare(t1, t3));
+ assertEquals(-1, comparator.compare(t3, t2));
+ assertEquals(1, comparator.compare(t2, t3));
+
+ assertEquals(-1, comparator.compare(t4, t1));
+ assertEquals(1, comparator.compare(t1, t4));
+ assertEquals(-1, comparator.compare(t4, t2));
+ assertEquals(1, comparator.compare(t2, t4));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/.project b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/.project
new file mode 100644
index 000000000..8d093325e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.discovery.test1-feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/build.properties b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/build.properties
new file mode 100644
index 000000000..64f93a9f0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/feature.xml b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/feature.xml
new file mode 100644
index 000000000..e5b89e0a5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test1-feature/feature.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.mylyn.discovery.test1"
+ label="Discovery Test Feature 1"
+ version="1.0.0.qualifier"
+ provider-name="Eclipse Mylyn">
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+</feature>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/.project b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/.project
new file mode 100644
index 000000000..647d36dee
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.discovery.test2-feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/build.properties b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/build.properties
new file mode 100644
index 000000000..64f93a9f0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/feature.xml b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/feature.xml
new file mode 100644
index 000000000..f2f089a23
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/org.eclipse.mylyn.discovery.test2-feature/feature.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.mylyn.discovery.test2"
+ label="Discovery Test Feature 2"
+ version="1.0.0.qualifier"
+ provider-name="Eclipse Mylyn">
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+ <includes
+ id="org.eclipse.mylyn.discovery.test1"
+ version="0.0.0"/>
+
+</feature>
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/artifacts.jar b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/artifacts.jar
new file mode 100644
index 000000000..7a37f6f91
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/artifacts.jar
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/content.jar b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/content.jar
new file mode 100644
index 000000000..78e190ba1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/content.jar
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test1_1.0.0.201001200403.jar b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test1_1.0.0.201001200403.jar
new file mode 100644
index 000000000..4ede52590
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test1_1.0.0.201001200403.jar
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test2_1.0.0.201001200403.jar b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test2_1.0.0.201001200403.jar
new file mode 100644
index 000000000..52b43d8ab
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests.discovery/testdata/update/features/org.eclipse.mylyn.discovery.test2_1.0.0.201001200403.jar
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.classpath b/bundles/org.eclipse.equinox.p2.ui.discovery/.classpath
new file mode 100644
index 000000000..64c5e31b7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.cvsignore b/bundles/org.eclipse.equinox.p2.ui.discovery/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.gitignore b/bundles/org.eclipse.equinox.p2.ui.discovery/.gitignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.project b/bundles/org.eclipse.equinox.p2.ui.discovery/.project
new file mode 100644
index 000000000..185488de7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.p2.ui.discovery</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..654a73733
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,339 @@
+#Tue May 12 21:05:03 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=80
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..8d68e732b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Thu Sep 11 16:27:18 PDT 2008
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Mylyn based on Eclipse
+formatter_settings_version=11
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*******************************************************************************\r\n * Copyright (c) 2010 Tasktop Technologies and others.\r\n * All rights reserved. This program and the accompanying materials\r\n * are made available under the terms of the Eclipse Public License v1.0\r\n * which accompanies this distribution, and is available at\r\n * http\://www.eclipse.org/legal/epl-v10.html\r\n *\r\n * Contributors\:\r\n * Tasktop Technologies - initial API and implementation\r\n *******************************************************************************/\r\n\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ignore\r\n${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ignore</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 000000000..d8c6d26af
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.team.ui.prefs b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 000000000..1f2471371
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Tue Feb 16 15:43:06 PST 2010
+commit.comment.template=${connector.task.prefix} ${task.key} - ${task.description}
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..5937a85ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,24 @@
+#Tue May 20 17:39:22 PDT 2008
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=2
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..2c74edc6d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.equinox.p2.ui.discovery;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui,
+ org.eclipse.ui.browser,
+ org.eclipse.equinox.p2.discovery;bundle-version="[1.0.0,1.1.0)",
+ org.eclipse.equinox.p2.discovery.compatiblity;bundle-version="1.0.0";resolution:=optional,
+ org.eclipse.equinox.p2.core;bundle-version="1.0.4";resolution:=optional,
+ org.eclipse.equinox.p2.ui;bundle-version="1.0.4";resolution:=optional,
+ org.eclipse.equinox.p2.metadata;bundle-version="1.0.0";resolution:=optional,
+ org.eclipse.equinox.p2.operations;resolution:=optional,
+ org.eclipse.equinox.p2.repository;bundle-version="1.0.0";resolution:=optional,
+ org.eclipse.equinox.p2.ui.sdk;bundle-version="1.0.100";resolution:=optional
+Export-Package: org.eclipse.equinox.internal.p2.ui.discovery;x-internal:=true,
+ org.eclipse.equinox.internal.p2.ui.discovery.commands;x-internal:=true,
+ org.eclipse.equinox.internal.p2.ui.discovery.operations;x-internal:=true,
+ org.eclipse.equinox.internal.p2.ui.discovery.repository;x-internal:=true,
+ org.eclipse.equinox.internal.p2.ui.discovery.util;x-internal:=true,
+ org.eclipse.equinox.internal.p2.ui.discovery.wizards;x-internal:=true
+Bundle-ClassPath: .
+Import-Package: com.ibm.icu.text
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/about.html b/bundles/org.eclipse.equinox.p2.ui.discovery/about.html
new file mode 100644
index 000000000..bc6e2b493
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>July 3, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
+
+
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/build.properties b/bundles/org.eclipse.equinox.p2.ui.discovery/build.properties
new file mode 100644
index 000000000..2aa561fa8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ icons/,\
+ plugin.properties
+src.includes = about.html
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear-disabled.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear-disabled.gif
new file mode 100644
index 000000000..7f3248023
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear-disabled.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear.gif
new file mode 100644
index 000000000..2d3935a68
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/etool16/find-clear.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_disabled_obj.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_disabled_obj.gif
new file mode 100644
index 000000000..f192b8486
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_disabled_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_obj.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_obj.gif
new file mode 100644
index 000000000..8706680c7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_update_obj.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_update_obj.gif
new file mode 100644
index 000000000..16f4f7c4e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/iu_update_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/message_info.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/message_info.gif
new file mode 100644
index 000000000..b484d9be1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/obj16/message_info.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/ovr32/message_warning.gif b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/ovr32/message_warning.gif
new file mode 100644
index 000000000..8e054d073
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/ovr32/message_warning.gif
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/icons/wizban/banner-discovery.png b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/wizban/banner-discovery.png
new file mode 100644
index 000000000..cc4b2cfd7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/icons/wizban/banner-discovery.png
Binary files differ
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.properties b/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.properties
new file mode 100644
index 000000000..68682584c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+Bundle-Vendor = Eclipse.org - Equinox
+Bundle-Name = Equinox Provisioning Discovery UI
+
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.xml b/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.xml
new file mode 100644
index 000000000..84a08eceb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/plugin.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+ Copyright (c) 2009 Tasktop Technologies 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
+ -->
+<plugin>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ id="org.eclipse.equinox.p2.ui.discovery.commands.ShowBundleCatalog"
+ name="Show Bundle Catalog">
+ </command>
+ <command
+ id="org.eclipse.equinox.p2.ui.discovery.commands.ShowRepositoryCatalog"
+ name="Show Repository Catalog">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.equinox.internal.p2.ui.discovery.commands.ShowBundleCatalogCommandHandler"
+ commandId="org.eclipse.equinox.p2.ui.discovery.commands.ShowBundleCatalog">
+ </handler>
+ <handler
+ class="org.eclipse.equinox.internal.p2.ui.discovery.commands.ShowRepositoryCatalogCommandHandler"
+ commandId="org.eclipse.equinox.p2.ui.discovery.commands.ShowRepositoryCatalog">
+ </handler>
+ </extension>
+</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryImages.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryImages.java
new file mode 100644
index 000000000..728c2719a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryImages.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class DiscoveryImages {
+
+ private static final String T_OVR_32 = "ovr32"; //$NON-NLS-1$
+
+ private static final String T_OBJ_16 = "obj16"; //$NON-NLS-1$
+
+ private static final String T_WIZBAN = "wizban"; //$NON-NLS-1$
+
+ private static final String T_TOOL = "etool16"; //$NON-NLS-1$
+
+ private static final URL baseURL = Platform.getBundle(DiscoveryUi.ID_PLUGIN).getEntry("/icons/"); //$NON-NLS-1$
+
+ /**
+ * image descriptor for a warning overlay suitable for use with 32x32 images.
+ */
+ public static final ImageDescriptor OVERLAY_WARNING_32 = create(T_OVR_32, "message_warning.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor BANNER_DISOVERY = create(T_WIZBAN, "banner-discovery.png"); //$NON-NLS-1$
+
+ public static final ImageDescriptor IU_AVAILABLE = create(T_OBJ_16, "iu_disabled_obj.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor IU_INSTALLED = create(T_OBJ_16, "iu_obj.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor IU_UPDATABLE = create(T_OBJ_16, "iu_update_obj.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor MESSAGE_INFO = create(T_OBJ_16, "message_info.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor FIND_CLEAR = create(T_TOOL, "find-clear.gif"); //$NON-NLS-1$
+
+ public static final ImageDescriptor FIND_CLEAR_DISABLED = create(T_TOOL, "find-clear-disabled.gif"); //$NON-NLS-1$
+
+ private static ImageRegistry imageRegistry;
+
+ private static ImageDescriptor create(String prefix, String name) {
+ try {
+ return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name));
+ } catch (MalformedURLException e) {
+ return ImageDescriptor.getMissingImageDescriptor();
+ }
+ }
+
+ private static URL makeIconFileURL(String prefix, String name) throws MalformedURLException {
+ if (baseURL == null) {
+ throw new MalformedURLException();
+ }
+
+ StringBuilder buffer = new StringBuilder(prefix);
+ buffer.append('/');
+ buffer.append(name);
+ return new URL(baseURL, buffer.toString());
+ }
+
+ /**
+ * Lazily initializes image map.
+ *
+ * @param imageDescriptor
+ * @return Image
+ */
+ public static Image getImage(ImageDescriptor imageDescriptor) {
+ ImageRegistry imageRegistry = getImageRegistry();
+ Image image = imageRegistry.get("" + imageDescriptor.hashCode()); //$NON-NLS-1$
+ if (image == null) {
+ image = imageDescriptor.createImage(true);
+ imageRegistry.put("" + imageDescriptor.hashCode(), image); //$NON-NLS-1$
+ }
+ return image;
+ }
+
+ private static ImageRegistry getImageRegistry() {
+ if (imageRegistry == null) {
+ imageRegistry = new ImageRegistry();
+ }
+ return imageRegistry;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryUi.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryUi.java
new file mode 100644
index 000000000..dcf065fdb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/DiscoveryUi.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.ui.discovery.operations.DiscoveryInstallOperation;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.CommonColors;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.Messages;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * @author David Green
+ */
+public abstract class DiscoveryUi {
+
+ public static final String ID_PLUGIN = "org.eclipse.equinox.p2.ui.discovery"; //$NON-NLS-1$
+
+ private static CommonColors commonColors;
+
+ private DiscoveryUi() {
+ }
+
+ public static boolean install(List<CatalogItem> descriptors, IRunnableContext context) {
+ try {
+ IRunnableWithProgress runner = new DiscoveryInstallOperation(descriptors);
+ context.run(true, true, runner);
+ } catch (InvocationTargetException e) {
+ IStatus status = new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN, NLS.bind(
+ Messages.ConnectorDiscoveryWizard_installProblems, new Object[] { e.getCause().getMessage() }),
+ e.getCause());
+ StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ return false;
+ } catch (InterruptedException e) {
+ // canceled
+ return false;
+ }
+ return true;
+ }
+
+ public static CommonColors getCommonsColors() {
+ if (commonColors == null) {
+ commonColors = new CommonColors(Display.getDefault(), JFaceResources.getResources());
+ }
+ return commonColors;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/Messages.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/Messages.java
new file mode 100644
index 000000000..cfbf9ea80
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/Messages.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.commands;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.ui.discovery.commands.messages"; //$NON-NLS-1$
+
+ public static String ShowConnectorDiscoveryWizardCommandHandler_Install_Connectors;
+
+ public static String ShowConnectorDiscoveryWizardCommandHandler_Unable_To_Install_No_P2;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowBundleCatalogCommandHandler.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowBundleCatalogCommandHandler.java
new file mode 100644
index 000000000..4614377f9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowBundleCatalogCommandHandler.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.commands;
+
+import java.util.Arrays;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.BundleDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.ConnectorDiscoveryExtensionReader;
+import org.eclipse.equinox.internal.p2.discovery.compatibility.RemoteBundleDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogConfiguration;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.DiscoveryWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+
+/**
+ * A command that causes the {@link CatalogWizard} to appear in a dialog.
+ *
+ * @author David Green
+ */
+public class ShowBundleCatalogCommandHandler extends AbstractHandler {
+
+ private static final String DEFAULT_DIRECTORY_URL = "http://www.eclipse.org/mylyn/discovery/directory-3.3.xml"; //$NON-NLS-1$
+
+ private static final String SYSTEM_PROPERTY_DIRECTORY_URL = "mylyn.discovery.directory"; //$NON-NLS-1$
+
+ private static final String ID_P2_INSTALL_UI = "org.eclipse.equinox.p2.ui.sdk/org.eclipse.equinox.p2.ui.sdk.install"; //$NON-NLS-1$
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // check to make sure that the p2 install ui is enabled
+ if (WorkbenchUtil.allowUseOf(ID_P2_INSTALL_UI)) {
+ Catalog catalog = new Catalog();
+ catalog.setTags(Arrays.asList(ConnectorDiscoveryExtensionReader.TAGS));
+
+ // look for descriptors from installed bundles
+ catalog.getDiscoveryStrategies().add(new BundleDiscoveryStrategy());
+
+ // look for remote descriptor
+ String directoryUrl = System.getProperty(SYSTEM_PROPERTY_DIRECTORY_URL, DEFAULT_DIRECTORY_URL);
+ if (directoryUrl.length() > 0) {
+ RemoteBundleDiscoveryStrategy remoteDiscoveryStrategy = new RemoteBundleDiscoveryStrategy();
+ remoteDiscoveryStrategy.setDirectoryUrl(directoryUrl);
+ catalog.getDiscoveryStrategies().add(remoteDiscoveryStrategy);
+ }
+
+ catalog.setEnvironment(DiscoveryCore.createEnvironment());
+ catalog.setVerifyUpdateSiteAvailability(false);
+
+ CatalogConfiguration configuration = new CatalogConfiguration();
+ configuration.setShowTagFilter(true);
+ configuration.setSelectedTags(catalog.getTags());
+
+ DiscoveryWizard wizard = new DiscoveryWizard(catalog, configuration);
+ WizardDialog dialog = new WizardDialog(WorkbenchUtil.getShell(), wizard);
+ dialog.open();
+ } else {
+ MessageDialog.openWarning(WorkbenchUtil.getShell(),
+ Messages.ShowConnectorDiscoveryWizardCommandHandler_Install_Connectors,
+ Messages.ShowConnectorDiscoveryWizardCommandHandler_Unable_To_Install_No_P2);
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowRepositoryCatalogCommandHandler.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowRepositoryCatalogCommandHandler.java
new file mode 100644
index 000000000..483e8daf7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/ShowRepositoryCatalogCommandHandler.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.commands;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
+import org.eclipse.equinox.internal.p2.ui.discovery.repository.RepositoryDiscoveryStrategy;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.CatalogConfiguration;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.DiscoveryWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+
+/**
+ * A command that causes the {@link CatalogWizard} to appear in a dialog.
+ *
+ * @author Steffen Pingel
+ */
+public class ShowRepositoryCatalogCommandHandler extends AbstractHandler {
+
+ private static final String DEFAULT_REPOSITORY_URL = "http://download.eclipse.org/tools/mylyn/update/e3.4"; //$NON-NLS-1$
+
+ private static final String ID_P2_INSTALL_UI = "org.eclipse.equinox.p2.ui.sdk/org.eclipse.equinox.p2.ui.sdk.install"; //$NON-NLS-1$
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // check to make sure that the p2 install ui is enabled
+ if (WorkbenchUtil.allowUseOf(ID_P2_INSTALL_UI)) {
+ Catalog catalog = new Catalog();
+
+ // look for descriptors from installed bundles
+ RepositoryDiscoveryStrategy strategy = new RepositoryDiscoveryStrategy();
+ try {
+ strategy.addLocation(new URI(DEFAULT_REPOSITORY_URL));
+ } catch (URISyntaxException e) {
+ throw new ExecutionException("Invalid location format", e);
+ }
+ catalog.getDiscoveryStrategies().add(strategy);
+
+ catalog.setEnvironment(DiscoveryCore.createEnvironment());
+ catalog.setVerifyUpdateSiteAvailability(false);
+
+ CatalogConfiguration configuration = new CatalogConfiguration();
+ configuration.setShowTagFilter(false);
+
+ DiscoveryWizard wizard = new DiscoveryWizard(catalog, configuration);
+ WizardDialog dialog = new WizardDialog(WorkbenchUtil.getShell(), wizard);
+ dialog.open();
+ } else {
+ MessageDialog.openWarning(WorkbenchUtil.getShell(),
+ Messages.ShowConnectorDiscoveryWizardCommandHandler_Install_Connectors,
+ Messages.ShowConnectorDiscoveryWizardCommandHandler_Unable_To_Install_No_P2);
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/messages.properties b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/messages.properties
new file mode 100644
index 000000000..7b53ed34a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/commands/messages.properties
@@ -0,0 +1,2 @@
+ShowConnectorDiscoveryWizardCommandHandler_Install_Connectors=Install Connectors
+ShowConnectorDiscoveryWizardCommandHandler_Unable_To_Install_No_P2=Unable to launch connector install since the required p2 plugins are not available. Please contact your software vendor to correct this problem.
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java
new file mode 100644
index 000000000..d4e89620d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/operations/DiscoveryInstallOperation.java
@@ -0,0 +1,353 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+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.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.Messages;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IProvidedCapability;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.operations.InstallOperation;
+import org.eclipse.equinox.p2.operations.ProvisioningSession;
+import org.eclipse.equinox.p2.operations.RepositoryTracker;
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.ui.ProvisioningUI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A job that configures a p2 {@link #getInstallAction() install action} for installing 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. After running the job the {@link #getInstallAction() install action}
+ * must be run to perform the installation.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class DiscoveryInstallOperation implements IRunnableWithProgress {
+
+ private static final String P2_FEATURE_GROUP_SUFFIX = ".feature.group"; //$NON-NLS-1$
+
+ private final List<CatalogItem> installableConnectors;
+
+ private final ProvisioningUI provisioningUI;
+
+ private Set<URI> repositoryLocations;
+
+ public DiscoveryInstallOperation(List<CatalogItem> installableConnectors) {
+ if (installableConnectors == null || installableConnectors.isEmpty()) {
+ throw new IllegalArgumentException();
+ }
+ this.installableConnectors = new ArrayList<CatalogItem>(installableConnectors);
+ this.provisioningUI = ProvisioningUI.getDefaultUI();
+ }
+
+ public void run(IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
+ try {
+ SubMonitor monitor = SubMonitor.convert(progressMonitor, Messages.InstallConnectorsJob_task_configuring,
+ 100);
+ try {
+ final IInstallableUnit[] ius = computeInstallableUnits(monitor.newChild(50));
+
+ checkCancelled(monitor);
+
+ final InstallOperation installOperation = resolve(monitor.newChild(50), ius,
+ repositoryLocations.toArray(new URI[0]));
+
+ checkCancelled(monitor);
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ provisioningUI.openInstallWizard(WorkbenchUtil.getShell(), Arrays.asList(ius),
+ installOperation, null);
+ }
+ });
+ } finally {
+ monitor.done();
+ }
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException();
+ } catch (Exception e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ private void checkCancelled(IProgressMonitor monitor) {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ private InstallOperation resolve(IProgressMonitor monitor, final IInstallableUnit[] ius, URI[] repositories)
+ throws CoreException {
+ final InstallOperation installOperation = provisioningUI.getInstallOperation(Arrays.asList(ius), repositories);
+ IStatus operationStatus = installOperation.resolveModal(new SubProgressMonitor(monitor,
+ installableConnectors.size()));
+ if (operationStatus.getSeverity() > IStatus.WARNING) {
+ throw new CoreException(operationStatus);
+ }
+ return installOperation;
+ }
+
+ public IInstallableUnit[] computeInstallableUnits(SubMonitor monitor) throws CoreException {
+ try {
+ monitor.setWorkRemaining(100);
+ // add repository urls and load meta data
+ List<IMetadataRepository> repositories = addRepositories(monitor.newChild(50));
+ final List<IInstallableUnit> installableUnits = queryInstallableUnits(monitor.newChild(50), repositories);
+ removeOldVersions(installableUnits);
+ checkForUnavailable(installableUnits);
+ return installableUnits.toArray(new IInstallableUnit[installableUnits.size()]);
+
+// MultiStatus status = new MultiStatus(DiscoveryUi.ID_PLUGIN, 0, Messages.PrepareInstallProfileJob_ok, null);
+// ius = installableUnits.toArray(new IInstallableUnit[installableUnits.size()]);
+// ProfileChangeRequest profileChangeRequest = InstallAction.computeProfileChangeRequest(ius, profileId,
+// status, new SubProgressMonitor(monitor, installableConnectors.size()));
+// if (status.getSeverity() > IStatus.WARNING) {
+// throw new CoreException(status);
+// }
+// if (profileChangeRequest == null) {
+// // failed but no indication as to why
+// throw new CoreException(new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN,
+// Messages.PrepareInstallProfileJob_computeProfileChangeRequestFailed, null));
+// }
+// PlannerResolutionOperation operation = new PlannerResolutionOperation(
+// Messages.PrepareInstallProfileJob_calculatingRequirements, profileId, profileChangeRequest, null,
+// status, true);
+// IStatus operationStatus = operation.execute(new SubProgressMonitor(monitor, installableConnectors.size()));
+// if (operationStatus.getSeverity() > IStatus.WARNING) {
+// throw new CoreException(operationStatus);
+// }
+//
+// plannerResolutionOperation = operation;
+
+ } catch (URISyntaxException e) {
+ // should never happen, since we already validated URLs.
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN,
+ Messages.InstallConnectorsJob_unexpectedError_url, e));
+ } catch (MalformedURLException e) {
+ // should never happen, since we already validated URLs.
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN,
+ Messages.InstallConnectorsJob_unexpectedError_url, e));
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
+ * Verifies that we found what we were looking for: it's possible that we have connector descriptors that are no
+ * longer available on their respective sites. In that case we must inform the user. Unfortunately this is the
+ * earliest point at which we can know.
+ */
+ private void checkForUnavailable(final List<IInstallableUnit> installableUnits) throws CoreException {
+ // at least one selected connector could not be found in a repository
+ Set<String> foundIds = new HashSet<String>();
+ for (IInstallableUnit unit : installableUnits) {
+ String id = unit.getId();
+ if (id.endsWith(P2_FEATURE_GROUP_SUFFIX)) {
+ id = id.substring(0, id.indexOf(P2_FEATURE_GROUP_SUFFIX));
+ }
+ foundIds.add(id);
+ }
+
+ String message = ""; //$NON-NLS-1$
+ String detailedMessage = ""; //$NON-NLS-1$
+ for (CatalogItem descriptor : installableConnectors) {
+ StringBuilder unavailableIds = null;
+ for (String id : descriptor.getInstallableUnits()) {
+ if (!foundIds.contains(id)) {
+ if (unavailableIds == null) {
+ unavailableIds = new StringBuilder();
+ } else {
+ unavailableIds.append(Messages.InstallConnectorsJob_commaSeparator);
+ }
+ unavailableIds.append(id);
+ }
+ }
+ if (unavailableIds != null) {
+ if (message.length() > 0) {
+ message += Messages.InstallConnectorsJob_commaSeparator;
+ }
+ message += descriptor.getName();
+
+ if (detailedMessage.length() > 0) {
+ detailedMessage += Messages.InstallConnectorsJob_commaSeparator;
+ }
+ detailedMessage += NLS.bind(Messages.PrepareInstallProfileJob_notFoundDescriptorDetail, new Object[] {
+ descriptor.getName(), unavailableIds.toString(), descriptor.getSiteUrl() });
+ }
+ }
+
+ if (message.length() > 0) {
+ // instead of aborting here we ask the user if they wish to proceed anyways
+ final boolean[] okayToProceed = new boolean[1];
+ final String finalMessage = message;
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ okayToProceed[0] = MessageDialog.openQuestion(WorkbenchUtil.getShell(),
+ Messages.InstallConnectorsJob_questionProceed, NLS.bind(
+ Messages.InstallConnectorsJob_questionProceed_long, new Object[] { finalMessage }));
+ }
+ });
+ if (!okayToProceed[0]) {
+ throw new CoreException(new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN, NLS.bind(
+ Messages.InstallConnectorsJob_connectorsNotAvailable, detailedMessage), null));
+ }
+ }
+ }
+
+ /**
+ * Filters those installable units that have a duplicate in the list with a higher version number. it's possible
+ * that some repositories will host multiple versions of a particular feature. we assume that the user wants the
+ * highest version.
+ */
+ private void removeOldVersions(final List<IInstallableUnit> installableUnits) {
+ Map<String, Version> symbolicNameToVersion = new HashMap<String, Version>();
+ for (IInstallableUnit unit : installableUnits) {
+ Version version = symbolicNameToVersion.get(unit.getId());
+ if (version == null || version.compareTo(unit.getVersion()) == -1) {
+ symbolicNameToVersion.put(unit.getId(), unit.getVersion());
+ }
+ }
+ if (symbolicNameToVersion.size() != installableUnits.size()) {
+ for (IInstallableUnit unit : new ArrayList<IInstallableUnit>(installableUnits)) {
+ Version version = symbolicNameToVersion.get(unit.getId());
+ if (!version.equals(unit.getVersion())) {
+ installableUnits.remove(unit);
+ }
+ }
+ }
+ }
+
+ /**
+ * Perform a query to get the installable units. This causes p2 to determine what features are available in each
+ * repository. We select installable units by matching both the feature id and the repository; it is possible though
+ * unlikely that the same feature id is available from more than one of the selected repositories, and we must
+ * ensure that the user gets the one that they asked for.
+ */
+ private List<IInstallableUnit> queryInstallableUnits(SubMonitor monitor, List<IMetadataRepository> repositories)
+ throws URISyntaxException {
+ final List<IInstallableUnit> installableUnits = new ArrayList<IInstallableUnit>();
+
+ monitor.setWorkRemaining(repositories.size());
+ for (final IMetadataRepository repository : repositories) {
+ checkCancelled(monitor);
+ final Set<String> installableUnitIdsThisRepository = getDescriptorIds(repository);
+ IQuery<IInstallableUnit> query = new MatchQuery<IInstallableUnit>() {
+ @Override
+ public boolean isMatch(IInstallableUnit candidate) {
+ if ("true".equalsIgnoreCase(candidate.getProperty("org.eclipse.equinox.p2.type.group"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ String id = candidate.getId();
+ if (isQualifyingFeature(installableUnitIdsThisRepository, id)) {
+ Collection<IProvidedCapability> providedCapabilities = candidate.getProvidedCapabilities();
+ if (providedCapabilities != null && providedCapabilities.size() > 0) {
+ for (IProvidedCapability capability : providedCapabilities) {
+ if ("org.eclipse.equinox.p2.iu".equals(capability.getNamespace())) { //$NON-NLS-1$
+ String name = capability.getName();
+ if (isQualifyingFeature(installableUnitIdsThisRepository, name)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isQualifyingFeature(final Set<String> installableUnitIdsThisRepository, String id) {
+ return id.endsWith(P2_FEATURE_GROUP_SUFFIX)
+ && installableUnitIdsThisRepository.contains(id.substring(0,
+ id.indexOf(P2_FEATURE_GROUP_SUFFIX)));
+ }
+ };
+ IQueryResult<IInstallableUnit> result = repository.query(query, monitor.newChild(1));
+ installableUnits.addAll(result.toSet());
+ }
+ return installableUnits;
+ }
+
+ private List<IMetadataRepository> addRepositories(SubMonitor monitor) throws MalformedURLException,
+ URISyntaxException, ProvisionException {
+ // tell p2 that it's okay to use these repositories
+ ProvisioningSession session = ProvisioningUI.getDefaultUI().getSession();
+ RepositoryTracker repositoryTracker = ProvisioningUI.getDefaultUI().getRepositoryTracker();
+ repositoryLocations = new HashSet<URI>();
+ monitor.setWorkRemaining(installableConnectors.size() * 5);
+ for (CatalogItem descriptor : installableConnectors) {
+ URI uri = new URL(descriptor.getSiteUrl()).toURI();
+ if (repositoryLocations.add(uri)) {
+ checkCancelled(monitor);
+ repositoryTracker.addRepository(uri, null, session);
+// ProvisioningUtil.addMetaDataRepository(url.toURI(), true);
+// ProvisioningUtil.addArtifactRepository(url.toURI(), true);
+// ProvisioningUtil.setColocatedRepositoryEnablement(url.toURI(), true);
+ }
+ monitor.worked(1);
+ }
+
+ // fetch meta-data for these repositories
+ ArrayList<IMetadataRepository> repositories = new ArrayList<IMetadataRepository>();
+ monitor.setWorkRemaining(repositories.size());
+ for (URI uri : repositoryLocations) {
+ checkCancelled(monitor);
+ IMetadataRepository repository = session.getMetadataRepositoryManager().loadRepository(uri,
+ monitor.newChild(1));
+ repositories.add(repository);
+ }
+ return repositories;
+ }
+
+ private Set<String> getDescriptorIds(final IMetadataRepository repository) throws URISyntaxException {
+ final Set<String> installableUnitIdsThisRepository = new HashSet<String>();
+ // determine all installable units for this repository
+ for (CatalogItem descriptor : installableConnectors) {
+ try {
+ if (repository.getLocation().equals(new URL(descriptor.getSiteUrl()).toURI())) {
+ installableUnitIdsThisRepository.addAll(descriptor.getInstallableUnits());
+ }
+ } catch (MalformedURLException e) {
+ // will never happen, ignore
+ }
+ }
+ return installableUnitIdsThisRepository;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositoryDiscoveryStrategy.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositoryDiscoveryStrategy.java
new file mode 100644
index 000000000..a2ca1e523
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositoryDiscoveryStrategy.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.repository;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.core.runtime.SubMonitor;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+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;
+import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
+import org.eclipse.equinox.internal.p2.metadata.TranslationSupport;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IProvidedCapability;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.operations.ProvisioningSession;
+import org.eclipse.equinox.p2.operations.RepositoryTracker;
+import org.eclipse.equinox.p2.query.IQuery;
+import org.eclipse.equinox.p2.query.MatchQuery;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.ui.ProvisioningUI;
+
+/**
+ * @author Steffen Pingel
+ */
+public class RepositoryDiscoveryStrategy extends AbstractDiscoveryStrategy {
+
+ private static final String IU_PROPERTY_CATEGORY = "org.eclipse.equinox.p2.type.category"; //$NON-NLS-1$
+
+ private static final String PLUGIN_ID = "org.eclipse.equinox.p2.discovery.repository"; //$NON-NLS-1$
+
+ private static final String P2_FEATURE_GROUP_SUFFIX = ".feature.group"; //$NON-NLS-1$
+
+ private final List<URI> locations;
+
+ private final Map<IMetadataRepository, RepositorySource> sourceByRepository;
+
+ private final Map<String, CatalogCategory> categoryById;
+
+ private final Map<String, CatalogItem> catalogItemById;
+
+ public RepositoryDiscoveryStrategy() {
+ this.locations = new ArrayList<URI>();
+ this.sourceByRepository = new HashMap<IMetadataRepository, RepositorySource>();
+ this.categoryById = new HashMap<String, CatalogCategory>();
+ this.catalogItemById = new HashMap<String, CatalogItem>();
+ }
+
+ public void addLocation(URI location) {
+ locations.add(location);
+ }
+
+ public void removeLocation(URI location) {
+ locations.remove(location);
+ }
+
+ @Override
+ public void performDiscovery(IProgressMonitor progressMonitor) throws CoreException {
+ // ignore
+ SubMonitor monitor = SubMonitor.convert(progressMonitor);
+ monitor.setWorkRemaining(100);
+ try {
+ List<IMetadataRepository> repositories = addRepositories(monitor.newChild(50));
+ queryInstallableUnits(monitor.newChild(50), repositories);
+ connectCategories();
+ } catch (ProvisionException e) {
+ throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "Failed to process repository contents", e));
+ }
+ }
+
+ @SuppressWarnings("restriction")
+ private void connectCategories() {
+ for (CatalogCategory category : categories) {
+ if (category.getData() instanceof IInstallableUnit) {
+ IInstallableUnit categoryIU = (IInstallableUnit) category.getData();
+ Collection<IRequirement> required = categoryIU.getRequiredCapabilities();
+ for (IRequirement requirement : required) {
+ if (requirement instanceof IRequiredCapability) {
+ IRequiredCapability capability = (IRequiredCapability) requirement;
+ CatalogItem item = catalogItemById.get(capability.getName());
+ if (item != null) {
+ item.setCategoryId(category.getId());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private List<IMetadataRepository> addRepositories(SubMonitor monitor) throws ProvisionException {
+ ProvisioningSession session = ProvisioningUI.getDefaultUI().getSession();
+
+ monitor.setWorkRemaining(locations.size());
+
+ RepositoryTracker repositoryTracker = ProvisioningUI.getDefaultUI().getRepositoryTracker();
+ for (URI location : locations) {
+ repositoryTracker.addRepository(location, null, session);
+ monitor.worked(1);
+ }
+
+ // fetch meta-data for these repositories
+ ArrayList<IMetadataRepository> repositories = new ArrayList<IMetadataRepository>();
+ for (URI uri : locations) {
+ IMetadataRepository repository = session.getMetadataRepositoryManager().loadRepository(uri,
+ monitor.newChild(1));
+ repositories.add(repository);
+ }
+ return repositories;
+ }
+
+ private void checkCancelled(IProgressMonitor monitor) {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ private void queryInstallableUnits(SubMonitor monitor, List<IMetadataRepository> repositories) {
+ monitor.setWorkRemaining(repositories.size());
+ for (final IMetadataRepository repository : repositories) {
+ checkCancelled(monitor);
+ IQuery<IInstallableUnit> query = new MatchQuery<IInstallableUnit>() {
+ @Override
+ public boolean isMatch(IInstallableUnit candidate) {
+ if (isQualifyingFeature(candidate)) {
+ process(repository, candidate);
+ return true;
+ }
+ return false;
+ }
+ };
+ repository.query(query, monitor.newChild(1));
+ }
+ }
+
+ protected void process(IMetadataRepository repository, IInstallableUnit candidate) {
+ if (isCategory(candidate)) {
+ processCategory(repository, candidate);
+ } else {
+ processCatalogItem(repository, candidate);
+ }
+ }
+
+ private CatalogItem processCatalogItem(IMetadataRepository repository, IInstallableUnit candidate) {
+ CatalogItem item = catalogItemById.get(candidate.getId());
+ if (item != null) {
+ return item;
+ }
+
+ item = new CatalogItem();
+ item.setId(candidate.getId());
+ item.setDescription(getProperty(candidate, IInstallableUnit.PROP_DESCRIPTION));
+ item.setName(getProperty(candidate, IInstallableUnit.PROP_NAME));
+ item.setProvider(getProperty(candidate, IInstallableUnit.PROP_PROVIDER));
+ item.setSource(getSource(repository));
+ item.setData(candidate);
+ item.setSiteUrl(repository.getLocation().toString());
+ item.getInstallableUnits().add(item.getId());
+
+ catalogItemById.put(item.getId(), item);
+ items.add(item);
+ return item;
+ }
+
+ public String getProperty(IInstallableUnit candidate, String key) {
+ String value = TranslationSupport.getInstance().getIUProperty(candidate, key);
+ return (value != null) ? value : "";
+ }
+
+ private AbstractCatalogSource getSource(IMetadataRepository repository) {
+ RepositorySource source = sourceByRepository.get(repository);
+ if (source == null) {
+ source = new RepositorySource(repository);
+ sourceByRepository.put(repository, source);
+ }
+ return source;
+ }
+
+ private CatalogCategory processCategory(IMetadataRepository repository, IInstallableUnit candidate) {
+ CatalogCategory category = categoryById.get(candidate.getId());
+ if (category != null) {
+ return category;
+ }
+
+ category = new CatalogCategory();
+ category.setId(candidate.getId());
+ category.setDescription(getProperty(candidate, IInstallableUnit.PROP_DESCRIPTION));
+ category.setName(getProperty(candidate, IInstallableUnit.PROP_NAME));
+ category.setSource(getSource(repository));
+ category.setData(candidate);
+
+ categoryById.put(category.getId(), category);
+ categories.add(category);
+ return category;
+ }
+
+ private boolean isQualifyingFeature(IInstallableUnit candidate) {
+ if (candidate.getId().endsWith(P2_FEATURE_GROUP_SUFFIX)) {
+ Collection<IProvidedCapability> providedCapabilities = candidate.getProvidedCapabilities();
+ if (providedCapabilities != null && providedCapabilities.size() > 0) {
+ for (IProvidedCapability capability : providedCapabilities) {
+ if ("org.eclipse.equinox.p2.iu".equals(capability.getNamespace())) { //$NON-NLS-1$
+ String name = capability.getName();
+ if (name.endsWith(P2_FEATURE_GROUP_SUFFIX)) {
+ return true;
+ }
+ }
+ }
+ }
+ } else if (isCategory(candidate)) {
+ return true;
+ }
+ return false;
+ }
+
+ private Boolean isCategory(IInstallableUnit candidate) {
+ return Boolean.valueOf(candidate.getProperty(IU_PROPERTY_CATEGORY));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositorySource.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositorySource.java
new file mode 100644
index 000000000..e6b1f08e7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/repository/RepositorySource.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.repository;
+
+import java.net.URL;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+
+/**
+ * @author Steffen Pingel
+ */
+public class RepositorySource extends AbstractCatalogSource {
+
+ private final IMetadataRepository repository;
+
+ public RepositorySource(IMetadataRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public Object getId() {
+ return repository.getLocation();
+ }
+
+ @Override
+ public URL getResource(String resourceName) {
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/CommonColors.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/CommonColors.java
new file mode 100644
index 000000000..65abd87c0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/CommonColors.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Benjamin Pasero - initial contribution from RSSOwl, bug 177974
+ * Tasktop Technologies - improvements
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.jface.resource.DeviceResourceException;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Based on {org.eclipse.ui.forms.FormColors}.
+ *
+ * @author Benjamin Pasero
+ * @author Mik Kersten
+ */
+public class CommonColors {
+
+ private final Display display;
+
+ private Color titleText;
+
+ private Color gradientBegin;
+
+ private Color gradientEnd;
+
+ private Color border;
+
+ private final ResourceManager resourceManager;
+
+ public CommonColors(Display display, ResourceManager resourceManager) {
+ this.display = display;
+ this.resourceManager = resourceManager;
+
+ createColors();
+ }
+
+ private void createColors() {
+ createBorderColor();
+ createGradientColors();
+ // previously used SWT.COLOR_TITLE_INACTIVE_FOREGROUND, but too light on Windows XP
+ titleText = getColor(resourceManager, getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW));
+ }
+
+ public Color getGradientBegin() {
+ return gradientBegin;
+ }
+
+ public Color getGradientEnd() {
+ return gradientEnd;
+ }
+
+ public Color getBorder() {
+ return border;
+ }
+
+ public Color getTitleText() {
+ return titleText;
+ }
+
+ private void createBorderColor() {
+ RGB tbBorder = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
+ RGB bg = getImpliedBackground().getRGB();
+
+ // Group 1
+ // Rule: If at least 2 of the RGB values are equal to or between 180 and
+ // 255, then apply specified opacity for Group 1
+ // Examples: Vista, XP Silver, Wn High Con #2
+ // Keyline = TITLE_BACKGROUND @ 70% Opacity over LIST_BACKGROUND
+ if (testTwoPrimaryColors(tbBorder, 179, 256)) {
+ tbBorder = blend(tbBorder, bg, 70);
+ } else if (testTwoPrimaryColors(tbBorder, 120, 180)) {
+ tbBorder = blend(tbBorder, bg, 50);
+ } else {
+ tbBorder = blend(tbBorder, bg, 30);
+ }
+
+ border = getColor(resourceManager, tbBorder);
+ }
+
+ private void createGradientColors() {
+ RGB titleBg = getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
+ Color bgColor = getImpliedBackground();
+ RGB bg = bgColor.getRGB();
+ RGB bottom, top;
+
+ // Group 1
+ // Rule: If at least 2 of the RGB values are equal to or between 180 and
+ // 255, then apply specified opacity for Group 1
+ // Examples: Vista, XP Silver, Wn High Con #2
+ // Gradient Bottom = TITLE_BACKGROUND @ 30% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ if (testTwoPrimaryColors(titleBg, 179, 256)) {
+ bottom = blend(titleBg, bg, 30);
+ top = bg;
+ }
+
+ // Group 2
+ // Rule: If at least 2 of the RGB values are equal to or between 121 and
+ // 179, then apply specified opacity for Group 2
+ // Examples: XP Olive, OSX Graphite, Linux GTK, Wn High Con Black
+ // Gradient Bottom = TITLE_BACKGROUND @ 20% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ else if (testTwoPrimaryColors(titleBg, 120, 180)) {
+ bottom = blend(titleBg, bg, 20);
+ top = bg;
+ }
+
+ // Group 3
+ // Rule: If at least 2 of the RGB values are equal to or between 0 and
+ // 120, then apply specified opacity for Group 3
+ // Examples: XP Default, Wn Classic Standard, Wn Marine, Wn Plum, OSX
+ // Aqua, Wn High Con White, Wn High Con #1
+ // Gradient Bottom = TITLE_BACKGROUND @ 10% Opacity over LIST_BACKGROUND
+ // Gradient Top = TITLE BACKGROUND @ 0% Opacity over LIST_BACKGROUND
+ else {
+ bottom = blend(titleBg, bg, 10);
+ top = bg;
+ }
+
+ gradientBegin = getColor(resourceManager, top);
+ gradientEnd = getColor(resourceManager, bottom);
+ }
+
+ private RGB blend(RGB c1, RGB c2, int ratio) {
+ int r = blend(c1.red, c2.red, ratio);
+ int g = blend(c1.green, c2.green, ratio);
+ int b = blend(c1.blue, c2.blue, ratio);
+ return new RGB(r, g, b);
+ }
+
+ private int blend(int v1, int v2, int ratio) {
+ int b = (ratio * v1 + (100 - ratio) * v2) / 100;
+ return Math.min(255, b);
+ }
+
+ private boolean testTwoPrimaryColors(RGB rgb, int from, int to) {
+ int total = 0;
+ if (testPrimaryColor(rgb.red, from, to)) {
+ total++;
+ }
+ if (testPrimaryColor(rgb.green, from, to)) {
+ total++;
+ }
+ if (testPrimaryColor(rgb.blue, from, to)) {
+ total++;
+ }
+ return total >= 2;
+ }
+
+ private boolean testPrimaryColor(int value, int from, int to) {
+ return value > from && value < to;
+ }
+
+ private RGB getSystemColor(int code) {
+ return getDisplay().getSystemColor(code).getRGB();
+ }
+
+ private Color getImpliedBackground() {
+ return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ }
+
+ private Display getDisplay() {
+ return display;
+ }
+
+ private Color getColor(ResourceManager manager, RGB rgb) {
+ try {
+ return manager.createColor(rgb);
+ } catch (DeviceResourceException e) {
+ return manager.getDevice().getSystemColor(SWT.COLOR_BLACK);
+ }
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListItem.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListItem.java
new file mode 100644
index 000000000..86874122c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListItem.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Tasktop Technologies - generalized ProgressInfoItem for reuse
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Based on {@link org.eclipse.ui.internal.progress.ProgressInfoItem}.
+ *
+ * @author Steffen Pingel
+ */
+public abstract class ControlListItem<T> extends Composite {
+
+ static String DARK_COLOR_KEY = "org.eclipse.mylyn.commons.ui.ControlListItem.DARK_COLOR"; //$NON-NLS-1$
+
+ interface IndexListener {
+
+ /**
+ * Select the item previous to the receiver.
+ */
+ public void selectPrevious();
+
+ /**
+ * Select the next previous to the receiver.
+ */
+ public void selectNext();
+
+ /**
+ * Select the receiver.
+ */
+ public void select();
+
+ public void open();
+
+ }
+
+ IndexListener indexListener;
+
+ private int currentIndex;
+
+ private boolean selected;
+
+ private final MouseAdapter mouseListener;
+
+ private boolean isShowing = true;
+
+ private final MouseTrackAdapter mouseTrackListener;
+
+ private boolean hot;
+
+ static {
+ // Mac has different Gamma value
+ int shift = "carbon".equals(SWT.getPlatform()) ? -25 : -10;//$NON-NLS-1$
+
+ Color lightColor = PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+
+ // Determine a dark color by shifting the list color
+ RGB darkRGB = new RGB(Math.max(0, lightColor.getRed() + shift), Math.max(0, lightColor.getGreen() + shift),
+ Math.max(0, lightColor.getBlue() + shift));
+ JFaceResources.getColorRegistry().put(DARK_COLOR_KEY, darkRGB);
+ }
+
+ /**
+ * Create a new instance of the receiver with the specified parent, style and info object/
+ *
+ * @param parent
+ * @param style
+ * @param progressInfo
+ */
+ public ControlListItem(Composite parent, int style, T element) {
+ super(parent, style | SWT.NO_FOCUS);
+ Assert.isNotNull(element);
+ super.setData(element);
+ setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
+ mouseListener = doCreateMouseListener();
+ mouseTrackListener = doCreateMouseTrackListener();
+ registerChild(this);
+// Control[] children = getChildren();
+// for (Control child : children) {
+// registerChild(child);
+// }
+ setHot(false);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public T getData() {
+ return (T) super.getData();
+ }
+
+ @Override
+ public void setData(Object data) {
+ throw new IllegalArgumentException();
+ }
+
+ private MouseTrackAdapter doCreateMouseTrackListener() {
+ return new MouseTrackAdapter() {
+ private int enterCount;
+
+ @Override
+ public void mouseEnter(MouseEvent e) {
+ enterCount++;
+ updateHotState();
+ }
+
+ @Override
+ public void mouseExit(MouseEvent e) {
+ enterCount--;
+ getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (!isDisposed()) {
+ updateHotState();
+ }
+ }
+ });
+ }
+
+ private void updateHotState() {
+ if (enterCount == 0) {
+ if (isHot()) {
+ setHot(false);
+ }
+ } else {
+ if (!isHot()) {
+ setHot(true);
+ }
+ }
+ }
+ };
+ }
+
+ private MouseAdapter doCreateMouseListener() {
+ return new MouseAdapter() {
+ @Override
+ public void mouseDown(MouseEvent e) {
+ if (indexListener != null) {
+ if (e.count == 2) {
+ indexListener.open();
+ } else {
+ indexListener.select();
+ }
+ }
+ }
+ };
+ }
+
+ public boolean isHot() {
+ return hot;
+ }
+
+ public void setHot(boolean hot) {
+ this.hot = hot;
+ }
+
+ protected void registerChild(Control child) {
+ child.addMouseListener(mouseListener);
+ child.addMouseTrackListener(mouseTrackListener);
+
+ }
+
+ /**
+ * Refresh the contents of the receiver.
+ */
+ protected abstract void refresh();
+
+ /**
+ * Set the color base on the index
+ *
+ * @param index
+ */
+ public void updateColors(int index) {
+ currentIndex = index;
+
+ if (selected) {
+ setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
+ setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
+ } else {
+ if (index % 2 == 0) {
+ setBackground(JFaceResources.getColorRegistry().get(DARK_COLOR_KEY));
+ } else {
+ setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ }
+ setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ }
+ }
+
+ @Override
+ public void setForeground(Color color) {
+ super.setForeground(color);
+ Control[] children = getChildren();
+ for (Control child : children) {
+ child.setForeground(color);
+ }
+ }
+
+ @Override
+ public void setBackground(Color color) {
+ super.setBackground(color);
+ Control[] children = getChildren();
+ for (Control child : children) {
+ child.setBackground(color);
+ }
+ }
+
+ /**
+ * Set the selection colors.
+ *
+ * @param select
+ * boolean that indicates whether or not to show selection.
+ */
+ public void setSelected(boolean select) {
+ selected = select;
+ updateColors(currentIndex);
+ }
+
+ /**
+ * Set the listener for index changes.
+ *
+ * @param indexListener
+ */
+ void setIndexListener(IndexListener indexListener) {
+ this.indexListener = indexListener;
+ }
+
+ /**
+ * Return whether or not the receiver is selected.
+ *
+ * @return boolean
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * Set whether or not the receiver is being displayed based on the top and bottom of the currently visible area.
+ *
+ * @param top
+ * @param bottom
+ */
+ void setDisplayed(int top, int bottom) {
+ int itemTop = getLocation().y;
+ int itemBottom = itemTop + getBounds().height;
+ setDisplayed(itemTop <= bottom && itemBottom > top);
+
+ }
+
+ /**
+ * Set whether or not the receiver is being displayed
+ *
+ * @param displayed
+ */
+ private void setDisplayed(boolean displayed) {
+ // See if this element has been turned off
+ boolean refresh = !isShowing && displayed;
+ isShowing = displayed;
+ if (refresh) {
+ refresh();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListViewer.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListViewer.java
new file mode 100644
index 000000000..025740cbb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/ControlListViewer.java
@@ -0,0 +1,511 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * Based on {@link org.eclipse.ui.internal.progress.DetailedProgressViewer}.
+ *
+ * @author Steffen Pingel
+ */
+@SuppressWarnings("restriction")
+public abstract class ControlListViewer extends StructuredViewer {
+
+ Composite control;
+
+ private final ScrolledComposite scrolled;
+
+ private final Composite noEntryArea;
+
+ protected boolean hasFocus;
+
+ /**
+ * Create a new instance of the receiver with a control that is a child of parent with style style.
+ *
+ * @param parent
+ * @param style
+ */
+ public ControlListViewer(Composite parent, int style) {
+ scrolled = new ScrolledComposite(parent, style | SWT.VERTICAL);
+ int height = JFaceResources.getDefaultFont().getFontData()[0].getHeight();
+ scrolled.getVerticalBar().setIncrement(height * 2);
+ scrolled.setExpandHorizontal(true);
+ scrolled.setExpandVertical(true);
+
+ control = new Composite(scrolled, SWT.NONE) {
+ @Override
+ public boolean setFocus() {
+ forceFocus();
+ return true;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (visible) {
+ updateSize(control);
+ }
+ }
+ };
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ control.setLayout(layout);
+ control.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ control.setBackgroundMode(SWT.INHERIT_FORCE);
+ control.addControlListener(new ControlListener() {
+ public void controlMoved(ControlEvent e) {
+ updateVisibleItems();
+ }
+
+ public void controlResized(ControlEvent e) {
+ updateVisibleItems();
+ }
+ });
+
+ scrolled.setContent(control);
+ hookControl(control);
+
+ noEntryArea = new Composite(scrolled, SWT.NONE);
+ doCreateNoEntryArea(noEntryArea);
+
+ scrolled.setExpandHorizontal(true);
+ scrolled.setExpandVertical(true);
+ scrolled.addControlListener(new ControlAdapter() {
+ @Override
+ public void controlResized(ControlEvent e) {
+ updateSize(scrolled.getContent());
+ }
+ });
+ control.addTraverseListener(new TraverseListener() {
+ private boolean handleEvent = true;
+
+ public void keyTraversed(TraverseEvent event) {
+ if (!handleEvent) {
+ return;
+ }
+ switch (event.detail) {
+ case SWT.TRAVERSE_ARROW_PREVIOUS: {
+ Control[] children = control.getChildren();
+ if (children.length > 0) {
+ boolean selected = false;
+ for (int i = 0; i < children.length; i++) {
+ ControlListItem item = (ControlListItem) children[i];
+ if (item.isSelected()) {
+ selected = true;
+ if (i > 0) {
+ setSelection(new StructuredSelection(children[i - 1].getData()), true);
+ }
+ break;
+ }
+ }
+ if (!selected) {
+ setSelection(new StructuredSelection(children[children.length - 1].getData()), true);
+ }
+ }
+ break;
+ }
+ case SWT.TRAVERSE_ARROW_NEXT: {
+ Control[] children = control.getChildren();
+ if (children.length > 0) {
+ boolean selected = false;
+ for (int i = 0; i < children.length; i++) {
+ ControlListItem item = (ControlListItem) children[i];
+ if (item.isSelected()) {
+ selected = true;
+ if (i < children.length - 1) {
+ setSelection(new StructuredSelection(children[i + 1].getData()), true);
+ }
+ break;
+ }
+ }
+ if (!selected) {
+ setSelection(new StructuredSelection(children[0].getData()), true);
+ }
+ }
+ break;
+ }
+ default:
+ handleEvent = false;
+ event.doit = true;
+ Control control = ControlListViewer.this.control;
+ Shell shell = control.getShell();
+ while (control != null) {
+ if (control.traverse(event.detail)) {
+ break;
+ }
+ if (!event.doit || control == shell) {
+ break;
+ }
+ control = control.getParent();
+ }
+ handleEvent = true;
+ break;
+ }
+ }
+ });
+ }
+
+ protected void doCreateNoEntryArea(Composite parent) {
+ }
+
+ public void add(Object[] elements) {
+ ViewerComparator sorter = getComparator();
+
+ // Use a Set in case we are getting something added that exists
+ Set<Object> newItems = new HashSet<Object>(elements.length);
+
+ Control[] existingChildren = control.getChildren();
+ for (Control element : existingChildren) {
+ if (element.getData() != null) {
+ newItems.add(element.getData());
+ }
+ }
+
+ for (Object element : elements) {
+ if (element != null) {
+ newItems.add(element);
+ }
+ }
+
+ Object[] infos = new Object[newItems.size()];
+ newItems.toArray(infos);
+
+ if (sorter != null) {
+ sorter.sort(this, infos);
+ }
+
+ // Update with the new elements to prevent flash
+ for (Control element : existingChildren) {
+ ((ControlListItem) element).dispose();
+ }
+
+ for (int i = 0; i < infos.length; i++) {
+ ControlListItem item = createNewItem(infos[i]);
+ item.updateColors(i);
+ }
+
+ control.layout(true);
+ doUpdateContent();
+ }
+
+ private void updateSize(Control control) {
+ if (control == null) {
+ return;
+ }
+ // XXX need a small offset in case the list has a scroll bar
+ Point size = control.computeSize(scrolled.getClientArea().width - 20, SWT.DEFAULT, true);
+ control.setSize(size);
+ scrolled.setMinSize(size);
+ }
+
+ protected void doUpdateContent() {
+ if (control.getChildren().length > 0) {
+ updateSize(control);
+ scrolled.setContent(control);
+ } else {
+ updateSize(noEntryArea);
+ scrolled.setContent(noEntryArea);
+ }
+ }
+
+ /**
+ * Create a new item for info.
+ *
+ * @param element
+ * @return ControlListItem
+ */
+ private ControlListItem createNewItem(Object element) {
+ final ControlListItem item = doCreateItem(control, element);
+// item.getChildren()[0].addPaintListener(new PaintListener() {
+// public void paintControl(PaintEvent e) {
+// if (hasFocus && item.isSelected()) {
+// Point size = item.getSize();
+// e.gc.setForeground(e.gc.getDevice().getSystemColor(SWT.COLOR_DARK_GRAY));
+// e.gc.setLineDash(new int[] { 1, 2 });
+// e.gc.drawRoundRectangle(0, 0, size.x - 1, size.y - 1, 5, 5);
+// }
+// }
+// });
+ item.setIndexListener(new ControlListItem.IndexListener() {
+ public void selectNext() {
+ Control[] children = control.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ if (item == children[i]) {
+ if (i < children.length - 1) {
+ setSelection(new StructuredSelection(children[i + 1].getData()));
+ }
+ break;
+ }
+ }
+ }
+
+ public void selectPrevious() {
+ Control[] children = control.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ if (item == children[i]) {
+ if (i > 0) {
+ setSelection(new StructuredSelection(children[i - 1].getData()));
+ }
+ break;
+ }
+ }
+ }
+
+ public void select() {
+ setSelection(new StructuredSelection(item.getData()));
+ setFocus();
+ }
+
+ public void open() {
+ handleOpen();
+ }
+ });
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(item);
+ // Refresh to populate with the current tasks
+ item.refresh();
+ return item;
+ }
+
+ protected abstract ControlListItem doCreateItem(Composite parent, Object element);
+
+ @Override
+ protected ControlListItem doFindInputItem(Object element) {
+ return null;
+ }
+
+ @Override
+ protected ControlListItem doFindItem(Object element) {
+ Control[] children = control.getChildren();
+ for (Control child : children) {
+ if (child.isDisposed() || child.getData() == null) {
+ continue;
+ }
+ if (child.getData().equals(element)) {
+ return (ControlListItem) child;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void doUpdateItem(Widget item, Object element, boolean fullMap) {
+ if (usingElementMap()) {
+ unmapElement(item);
+ }
+ item.dispose();
+ add(new Object[] { element });
+ }
+
+ @Override
+ public ScrolledComposite getControl() {
+ return scrolled;
+ }
+
+ @Override
+ protected List<?> getSelectionFromWidget() {
+ Control[] children = control.getChildren();
+ ArrayList<Object> selection = new ArrayList<Object>(children.length);
+ for (Control child : children) {
+ ControlListItem item = (ControlListItem) child;
+ if (item.isSelected() && item.getData() != null) {
+ selection.add(item.getData());
+ }
+ }
+ return selection;
+ }
+
+ protected void handleOpen() {
+ Control control = getControl();
+ if (control != null && !control.isDisposed()) {
+ ISelection selection = getSelection();
+ fireOpen(new OpenEvent(this, selection));
+ }
+ }
+
+ @Override
+ protected void inputChanged(Object input, Object oldInput) {
+ super.inputChanged(input, oldInput);
+ refreshAll();
+ doUpdateContent();
+ }
+
+ @Override
+ protected void internalRefresh(Object element) {
+ if (element == null) {
+ return;
+ }
+
+ if (element.equals(getRoot())) {
+ refreshAll();
+ return;
+ }
+ Widget widget = findItem(element);
+ if (widget == null) {
+ add(new Object[] { element });
+ return;
+ }
+ ((ControlListItem) widget).refresh();
+
+ updateSize(control);
+ }
+
+ public void remove(Object[] elements) {
+ for (Object element : elements) {
+ Widget item = doFindItem(element);
+ if (item != null) {
+ unmapElement(element);
+ item.dispose();
+ }
+ }
+
+ Control[] existingChildren = control.getChildren();
+ for (int i = 0; i < existingChildren.length; i++) {
+ ControlListItem item = (ControlListItem) existingChildren[i];
+ item.updateColors(i);
+ }
+ control.layout(true);
+ doUpdateContent();
+ }
+
+ @Override
+ public void reveal(Object element) {
+ Control control = doFindItem(element);
+ if (control != null) {
+ revealControl(control);
+ }
+ }
+
+ private void revealControl(Control control) {
+ Rectangle clientArea = scrolled.getClientArea();
+ Point origin = scrolled.getOrigin();
+ Point location = control.getLocation();
+ Point size = control.getSize();
+ if (location.y + size.y > origin.y + clientArea.height) {
+ scrolled.setOrigin(origin.x, location.y + size.y - clientArea.height);
+ }
+ if (location.y < origin.y) {
+ scrolled.setOrigin(origin.x, location.y);
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ protected void setSelectionToWidget(List list, boolean reveal) {
+ if (list != null) {
+ HashSet<Object> elements = new HashSet<Object>(list);
+ Control[] children = control.getChildren();
+ for (Control control : children) {
+ ControlListItem child = (ControlListItem) control;
+ boolean selected = elements.contains(child.getData());
+ if (selected != child.isSelected()) {
+ child.setSelected(selected);
+ }
+ if (reveal && selected) {
+ revealControl(child);
+ reveal = false;
+ }
+ }
+ } else {
+ Control[] children = control.getChildren();
+ for (Control control : children) {
+ ControlListItem child = (ControlListItem) control;
+ if (child.isSelected()) {
+ child.setSelected(false);
+ }
+ }
+ }
+ }
+
+ /**
+ * Set focus on the current selection.
+ */
+ public void setFocus() {
+ Control[] children = control.getChildren();
+ if (children.length > 0) {
+ // causes the item's tool bar to get focus when clicked which is undesirable
+// for (Control element : children) {
+// ControlListItem item = (ControlListItem) element;
+// if (item.isSelected()) {
+// if (item.setFocus()) {
+// return;
+// }
+// }
+// }
+ control.forceFocus();
+ } else {
+ noEntryArea.setFocus();
+ }
+ }
+
+ /**
+ * Refresh everything as the root is being refreshed.
+ */
+ private void refreshAll() {
+ Object[] infos = getSortedChildren(getRoot());
+ Control[] existingChildren = control.getChildren();
+
+ for (Control element : existingChildren) {
+ element.dispose();
+ }
+
+ for (int i = 0; i < infos.length; i++) {
+ ControlListItem item = createNewItem(infos[i]);
+ item.updateColors(i);
+ }
+
+ control.layout(true);
+ doUpdateContent();
+ }
+
+ /**
+ * Set the virtual items to be visible or not depending on the displayed area.
+ */
+ private void updateVisibleItems() {
+ Control[] children = control.getChildren();
+ int top = scrolled.getOrigin().y;
+ int bottom = top + scrolled.getParent().getBounds().height;
+ for (Control element : children) {
+ ControlListItem item = (ControlListItem) element;
+ item.setDisplayed(top, bottom);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/FilteredViewer.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/FilteredViewer.java
new file mode 100644
index 000000000..3b764b310
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/FilteredViewer.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Jacek Pospychala - bug 187762
+ * Mohamed Tarief - tarief@eg.ibm.com - IBM - Bug 174481
+ * Tasktop Technologies - generalized filter code for structured viewers
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryImages;
+import org.eclipse.equinox.internal.p2.ui.discovery.wizards.Messages;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.ACC;
+import org.eclipse.swt.accessibility.AccessibleAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlAdapter;
+import org.eclipse.swt.accessibility.AccessibleControlEvent;
+import org.eclipse.swt.accessibility.AccessibleEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.progress.WorkbenchJob;
+
+/**
+ * Based on {@link org.eclipse.ui.dialogs.FilteredTree}.
+ *
+ * @author Steffen Pingel
+ */
+public abstract class FilteredViewer {
+
+ private static Boolean useNativeSearchField;
+
+ private static boolean useNativeSearchField(Composite composite) {
+ if (useNativeSearchField == null) {
+ useNativeSearchField = Boolean.FALSE;
+ Text testText = null;
+ try {
+ testText = new Text(composite, SWT.SEARCH | SWT.ICON_CANCEL);
+ useNativeSearchField = new Boolean((testText.getStyle() & SWT.ICON_CANCEL) != 0);
+ } finally {
+ if (testText != null) {
+ testText.dispose();
+ }
+ }
+
+ }
+ return useNativeSearchField;
+ }
+
+ private Label clearFilterTextControl;
+
+ private Composite container;
+
+ private Text filterText;
+
+ private int minimumHeight;
+
+ private String previousFilterText = ""; //$NON-NLS-1$
+
+ private WorkbenchJob refreshJob;
+
+ private PatternFilter searchFilter;
+
+ protected StructuredViewer viewer;
+
+ public FilteredViewer() {
+ }
+
+ private void clearFilterText() {
+ filterText.setText(""); //$NON-NLS-1$
+ filterTextChanged();
+ }
+
+ private Label createClearFilterTextControl(Composite filterContainer, final Text filterText) {
+ final Image inactiveImage = DiscoveryImages.FIND_CLEAR_DISABLED.createImage();
+ final Image activeImage = DiscoveryImages.FIND_CLEAR.createImage();
+ final Image pressedImage = new Image(filterContainer.getDisplay(), activeImage, SWT.IMAGE_GRAY);
+
+ final Label clearButton = new Label(filterContainer, SWT.NONE);
+ clearButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+ clearButton.setImage(inactiveImage);
+ clearButton.setToolTipText(Messages.ConnectorDiscoveryWizardMainPage_clearButton_toolTip);
+ clearButton.setBackground(filterContainer.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ clearButton.addMouseListener(new MouseAdapter() {
+ private MouseMoveListener fMoveListener;
+
+ private boolean isMouseInButton(MouseEvent e) {
+ Point buttonSize = clearButton.getSize();
+ return 0 <= e.x && e.x < buttonSize.x && 0 <= e.y && e.y < buttonSize.y;
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ clearButton.setImage(pressedImage);
+ fMoveListener = new MouseMoveListener() {
+ private boolean fMouseInButton = true;
+
+ public void mouseMove(MouseEvent e) {
+ boolean mouseInButton = isMouseInButton(e);
+ if (mouseInButton != fMouseInButton) {
+ fMouseInButton = mouseInButton;
+ clearButton.setImage(mouseInButton ? pressedImage : inactiveImage);
+ }
+ }
+ };
+ clearButton.addMouseMoveListener(fMoveListener);
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ if (fMoveListener != null) {
+ clearButton.removeMouseMoveListener(fMoveListener);
+ fMoveListener = null;
+ boolean mouseInButton = isMouseInButton(e);
+ clearButton.setImage(mouseInButton ? activeImage : inactiveImage);
+ if (mouseInButton) {
+ clearFilterText();
+ filterText.setFocus();
+ }
+ }
+ }
+ });
+ clearButton.addMouseTrackListener(new MouseTrackListener() {
+ public void mouseEnter(MouseEvent e) {
+ clearButton.setImage(activeImage);
+ }
+
+ public void mouseExit(MouseEvent e) {
+ clearButton.setImage(inactiveImage);
+ }
+
+ public void mouseHover(MouseEvent e) {
+ }
+ });
+ clearButton.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ inactiveImage.dispose();
+ activeImage.dispose();
+ pressedImage.dispose();
+ }
+ });
+ clearButton.getAccessible().addAccessibleListener(new AccessibleAdapter() {
+ @Override
+ public void getName(AccessibleEvent e) {
+ e.result = Messages.ConnectorDiscoveryWizardMainPage_clearButton_accessibleListener;
+ }
+ });
+ clearButton.getAccessible().addAccessibleControlListener(new AccessibleControlAdapter() {
+ @Override
+ public void getRole(AccessibleControlEvent e) {
+ e.detail = ACC.ROLE_PUSHBUTTON;
+ }
+ });
+ return clearButton;
+ }
+
+ public void createControl(Composite parent) {
+ container = new Composite(parent, SWT.NONE);
+ GridLayoutFactory.fillDefaults().margins(0, 0).applyTo(container);
+ container.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ if (refreshJob != null) {
+ refreshJob.cancel();
+ }
+ }
+ });
+
+ doCreateHeader();
+
+ viewer = doCreateViewer(container);
+ searchFilter = doCreateFilter();
+ viewer.addFilter(searchFilter);
+ GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, minimumHeight).applyTo(viewer.getControl());
+ }
+
+ protected PatternFilter doCreateFilter() {
+ return new PatternFilter() {
+ @Override
+ protected boolean isParentMatch(Viewer viewer, Object element) {
+ return false;
+ }
+ };
+ }
+
+ private void doCreateHeader() {
+ Composite header = new Composite(container, SWT.NONE);
+ GridLayoutFactory.fillDefaults().applyTo(header);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(header);
+
+ doCreateFindControl(header);
+ doCreateHeaderControls(header);
+
+ // arrange all header controls horizontally
+ GridLayoutFactory.fillDefaults().numColumns(header.getChildren().length).applyTo(header);
+ }
+
+ protected void doCreateHeaderControls(Composite header) {
+ // ignore
+ }
+
+ protected WorkbenchJob doCreateRefreshJob() {
+ return new WorkbenchJob("filter") { //$NON-NLS-1$
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ if (filterText.isDisposed()) {
+ return Status.CANCEL_STATUS;
+ }
+ String text = filterText.getText();
+ text = text.trim();
+
+ if (!previousFilterText.equals(text)) {
+ previousFilterText = text;
+ doFind(text);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ }
+
+ private void doCreateFindControl(Composite header) {
+ Label label = new Label(header, SWT.NONE);
+ label.setText(Messages.ConnectorDiscoveryWizardMainPage_filterLabel);
+
+ Composite textFilterContainer;
+ boolean nativeSearch = useNativeSearchField(header);
+ if (nativeSearch) {
+ textFilterContainer = new Composite(header, SWT.NONE);
+ } else {
+ textFilterContainer = new Composite(header, SWT.BORDER);
+ textFilterContainer.setBackground(header.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+ }
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(textFilterContainer);
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(textFilterContainer);
+
+ if (nativeSearch) {
+ filterText = new Text(textFilterContainer, SWT.SINGLE | SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL);
+ } else {
+ filterText = new Text(textFilterContainer, SWT.SINGLE);
+ }
+
+ filterText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ filterTextChanged();
+ }
+ });
+ if (nativeSearch) {
+ filterText.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ if (e.detail == SWT.ICON_CANCEL) {
+ clearFilterText();
+ }
+ }
+ });
+ GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(filterText);
+ } else {
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(filterText);
+ clearFilterTextControl = createClearFilterTextControl(textFilterContainer, filterText);
+ clearFilterTextControl.setVisible(false);
+ }
+ }
+
+ protected abstract StructuredViewer doCreateViewer(Composite container);
+
+ protected void doFind(String text) {
+ searchFilter.setPattern(text);
+ if (clearFilterTextControl != null) {
+ clearFilterTextControl.setVisible(text != null && text.length() != 0);
+ }
+ viewer.refresh(true);
+ }
+
+ private void filterTextChanged() {
+ if (refreshJob == null) {
+ refreshJob = doCreateRefreshJob();
+ } else {
+ refreshJob.cancel();
+ }
+ refreshJob.schedule(200L);
+ }
+
+ public Control getControl() {
+ return container;
+ }
+
+ public int getMinimumHeight() {
+ return minimumHeight;
+ }
+
+ public StructuredViewer getViewer() {
+ return viewer;
+ }
+
+ public void setMinimumHeight(int minimumHeight) {
+ this.minimumHeight = minimumHeight;
+ if (viewer != null) {
+ GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, minimumHeight).applyTo(
+ viewer.getControl());
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientCanvas.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientCanvas.java
new file mode 100644
index 000000000..2f06f33e7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientCanvas.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Tasktop Technologies - extracted FormHeading implementation for Mylyn
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * Based on {@link org.eclipse.ui.internal.forms.widgets.FormHeading}.
+ */
+public class GradientCanvas extends Canvas {
+
+ private static final int SEPARATOR = 1 << 1;
+
+ private static final int BOTTOM_SEPARATOR = 1 << 2;
+
+ private static final int BACKGROUND_IMAGE_TILED = 1 << 3;
+
+ public static final String COLOR_BASE_BG = "baseBg"; //$NON-NLS-1$
+
+ static String PREFIX = "org.eclipse.ui.forms."; //$NON-NLS-1$
+
+ static String H_PREFIX = PREFIX + "H_"; //$NON-NLS-1$
+
+ public static String H_BOTTOM_KEYLINE1 = H_PREFIX + "BOTTOM_KEYLINE1"; //$NON-NLS-1$
+
+ /**
+ * Key for the form header bottom keyline 2 color.
+ */
+ public static String H_BOTTOM_KEYLINE2 = H_PREFIX + "BOTTOM_KEYLINE2"; //$NON-NLS-1$
+
+ private Image backgroundImage;
+
+ private Image gradientImage;
+
+ Map<String, Color> colors = new Hashtable<String, Color>();
+
+ private int flags;
+
+ private GradientInfo gradientInfo;
+
+ private class GradientInfo {
+ Color[] gradientColors;
+
+ int[] percents;
+
+ boolean vertical;
+ }
+
+ @Override
+ public boolean forceFocus() {
+ return false;
+ }
+
+ /**
+ * Creates the form content control as a child of the provided parent.
+ *
+ * @param parent
+ * the parent widget
+ */
+ public GradientCanvas(Composite parent, int style) {
+ super(parent, style);
+ setBackgroundMode(SWT.INHERIT_DEFAULT);
+ setSeparatorAlignment(SWT.BOTTOM);
+ addListener(SWT.Paint, new Listener() {
+ public void handleEvent(Event e) {
+ onPaint(e.gc);
+ }
+ });
+ addListener(SWT.Dispose, new Listener() {
+ public void handleEvent(Event e) {
+ if (gradientImage != null) {
+ // TODO e3.4 FormImages.getInstance().markFinished(gradientImage);
+ gradientImage.dispose();
+ gradientImage = null;
+ }
+ }
+ });
+ addListener(SWT.Resize, new Listener() {
+ public void handleEvent(Event e) {
+ if (gradientInfo != null || (backgroundImage != null && !isBackgroundImageTiled())) {
+ updateGradientImage();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void setBackground(Color bg) {
+ super.setBackground(bg);
+ internalSetBackground(bg);
+ }
+
+ private void internalSetBackground(Color bg) {
+ putColor(COLOR_BASE_BG, bg);
+ }
+
+ public void setBackgroundGradient(Color[] gradientColors, int[] percents, boolean vertical) {
+ if (gradientColors != null) {
+ gradientInfo = new GradientInfo();
+ gradientInfo.gradientColors = gradientColors;
+ gradientInfo.percents = percents;
+ gradientInfo.vertical = vertical;
+ setBackground(null);
+ updateGradientImage();
+ } else {
+ // reset
+ gradientInfo = null;
+ if (gradientImage != null) {
+ // TODO e3.4 FormImages.getInstance().markFinished(gradientImage);
+ gradientImage.dispose();
+ gradientImage = null;
+ setBackgroundImage(null);
+ }
+ }
+ }
+
+ public void setHeadingBackgroundImage(Image image) {
+ this.backgroundImage = image;
+ if (image != null) {
+ setBackground(null);
+ }
+ if (isBackgroundImageTiled()) {
+ setBackgroundImage(image);
+ } else {
+ updateGradientImage();
+ }
+ }
+
+ public Image getHeadingBackgroundImage() {
+ return backgroundImage;
+ }
+
+ public void setBackgroundImageTiled(boolean tiled) {
+ if (tiled) {
+ flags |= BACKGROUND_IMAGE_TILED;
+ } else {
+ flags &= ~BACKGROUND_IMAGE_TILED;
+ }
+ setHeadingBackgroundImage(this.backgroundImage);
+ }
+
+ public boolean isBackgroundImageTiled() {
+ return (flags & BACKGROUND_IMAGE_TILED) != 0;
+ }
+
+ @Override
+ public void setBackgroundImage(Image image) {
+ super.setBackgroundImage(image);
+ if (image != null) {
+ internalSetBackground(null);
+ }
+ }
+
+ private void onPaint(GC gc) {
+ if (!isSeparatorVisible() && getBackgroundImage() == null) {
+ return;
+ }
+ Rectangle carea = getClientArea();
+ Image buffer = new Image(getDisplay(), carea.width, carea.height);
+ buffer.setBackground(getBackground());
+ GC igc = new GC(buffer);
+ igc.setBackground(getBackground());
+ igc.fillRectangle(0, 0, carea.width, carea.height);
+ if (getBackgroundImage() != null) {
+ if (gradientInfo != null) {
+ drawBackground(igc, carea.x, carea.y, carea.width, carea.height);
+ } else {
+ Image bgImage = getBackgroundImage();
+ Rectangle ibounds = bgImage.getBounds();
+ drawBackground(igc, carea.x, carea.y, ibounds.width, ibounds.height);
+ }
+ }
+
+ if (isSeparatorVisible()) {
+ drawSeparator(carea, igc);
+ }
+ igc.dispose();
+ gc.drawImage(buffer, carea.x, carea.y);
+ buffer.dispose();
+ }
+
+ private void drawSeparator(Rectangle carea, GC igc) {
+ // bg separator
+ if (hasColor(H_BOTTOM_KEYLINE1)) {
+ igc.setForeground(getColor(H_BOTTOM_KEYLINE1));
+ } else {
+ igc.setForeground(getBackground());
+ }
+ if (getSeparatorAlignment() == SWT.BOTTOM) {
+ igc.drawLine(carea.x, carea.height - 2, carea.x + carea.width - 1, carea.height - 2);
+ } else {
+ igc.drawLine(carea.x, 1, carea.x + carea.width - 1, 1);
+ }
+ if (hasColor(H_BOTTOM_KEYLINE2)) {
+ igc.setForeground(getColor(H_BOTTOM_KEYLINE2));
+ } else {
+ igc.setForeground(getForeground());
+ }
+ if (getSeparatorAlignment() == SWT.BOTTOM) {
+ igc.drawLine(carea.x, carea.height - 1, carea.x + carea.width - 1, carea.height - 1);
+ } else {
+ igc.drawLine(carea.x, 0, carea.x + carea.width - 1, 0);
+ }
+ }
+
+ private void updateGradientImage() {
+ Rectangle rect = getBounds();
+ if (gradientImage != null) {
+ // TODO e3.4 FormImages.getInstance().markFinished(gradientImage);
+ gradientImage.dispose();
+ gradientImage = null;
+ }
+ if (gradientInfo != null) {
+ // TODO e3.4 use FormImages
+// gradientImage = FormImages.getInstance().getGradient(gradientInfo.gradientColors, gradientInfo.percents,
+// gradientInfo.vertical ? rect.height : rect.width, gradientInfo.vertical, getColor(COLOR_BASE_BG));
+ boolean vertical = gradientInfo.vertical;
+ int width = vertical ? 1 : rect.width;
+ int height = vertical ? rect.height : 1;
+ gradientImage = new Image(getDisplay(), Math.max(width, 1), Math.max(height, 1));
+ GC gc = new GC(gradientImage);
+ drawTextGradient(gc, width, height);
+ gc.dispose();
+ } else if (backgroundImage != null && !isBackgroundImageTiled()) {
+ gradientImage = new Image(getDisplay(), Math.max(rect.width, 1), Math.max(rect.height, 1));
+ gradientImage.setBackground(getBackground());
+ GC gc = new GC(gradientImage);
+ gc.drawImage(backgroundImage, 0, 0);
+ gc.dispose();
+ }
+ setBackgroundImage(gradientImage);
+ }
+
+ private void drawTextGradient(GC gc, int width, int height) {
+ final Color oldBackground = gc.getBackground();
+ if (gradientInfo.gradientColors.length == 1) {
+ if (gradientInfo.gradientColors[0] != null) {
+ gc.setBackground(gradientInfo.gradientColors[0]);
+ }
+ gc.fillRectangle(0, 0, width, height);
+ } else {
+ final Color oldForeground = gc.getForeground();
+ Color lastColor = gradientInfo.gradientColors[0];
+ if (lastColor == null) {
+ lastColor = oldBackground;
+ }
+ int pos = 0;
+ for (int i = 0; i < gradientInfo.percents.length; ++i) {
+ gc.setForeground(lastColor);
+ lastColor = gradientInfo.gradientColors[i + 1];
+ if (lastColor == null) {
+ lastColor = oldBackground;
+ }
+ gc.setBackground(lastColor);
+ if (gradientInfo.vertical) {
+ final int gradientHeight = (gradientInfo.percents[i] * height / 100) - pos;
+ gc.fillGradientRectangle(0, pos, width, gradientHeight, true);
+ pos += gradientHeight;
+ } else {
+ final int gradientWidth = (gradientInfo.percents[i] * width / 100) - pos;
+ gc.fillGradientRectangle(pos, 0, gradientWidth, height, false);
+ pos += gradientWidth;
+ }
+ }
+ if (gradientInfo.vertical && pos < height) {
+ gc.setBackground(getColor(COLOR_BASE_BG));
+ gc.fillRectangle(0, pos, width, height - pos);
+ }
+ if (!gradientInfo.vertical && pos < width) {
+ gc.setBackground(getColor(COLOR_BASE_BG));
+ gc.fillRectangle(pos, 0, width - pos, height);
+ }
+
+ if (isSeparatorVisible()) {
+ drawSeparator(getClientArea(), gc);
+ }
+ gc.setForeground(oldForeground);
+ }
+ }
+
+ public boolean isSeparatorVisible() {
+ return (flags & SEPARATOR) != 0;
+ }
+
+ public void setSeparatorVisible(boolean addSeparator) {
+ if (addSeparator) {
+ flags |= SEPARATOR;
+ } else {
+ flags &= ~SEPARATOR;
+ }
+ }
+
+ public void setSeparatorAlignment(int alignment) {
+ if (alignment == SWT.BOTTOM) {
+ flags |= BOTTOM_SEPARATOR;
+ } else {
+ flags &= ~BOTTOM_SEPARATOR;
+ }
+ }
+
+ public int getSeparatorAlignment() {
+ return (flags & BOTTOM_SEPARATOR) != 0 ? SWT.BOTTOM : SWT.TOP;
+ }
+
+ public void putColor(String key, Color color) {
+ if (color == null) {
+ colors.remove(key);
+ } else {
+ colors.put(key, color);
+ }
+ }
+
+ public Color getColor(String key) {
+ return colors.get(key);
+ }
+
+ public boolean hasColor(String key) {
+ return colors.containsKey(key);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientToolTip.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientToolTip.java
new file mode 100644
index 000000000..db3025698
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/GradientToolTip.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * A custom {@link ToolTip} that applies a gradient to the contents.
+ *
+ * @author Shawn Minto
+ */
+public abstract class GradientToolTip extends ToolTip {
+
+ private CommonColors colors;
+
+ public GradientToolTip(Control control, int style, boolean manualActivation) {
+ super(control, style, manualActivation);
+ initResources(control);
+ }
+
+ public GradientToolTip(Control control) {
+ super(control);
+ initResources(control);
+ }
+
+ private void initResources(Control control) {
+ colors = DiscoveryUi.getCommonsColors();
+ }
+
+ @Override
+ protected final Composite createToolTipContentArea(Event event, final Composite parent) {
+ GradientCanvas gradient = new GradientCanvas(parent, SWT.NONE);
+ gradient.setSeparatorVisible(false);
+ GridLayout headLayout = new GridLayout();
+ headLayout.marginHeight = 0;
+ headLayout.marginWidth = 0;
+ headLayout.horizontalSpacing = 0;
+ headLayout.verticalSpacing = 0;
+ headLayout.numColumns = 1;
+ gradient.setLayout(headLayout);
+
+ gradient.setBackgroundGradient(new Color[] { colors.getGradientBegin(), colors.getGradientEnd() },
+ new int[] { 100 }, true);
+
+ createToolTipArea(event, gradient);
+
+ // force a null background so that the gradient shines through
+ for (Control c : gradient.getChildren()) {
+ setNullBackground(c);
+ }
+
+ return gradient;
+ }
+
+ private void setNullBackground(final Control outerCircle) {
+ outerCircle.setBackground(null);
+ if (outerCircle instanceof Composite) {
+ ((Composite) outerCircle).setBackgroundMode(SWT.INHERIT_FORCE);
+ for (Control c : ((Composite) outerCircle).getChildren()) {
+ setNullBackground(c);
+ }
+ }
+ }
+
+ protected abstract Composite createToolTipArea(Event event, Composite parent);
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/Messages.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/Messages.java
new file mode 100644
index 000000000..94b357499
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/Messages.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.ui.discovery.util.messages"; //$NON-NLS-1$
+
+ static {
+ // load message values from bundle file
+ reloadMessages();
+ }
+
+ public static void reloadMessages() {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ public static String WorkbenchUtil_Browser_Initialization_Failed;
+
+ public static String WorkbenchUtil_Invalid_URL_Error;
+
+ public static String WorkbenchUtil_No_URL_Error;
+
+ public static String WorkbenchUtil_Open_Location_Title;
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/PatternFilter.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/PatternFilter.java
new file mode 100644
index 000000000..dd03e464f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/PatternFilter.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Tasktop Technologies - generalization for structured viewers
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.ui.internal.misc.StringMatcher;
+
+import com.ibm.icu.text.BreakIterator;
+
+/**
+ * A filter used in conjunction with <code>FilteredTree</code>. In order to determine if a node should be filtered it
+ * uses the content and label provider of the tree to do pattern matching on its children. This causes the entire tree
+ * structure to be realized. Note that the label provider must implement ILabelProvider.
+ *
+ * @see org.eclipse.ui.dialogs.FilteredTree
+ * @since 3.2
+ */
+public class PatternFilter extends ViewerFilter {
+ /*
+ * Cache of filtered elements in the tree
+ */
+ private final Map cache = new HashMap();
+
+ /*
+ * Maps parent elements to TRUE or FALSE
+ */
+ private final Map foundAnyCache = new HashMap();
+
+ private boolean useCache = false;
+
+ /**
+ * Whether to include a leading wildcard for all provided patterns. A trailing wildcard is always included.
+ */
+ private boolean includeLeadingWildcard = false;
+
+ /**
+ * The string pattern matcher used for this pattern filter.
+ */
+ private StringMatcher matcher;
+
+ private boolean useEarlyReturnIfMatcherIsNull = true;
+
+ private static Object[] EMPTY = new Object[0];
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#filter(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object[])
+ */
+ @Override
+ public final Object[] filter(Viewer viewer, Object parent, Object[] elements) {
+ // we don't want to optimize if we've extended the filter ... this
+ // needs to be addressed in 3.4
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404
+ if (matcher == null && useEarlyReturnIfMatcherIsNull) {
+ return elements;
+ }
+
+ if (!useCache) {
+ return super.filter(viewer, parent, elements);
+ }
+
+ Object[] filtered = (Object[]) cache.get(parent);
+ if (filtered == null) {
+ Boolean foundAny = (Boolean) foundAnyCache.get(parent);
+ if (foundAny != null && !foundAny.booleanValue()) {
+ filtered = EMPTY;
+ } else {
+ filtered = super.filter(viewer, parent, elements);
+ }
+ cache.put(parent, filtered);
+ }
+ return filtered;
+ }
+
+ /**
+ * Returns true if any of the elements makes it through the filter. This method uses caching if enabled; the
+ * computation is done in computeAnyVisible.
+ *
+ * @param viewer
+ * @param parent
+ * @param elements
+ * the elements (must not be an empty array)
+ * @return true if any of the elements makes it through the filter.
+ */
+ private boolean isAnyVisible(Viewer viewer, Object parent, Object[] elements) {
+ if (matcher == null) {
+ return true;
+ }
+
+ if (!useCache) {
+ return computeAnyVisible(viewer, elements);
+ }
+
+ Object[] filtered = (Object[]) cache.get(parent);
+ if (filtered != null) {
+ return filtered.length > 0;
+ }
+ Boolean foundAny = (Boolean) foundAnyCache.get(parent);
+ if (foundAny == null) {
+ foundAny = computeAnyVisible(viewer, elements) ? Boolean.TRUE : Boolean.FALSE;
+ foundAnyCache.put(parent, foundAny);
+ }
+ return foundAny.booleanValue();
+ }
+
+ /**
+ * Returns true if any of the elements makes it through the filter.
+ *
+ * @param viewer
+ * the viewer
+ * @param elements
+ * the elements to test
+ * @return <code>true</code> if any of the elements makes it through the filter
+ */
+ private boolean computeAnyVisible(Viewer viewer, Object[] elements) {
+ boolean elementFound = false;
+ for (int i = 0; i < elements.length && !elementFound; i++) {
+ Object element = elements[i];
+ elementFound = isElementVisible(viewer, element);
+ }
+ return elementFound;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public final boolean select(Viewer viewer, Object parentElement, Object element) {
+ return isElementVisible(viewer, element);
+ }
+
+ /**
+ * Sets whether a leading wildcard should be attached to each pattern string.
+ *
+ * @param includeLeadingWildcard
+ * Whether a leading wildcard should be added.
+ */
+ public final void setIncludeLeadingWildcard(final boolean includeLeadingWildcard) {
+ this.includeLeadingWildcard = includeLeadingWildcard;
+ }
+
+ /**
+ * The pattern string for which this filter should select elements in the viewer.
+ *
+ * @param patternString
+ */
+ public void setPattern(String patternString) {
+ // these 2 strings allow the PatternFilter to be extended in
+ // 3.3 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=186404
+ if ("org.eclipse.ui.keys.optimization.true".equals(patternString)) { //$NON-NLS-1$
+ useEarlyReturnIfMatcherIsNull = true;
+ return;
+ } else if ("org.eclipse.ui.keys.optimization.false".equals(patternString)) { //$NON-NLS-1$
+ useEarlyReturnIfMatcherIsNull = false;
+ return;
+ }
+ clearCaches();
+ if (patternString == null || patternString.equals("")) { //$NON-NLS-1$
+ matcher = null;
+ } else {
+ String pattern = patternString + "*"; //$NON-NLS-1$
+ if (includeLeadingWildcard) {
+ pattern = "*" + pattern; //$NON-NLS-1$
+ }
+ matcher = new StringMatcher(pattern, true, false);
+ }
+ }
+
+ /**
+ * Clears the caches used for optimizing this filter. Needs to be called whenever the tree content changes.
+ */
+ /* package */void clearCaches() {
+ cache.clear();
+ foundAnyCache.clear();
+ }
+
+ /**
+ * Answers whether the given String matches the pattern.
+ *
+ * @param string
+ * the String to test
+ * @return whether the string matches the pattern
+ */
+ private boolean match(String string) {
+ if (matcher == null) {
+ return true;
+ }
+ return matcher.match(string);
+ }
+
+ /**
+ * Answers whether the given element is a valid selection in the filtered tree. For example, if a tree has items
+ * that are categorized, the category itself may not be a valid selection since it is used merely to organize the
+ * elements.
+ *
+ * @param element
+ * @return true if this element is eligible for automatic selection
+ */
+ public boolean isElementSelectable(Object element) {
+ return element != null;
+ }
+
+ /**
+ * Answers whether the given element in the given viewer matches the filter pattern. This is a default
+ * implementation that will show a leaf element in the tree based on whether the provided filter text matches the
+ * text of the given element's text, or that of it's children (if the element has any). Subclasses may override this
+ * method.
+ *
+ * @param viewer
+ * the tree viewer in which the element resides
+ * @param element
+ * the element in the tree to check for a match
+ * @return true if the element matches the filter pattern
+ */
+ public boolean isElementVisible(Viewer viewer, Object element) {
+ return isParentMatch(viewer, element) || isLeafMatch(viewer, element);
+ }
+
+ /**
+ * Check if the parent (category) is a match to the filter text. The default behavior returns true if the element
+ * has at least one child element that is a match with the filter text. Subclasses may override this method.
+ *
+ * @param viewer
+ * the viewer that contains the element
+ * @param element
+ * the tree element to check
+ * @return true if the given element has children that matches the filter text
+ */
+ protected boolean isParentMatch(Viewer viewer, Object element) {
+ Object[] children = getChildren(element);
+
+ if ((children != null) && (children.length > 0)) {
+ return isAnyVisible(viewer, element, children);
+ }
+ return false;
+ }
+
+ protected Object[] getChildren(Object element) {
+ return null;
+ }
+
+ /**
+ * Check if the current (leaf) element is a match with the filter text. The default behavior checks that the label
+ * of the element is a match. Subclasses should override this method.
+ *
+ * @param viewer
+ * the viewer that contains the element
+ * @param element
+ * the tree element to check
+ * @return true if the given element's label matches the filter text
+ */
+ protected boolean isLeafMatch(Viewer viewer, Object element) {
+ String labelText = ((ILabelProvider) ((StructuredViewer) viewer).getLabelProvider()).getText(element);
+
+ if (labelText == null) {
+ return false;
+ }
+ return wordMatches(labelText);
+ }
+
+ /**
+ * Take the given filter text and break it down into words using a BreakIterator.
+ *
+ * @param text
+ * @return an array of words
+ */
+ private String[] getWords(String text) {
+ List words = new ArrayList();
+ // Break the text up into words, separating based on whitespace and
+ // common punctuation.
+ // Previously used String.split(..., "\\W"), where "\W" is a regular
+ // expression (see the Javadoc for class Pattern).
+ // Need to avoid both String.split and regular expressions, in order to
+ // compile against JCL Foundation (bug 80053).
+ // Also need to do this in an NL-sensitive way. The use of BreakIterator
+ // was suggested in bug 90579.
+ BreakIterator iter = BreakIterator.getWordInstance();
+ iter.setText(text);
+ int i = iter.first();
+ while (i != java.text.BreakIterator.DONE && i < text.length()) {
+ int j = iter.following(i);
+ if (j == java.text.BreakIterator.DONE) {
+ j = text.length();
+ }
+ // match the word
+ if (Character.isLetterOrDigit(text.charAt(i))) {
+ String word = text.substring(i, j);
+ words.add(word);
+ }
+ i = j;
+ }
+ return (String[]) words.toArray(new String[words.size()]);
+ }
+
+ /**
+ * Return whether or not if any of the words in text satisfy the match critera.
+ *
+ * @param text
+ * the text to match
+ * @return boolean <code>true</code> if one of the words in text satisifes the match criteria.
+ */
+ protected boolean wordMatches(String text) {
+ if (text == null) {
+ return false;
+ }
+
+ //If the whole text matches we are all set
+ if (match(text)) {
+ return true;
+ }
+
+ // Otherwise check if any of the words of the text matches
+ String[] words = getWords(text);
+ for (String word : words) {
+ if (match(word)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Can be called by the filtered tree to turn on caching.
+ *
+ * @param useCache
+ * The useCache to set.
+ */
+ void setUseCache(boolean useCache) {
+ this.useCache = useCache;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/SelectionProviderAdapter.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/SelectionProviderAdapter.java
new file mode 100644
index 000000000..486358ded
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/SelectionProviderAdapter.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+
+/**
+ * Provides an simple implementation of {@link ISelectionProvider} that propagates selection events to registered
+ * listeners.
+ *
+ * @author Steffen Pingel
+ */
+public class SelectionProviderAdapter extends EventManager implements ISelectionProvider, ISelectionChangedListener {
+
+ private ISelection selection;
+
+ /**
+ * Constructs a <code>SelectionProviderAdapter</code> and initializes the selection to <code>selection</code>.
+ *
+ * @param selection
+ * the initial selection
+ * @see #setSelection(ISelection)
+ */
+ public SelectionProviderAdapter(ISelection selection) {
+ setSelection(selection);
+ }
+
+ /**
+ * Constructs a <code>SelectionProviderAdapter</code> with a <code>null</code> selection.
+ */
+ public SelectionProviderAdapter() {
+ }
+
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ addListenerObject(listener);
+ }
+
+ public ISelection getSelection() {
+ return selection;
+ }
+
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ removeListenerObject(listener);
+ }
+
+ public void selectionChanged(final SelectionChangedEvent event) {
+ this.selection = event.getSelection();
+ Object[] listeners = getListeners();
+ for (int i = 0; i < listeners.length; ++i) {
+ final ISelectionChangedListener listener = (ISelectionChangedListener) listeners[i];
+ SafeRunner.run(new SafeRunnable() {
+ public void run() {
+ listener.selectionChanged(event);
+ }
+ });
+ }
+ }
+
+ public void setSelection(ISelection selection) {
+ selectionChanged(new SelectionChangedEvent(this, selection));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/WorkbenchUtil.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/WorkbenchUtil.java
new file mode 100644
index 000000000..120241f69
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/WorkbenchUtil.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 Tasktop Technologies 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
+ * IBM Corporation - helper methods from
+ * org.eclipse.wst.common.frameworks.internal.ui.WTPActivityHelper
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.util;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Calendar;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.activities.IIdentifier;
+import org.eclipse.ui.activities.IWorkbenchActivitySupport;
+import org.eclipse.ui.browser.IWebBrowser;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.internal.browser.WebBrowserPreference;
+import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
+
+/**
+ * @author Mik Kersten
+ * @author Steffen Pingel
+ */
+public class WorkbenchUtil {
+
+ /**
+ * Return the modal shell that is currently open. If there isn't one then return null.
+ * <p>
+ * <b>Note: Applied from patch on bug 99472.</b>
+ *
+ * @param shell
+ * A shell to exclude from the search. May be <code>null</code>.
+ * @return Shell or <code>null</code>.
+ */
+ private static Shell getModalShellExcluding(Shell shell) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ Shell[] shells = workbench.getDisplay().getShells();
+ int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
+ for (Shell shell2 : shells) {
+ if (shell2.equals(shell)) {
+ break;
+ }
+ // Do not worry about shells that will not block the user.
+ if (shell2.isVisible()) {
+ int style = shell2.getStyle();
+ if ((style & modal) != 0) {
+ return shell2;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to get the best parenting possible for a dialog. If there is a modal shell create it so as to
+ * avoid two modal dialogs. If not then return the shell of the active workbench window. If neither can be found
+ * return null.
+ * <p>
+ * <b>Note: Applied from patch on bug 99472.</b>
+ *
+ * @return Shell or <code>null</code>
+ */
+ public static Shell getShell() {
+ if (!PlatformUI.isWorkbenchRunning() || PlatformUI.getWorkbench().isClosing()) {
+ return null;
+ }
+ Shell modal = getModalShellExcluding(null);
+ if (modal != null) {
+ return modal;
+ }
+ return getNonModalShell();
+ }
+
+ /**
+ * Get the active non modal shell. If there isn't one return null.
+ * <p>
+ * <b>Note: Applied from patch on bug 99472.</b>
+ *
+ * @return Shell
+ */
+ private static Shell getNonModalShell() {
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) {
+ IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
+ if (windows.length > 0) {
+ return windows[0].getShell();
+ }
+ } else {
+ return window.getShell();
+ }
+
+ return null;
+ }
+
+ /**
+ * @return whether the UI is set up to filter contributions (has defined activity categories).
+ */
+ public static final boolean isFiltering() {
+ return !PlatformUI.getWorkbench().getActivitySupport().getActivityManager().getDefinedActivityIds().isEmpty();
+ }
+
+ public static boolean allowUseOf(Object object) {
+ if (!isFiltering()) {
+ return true;
+ }
+ if (object instanceof IPluginContribution) {
+ IPluginContribution contribution = (IPluginContribution) object;
+ if (contribution.getPluginId() != null) {
+ IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport();
+ IIdentifier identifier = workbenchActivitySupport.getActivityManager().getIdentifier(
+ createUnifiedId(contribution));
+ return identifier.isEnabled();
+ }
+ }
+ if (object instanceof String) {
+ IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport();
+ IIdentifier identifier = workbenchActivitySupport.getActivityManager().getIdentifier((String) object);
+ return identifier.isEnabled();
+ }
+ return true;
+ }
+
+ private static final String createUnifiedId(IPluginContribution contribution) {
+ if (contribution.getPluginId() != null) {
+ return contribution.getPluginId() + '/' + contribution.getLocalId();
+ }
+ return contribution.getLocalId();
+ }
+
+ /**
+ * Opens <code>location</code> in a web-browser according to the Eclipse workbench preferences.
+ *
+ * @param location
+ * the url to open
+ * @see #openUrl(String, int)
+ */
+ public static void openUrl(String location) {
+ openUrl(location, SWT.NONE);
+ }
+
+ /**
+ * Opens <code>location</code> in a web-browser according to the Eclipse workbench preferences.
+ *
+ * @param location
+ * the url to open
+ * @param customFlags
+ * additional flags that are passed to {@link IWorkbenchBrowserSupport}, pass
+ * {@link IWorkbenchBrowserSupport#AS_EXTERNAL} to force opening external browser
+ */
+ public static void openUrl(String location, int customFlags) {
+ try {
+ URL url = null;
+ if (location != null) {
+ url = new URL(location);
+ }
+ if (WebBrowserPreference.getBrowserChoice() == WebBrowserPreference.EXTERNAL
+ || (customFlags & IWorkbenchBrowserSupport.AS_EXTERNAL) != 0) {
+ try {
+ IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
+ support.getExternalBrowser().openURL(url);
+ } catch (PartInitException e) {
+ Status status = new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN,
+ Messages.WorkbenchUtil_Browser_Initialization_Failed);
+ MessageDialog.openError(getShell(), Messages.WorkbenchUtil_Open_Location_Title, status.getMessage());
+ }
+ } else {
+ IWebBrowser browser = null;
+ int flags = customFlags;
+ if (WorkbenchBrowserSupport.getInstance().isInternalWebBrowserAvailable()) {
+ flags |= IWorkbenchBrowserSupport.AS_EDITOR | IWorkbenchBrowserSupport.LOCATION_BAR
+ | IWorkbenchBrowserSupport.NAVIGATION_BAR;
+ } else {
+ flags |= IWorkbenchBrowserSupport.AS_EXTERNAL | IWorkbenchBrowserSupport.LOCATION_BAR
+ | IWorkbenchBrowserSupport.NAVIGATION_BAR;
+ }
+
+ String generatedId = "org.eclipse.mylyn.web.browser-" + Calendar.getInstance().getTimeInMillis(); //$NON-NLS-1$
+ browser = WorkbenchBrowserSupport.getInstance().createBrowser(flags, generatedId, null, null);
+ browser.openURL(url);
+ }
+ } catch (PartInitException e) {
+ Status status = new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN,
+ Messages.WorkbenchUtil_Browser_Initialization_Failed, e);
+ LogHelper.log(status);
+ MessageDialog.openError(getShell(), Messages.WorkbenchUtil_Open_Location_Title, status.getMessage());
+ } catch (MalformedURLException e) {
+ if (location != null && location.trim().equals("")) { //$NON-NLS-1$
+ Status status = new Status(IStatus.WARNING, DiscoveryUi.ID_PLUGIN, Messages.WorkbenchUtil_No_URL_Error,
+ e);
+ MessageDialog.openWarning(getShell(), Messages.WorkbenchUtil_Open_Location_Title, status.getMessage());
+ } else {
+ Status status = new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN, NLS.bind(
+ Messages.WorkbenchUtil_Invalid_URL_Error, location), e);
+ MessageDialog.openError(getShell(), Messages.WorkbenchUtil_Open_Location_Title, status.getMessage());
+ }
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/messages.properties b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/messages.properties
new file mode 100644
index 000000000..565b48db1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/util/messages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+WorkbenchUtil_Browser_Initialization_Failed=Browser initialization failed.
+WorkbenchUtil_Invalid_URL_Error=Invalid URL specified: ''{0}''.
+WorkbenchUtil_No_URL_Error=No URL specified when opening browser.
+WorkbenchUtil_Open_Location_Title=Open Location
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/AbstractDiscoveryItem.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/AbstractDiscoveryItem.java
new file mode 100644
index 000000000..aa1cf7c76
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/AbstractDiscoveryItem.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.ControlListItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * @author Steffen Pingel
+ */
+public abstract class AbstractDiscoveryItem<T> extends ControlListItem<T> {
+
+ protected final DiscoveryResources resources;
+
+ public AbstractDiscoveryItem(Composite parent, int style, DiscoveryResources resources, T element) {
+ super(parent, style, element);
+ this.resources = resources;
+ }
+
+ private void hookRecursively(Control control, Listener listener) {
+ control.addListener(SWT.Dispose, listener);
+ control.addListener(SWT.MouseHover, listener);
+ control.addListener(SWT.MouseMove, listener);
+ control.addListener(SWT.MouseExit, listener);
+ control.addListener(SWT.MouseDown, listener);
+ control.addListener(SWT.MouseWheel, listener);
+ if (control instanceof Composite) {
+ for (Control child : ((Composite) control).getChildren()) {
+ hookRecursively(child, listener);
+ }
+ }
+ }
+
+ protected void hookTooltip(final Control parent, final Widget tipActivator, final Control exitControl,
+ final Control titleControl, AbstractCatalogSource source, Overview overview, Image image) {
+ final OverviewToolTip toolTip = new OverviewToolTip(parent, source, overview, image);
+ Listener listener = new Listener() {
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.MouseHover:
+ toolTip.show(titleControl);
+ break;
+ case SWT.Dispose:
+ case SWT.MouseWheel:
+ toolTip.hide();
+ break;
+ }
+
+ }
+ };
+ tipActivator.addListener(SWT.Dispose, listener);
+ tipActivator.addListener(SWT.MouseWheel, listener);
+ if (image != null) {
+ tipActivator.addListener(SWT.MouseHover, listener);
+ }
+ Listener selectionListener = new Listener() {
+ public void handleEvent(Event event) {
+ toolTip.show(titleControl);
+ }
+ };
+ tipActivator.addListener(SWT.Selection, selectionListener);
+ Listener exitListener = new Listener() {
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.MouseWheel:
+ toolTip.hide();
+ break;
+ case SWT.MouseExit:
+ /*
+ * Check if the mouse exit happened because we move over the
+ * tooltip
+ */
+ Rectangle containerBounds = exitControl.getBounds();
+ Point displayLocation = exitControl.getParent().toDisplay(containerBounds.x, containerBounds.y);
+ containerBounds.x = displayLocation.x;
+ containerBounds.y = displayLocation.y;
+ if (containerBounds.contains(Display.getCurrent().getCursorLocation())) {
+ break;
+ }
+ toolTip.hide();
+ break;
+ }
+ }
+ };
+ hookRecursively(exitControl, exitListener);
+ }
+
+ @Override
+ public void updateColors(int index) {
+ // ignore
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogConfiguration.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogConfiguration.java
new file mode 100644
index 000000000..5aa5b88ba
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogConfiguration.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+
+/**
+ * A configuration for the discovery wizard that affects its presentation and behavior.
+ *
+ * @author David Green
+ */
+public class CatalogConfiguration {
+
+ private final List<CatalogFilter> filters = new ArrayList<CatalogFilter>();
+
+ private boolean showInstalled = false;
+
+ private boolean showInstalledFilter = true;
+
+ private boolean showTagFilter = true;
+
+ private boolean showTextFilter = true;
+
+ private boolean verifyUpdateSiteAvailability = true;
+
+ private Set<Tag> selectedTags;
+
+ public List<CatalogFilter> getFilters() {
+ return filters;
+ }
+
+ public Set<Tag> getSelectedTags() {
+ return selectedTags;
+ }
+
+ public boolean isShowInstalled() {
+ return showInstalled;
+ }
+
+ public boolean isShowInstalledFilter() {
+ return showInstalledFilter;
+ }
+
+ public boolean isShowTagFilter() {
+ return showTagFilter;
+ }
+
+ /**
+ * indicate if a text field should be provided to allow the user to filter connector descriptors
+ */
+ public boolean isShowTextFilter() {
+ return showTextFilter;
+ }
+
+ public boolean isVerifyUpdateSiteAvailability() {
+ return verifyUpdateSiteAvailability;
+ }
+
+ public void setShowInstalled(boolean showInstalled) {
+ this.showInstalled = showInstalled;
+ }
+
+ public void setShowInstalledFilter(boolean showInstalledFilter) {
+ this.showInstalledFilter = showInstalledFilter;
+ }
+
+ public void setShowTagFilter(boolean showTagFilter) {
+ this.showTagFilter = showTagFilter;
+ }
+
+ /**
+ * indicate if a text field should be provided to allow the user to filter connector descriptors
+ */
+ public void setShowTextFilter(boolean showTextFilter) {
+ this.showTextFilter = showTextFilter;
+ }
+
+ public void setVerifyUpdateSiteAvailability(boolean verifyUpdateSiteAvailability) {
+ this.verifyUpdateSiteAvailability = verifyUpdateSiteAvailability;
+ }
+
+ public void setSelectedTags(Collection<Tag> selectedTags) {
+ if (selectedTags != null) {
+ this.selectedTags = new HashSet<Tag>(selectedTags);
+ } else {
+ this.selectedTags = null;
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogFilter.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogFilter.java
new file mode 100644
index 000000000..36c652e4e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogFilter.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+
+/**
+ * @author David Green
+ */
+public abstract class CatalogFilter {
+
+ public abstract boolean select(CatalogItem item);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogPage.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogPage.java
new file mode 100644
index 000000000..50808f576
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogPage.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ * David Green
+ * Shawn Minto bug 275513
+ * Steffen Pingel bug 276012 code review, bug 277191 gradient canvas
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.util.List;
+
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A wizard page that allows users to select connectors that they wish to install.
+ *
+ * @see DiscoveryWizard
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class CatalogPage extends WizardPage implements IShellProvider {
+
+ protected static final int MINIMUM_HEIGHT = 480;
+
+ private final Catalog catalog;
+
+ private boolean updated;
+
+ private CatalogViewer viewer;
+
+ public CatalogPage(Catalog catalog) {
+ super(CatalogPage.class.getSimpleName());
+ this.catalog = catalog;
+ setPageComplete(false);
+ setTitle(Messages.ConnectorDiscoveryWizardMainPage_connectorDiscovery);
+ setDescription(Messages.ConnectorDiscoveryWizardMainPage_pageDescription);
+ }
+
+ public void createControl(Composite parent) {
+ viewer = doCreateViewer(parent);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ setPageComplete(!viewer.getCheckedItems().isEmpty());
+ }
+ });
+ setControl(viewer.getControl());
+ }
+
+ protected CatalogViewer doCreateViewer(Composite parent) {
+ CatalogViewer viewer = new CatalogViewer(getCatalog(), this, getContainer(), getWizard().getConfiguration());
+ viewer.setMinimumHeight(MINIMUM_HEIGHT);
+ viewer.createControl(parent);
+ return viewer;
+ }
+
+ public Catalog getCatalog() {
+ return catalog;
+ }
+
+ public List<CatalogItem> getInstallableConnectors() {
+ return viewer.getCheckedItems();
+ }
+
+ @Override
+ public DiscoveryWizard getWizard() {
+ return (DiscoveryWizard) super.getWizard();
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (!updated) {
+ updated = true;
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ updateCatalog();
+ }
+ });
+ }
+ }
+
+ private void updateCatalog() {
+ if (!getControl().isDisposed() && isCurrentPage()) {
+ viewer.updateCatalog();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogViewer.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogViewer.java
new file mode 100644
index 000000000..d58a386f0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CatalogViewer.java
@@ -0,0 +1,597 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IBundleGroup;
+import org.eclipse.core.runtime.IBundleGroupProvider;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+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;
+import org.eclipse.equinox.internal.p2.discovery.model.Tag;
+import org.eclipse.equinox.internal.p2.discovery.util.CatalogCategoryComparator;
+import org.eclipse.equinox.internal.p2.discovery.util.CatalogItemComparator;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.ControlListItem;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.ControlListViewer;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.FilteredViewer;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.PatternFilter;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.SelectionProviderAdapter;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * The main wizard page that allows users to select connectors that they wish to install.
+ *
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class CatalogViewer extends FilteredViewer {
+
+ private class Filter extends ViewerFilter {
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (element instanceof CatalogItem) {
+ return doFilter((CatalogItem) element);
+ } else if (element instanceof CatalogCategory) {
+ // only show categories if at least one child is visible
+ CatalogCategory category = (CatalogCategory) element;
+ for (CatalogItem item : category.getItems()) {
+ if (doFilter(item)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ private class FindFilter extends PatternFilter {
+
+ private boolean filterMatches(String text) {
+ return text != null && wordMatches(text);
+ }
+
+ @Override
+ protected Object[] getChildren(Object element) {
+ if (element instanceof CatalogCategory) {
+ return ((CatalogCategory) element).getItems().toArray();
+ }
+ return super.getChildren(element);
+ }
+
+ @Override
+ protected boolean isLeafMatch(Viewer viewer, Object element) {
+ if (element instanceof CatalogItem) {
+ CatalogItem descriptor = (CatalogItem) element;
+ if (!(filterMatches(descriptor.getName()) || filterMatches(descriptor.getDescription())
+ || filterMatches(descriptor.getProvider()) || filterMatches(descriptor.getLicense()))) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ }
+
+// private class ConnectorBorderPaintListener implements PaintListener {
+// public void paintControl(PaintEvent e) {
+// Composite composite = (Composite) e.widget;
+// Rectangle bounds = composite.getBounds();
+// GC gc = e.gc;
+// gc.setLineStyle(SWT.LINE_DOT);
+// gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
+// }
+// }
+
+ private static final int DEFAULT_HEIGHT = 250;
+
+ private final Catalog catalog;
+
+ private final List<CatalogItem> checkedItems = new ArrayList<CatalogItem>();
+
+ private boolean complete;
+
+ private final CatalogConfiguration configuration;
+
+ private final IRunnableContext context;
+
+ private boolean ignoreUpdates;
+
+ private Set<String> installedFeatures;
+
+ private DiscoveryResources resources;
+
+ private final SelectionProviderAdapter selectionProvider;
+
+ private final IShellProvider shellProvider;
+
+ boolean showInstalled;
+
+ private Button showInstalledCheckbox;
+
+ private Set<Tag> visibleTags;
+
+ public CatalogViewer(Catalog catalog, IShellProvider shellProvider, IRunnableContext context,
+ CatalogConfiguration configuration) {
+ Assert.isNotNull(catalog);
+ Assert.isNotNull(shellProvider);
+ Assert.isNotNull(context);
+ Assert.isNotNull(configuration);
+ this.catalog = catalog;
+ this.shellProvider = shellProvider;
+ this.context = context;
+ this.configuration = configuration;
+ this.selectionProvider = new SelectionProviderAdapter();
+ this.showInstalled = configuration.isShowInstalled();
+ if (configuration.getSelectedTags() != null) {
+ this.visibleTags = new HashSet<Tag>(configuration.getSelectedTags());
+ } else {
+ this.visibleTags = new HashSet<Tag>();
+ }
+ setMinimumHeight(DEFAULT_HEIGHT);
+ setComplete(false);
+ }
+
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ selectionProvider.addSelectionChangedListener(listener);
+ }
+
+ protected void catalogUpdated(boolean wasCancelled) {
+ if (catalog != null && !wasCancelled) {
+ int categoryWithConnectorCount = 0;
+ for (CatalogCategory category : catalog.getCategories()) {
+ categoryWithConnectorCount += category.getItems().size();
+ }
+ if (categoryWithConnectorCount == 0) {
+ // nothing was discovered: notify the user
+ MessageDialog.openWarning(getShell(), Messages.ConnectorDiscoveryWizardMainPage_noConnectorsFound,
+ Messages.ConnectorDiscoveryWizardMainPage_noConnectorsFound_description);
+ }
+ }
+ viewer.setInput(catalog);
+ selectionProvider.setSelection(StructuredSelection.EMPTY);
+ }
+
+ private IStatus computeStatus(InvocationTargetException e, String message) {
+ Throwable cause = e.getCause();
+ IStatus statusCause;
+ if (cause instanceof CoreException) {
+ statusCause = ((CoreException) cause).getStatus();
+ } else {
+ statusCause = new Status(IStatus.ERROR, DiscoveryUi.ID_PLUGIN, cause.getMessage(), cause);
+ }
+ if (statusCause.getMessage() != null) {
+ message = NLS.bind(Messages.ConnectorDiscoveryWizardMainPage_message_with_cause, message,
+ statusCause.getMessage());
+ }
+ IStatus status = new MultiStatus(DiscoveryUi.ID_PLUGIN, 0, new IStatus[] { statusCause }, message, cause);
+ return status;
+ }
+
+ protected Pattern createPattern(String filterText) {
+ if (filterText == null || filterText.length() == 0) {
+ return null;
+ }
+ String regex = filterText;
+ regex.replace("\\", "\\\\").replace("?", ".").replace("*", ".*?"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ return Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+ }
+
+ public void dispose() {
+ if (catalog != null) {
+ catalog.dispose();
+ }
+ }
+
+ @Override
+ protected PatternFilter doCreateFilter() {
+ return new FindFilter();
+ }
+
+ @Override
+ protected void doCreateHeaderControls(Composite parent) {
+ if (configuration.isShowInstalledFilter()) {
+ showInstalledCheckbox = new Button(parent, SWT.CHECK);
+ showInstalledCheckbox.setSelection(showInstalled);
+ showInstalledCheckbox.setText(Messages.DiscoveryViewer_Show_Installed);
+ showInstalledCheckbox.addSelectionListener(new SelectionListener() {
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if (ignoreUpdates) {
+ return;
+ }
+
+ ignoreUpdates = true;
+ setShowInstalled(showInstalledCheckbox.getSelection());
+ ignoreUpdates = false;
+ }
+ });
+ }
+ if (configuration.isShowTagFilter()) {
+ for (final Tag tag : catalog.getTags()) {
+ final Button checkbox = new Button(parent, SWT.CHECK);
+ checkbox.setSelection(visibleTags.contains(tag));
+ checkbox.setText(tag.getLabel());
+ checkbox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ boolean selection = checkbox.getSelection();
+ if (selection) {
+ visibleTags.add(tag);
+ } else {
+ visibleTags.remove(tag);
+ }
+ refresh();
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ protected StructuredViewer doCreateViewer(Composite container) {
+ StructuredViewer viewer = new ControlListViewer(container, SWT.BORDER) {
+ @Override
+ protected ControlListItem<?> doCreateItem(Composite parent, Object element) {
+ return doCreateViewerItem(parent, element);
+ }
+ };
+ viewer.setContentProvider(new ITreeContentProvider() {
+
+ private Catalog catalog;
+
+ public void dispose() {
+ catalog = null;
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof CatalogCategory) {
+ return ((CatalogCategory) parentElement).getItems().toArray();
+ }
+ return null;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (catalog != null) {
+ List<Object> elements = new ArrayList<Object>();
+ elements.addAll(catalog.getCategories());
+ elements.addAll(catalog.getItems());
+ return elements.toArray(new Object[0]);
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof CatalogCategory) {
+ return catalog;
+ }
+ if (element instanceof CatalogItem) {
+ return ((CatalogItem) element).getCategory();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof CatalogCategory) {
+ return ((CatalogCategory) element).getItems().size() > 0;
+ }
+ return false;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ this.catalog = (Catalog) newInput;
+ }
+ });
+ viewer.setSorter(new ViewerSorter() {
+ CatalogCategoryComparator categoryComparator = new CatalogCategoryComparator();
+
+ CatalogItemComparator itemComparator = new CatalogItemComparator();
+
+ @Override
+ public int compare(Viewer viewer, Object o1, Object o2) {
+ CatalogCategory cat1 = getCategory(o1);
+ CatalogCategory cat2 = getCategory(o2);
+
+ // FIXME filter uncategorized items?
+ if (cat1 == null) {
+ return (cat2 != null) ? 1 : 0;
+ } else if (cat2 == null) {
+ return 1;
+ }
+
+ int i = categoryComparator.compare(cat1, cat2);
+ if (i == 0) {
+ if (o1 instanceof CatalogCategory) {
+ return -1;
+ }
+ if (o2 instanceof CatalogCategory) {
+ return 1;
+ }
+ if (cat1 == cat2 && o1 instanceof CatalogItem && o2 instanceof CatalogItem) {
+ return itemComparator.compare((CatalogItem) o1, (CatalogItem) o2);
+ }
+ return super.compare(viewer, o1, o2);
+ }
+ return i;
+ }
+
+// private int compare(Comparator<Object> comparator, Object key1, Object key2) {
+// if (key1 == null) {
+// return (key2 != null) ? 1 : 0;
+// } else if (key2 == null) {
+// return -1;
+// }
+// return comparator.compare(key1, key2);
+// }
+ private CatalogCategory getCategory(Object o) {
+ if (o instanceof CatalogCategory) {
+ return (CatalogCategory) o;
+ }
+ if (o instanceof CatalogItem) {
+ return ((CatalogItem) o).getCategory();
+ }
+ return null;
+ }
+ });
+
+ resources = new DiscoveryResources(container.getDisplay());
+ viewer.getControl().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ resources.dispose();
+ }
+ });
+ viewer.addFilter(new Filter());
+ return viewer;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected ControlListItem<?> doCreateViewerItem(Composite parent, Object element) {
+ if (element instanceof CatalogItem) {
+ return new DiscoveryItem(parent, SWT.NONE, resources, shellProvider, (CatalogItem) element, this);
+ } else if (element instanceof CatalogCategory) {
+ return new CategoryItem(parent, SWT.NONE, resources, (CatalogCategory) element);
+ }
+ return null;
+ }
+
+ protected boolean doFilter(CatalogItem item) {
+ if (!showInstalled && item.isInstalled()) {
+ return false;
+ }
+
+ if (!isTagVisible(item)) {
+ return false;
+ }
+
+ for (CatalogFilter filter : configuration.getFilters()) {
+ if (!filter.select(item)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public Catalog getCatalog() {
+ return catalog;
+ }
+
+ public List<CatalogItem> getCheckedItems() {
+ return new ArrayList<CatalogItem>(checkedItems);
+ }
+
+ public CatalogConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ protected Set<String> getInstalledFeatures(IProgressMonitor monitor) throws InterruptedException {
+ Set<String> installedFeatures = new HashSet<String>();
+ IBundleGroupProvider[] bundleGroupProviders = Platform.getBundleGroupProviders();
+ for (IBundleGroupProvider provider : bundleGroupProviders) {
+ if (monitor.isCanceled()) {
+ throw new InterruptedException();
+ }
+ IBundleGroup[] bundleGroups = provider.getBundleGroups();
+ for (IBundleGroup group : bundleGroups) {
+ installedFeatures.add(group.getIdentifier());
+ }
+ }
+ return installedFeatures;
+ }
+
+ public IStructuredSelection getSelection() {
+ return (IStructuredSelection) selectionProvider.getSelection();
+ }
+
+ private Shell getShell() {
+ return shellProvider.getShell();
+ }
+
+ public boolean isComplete() {
+ return complete;
+ }
+
+ public boolean isShowInstalled() {
+ return showInstalled;
+ }
+
+ private boolean isTagVisible(CatalogItem item) {
+ if (!configuration.isShowTagFilter()) {
+ return true;
+ }
+ for (Tag selectedTag : visibleTags) {
+ for (Tag tag : item.getTags()) {
+ if (tag.equals(selectedTag)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void modifySelection(final CatalogItem connector, boolean selected) {
+ modifySelectionInternal(connector, selected);
+ updateState();
+ }
+
+ private void modifySelectionInternal(final CatalogItem connector, boolean selected) {
+ connector.setSelected(selected);
+ if (selected) {
+ checkedItems.add(connector);
+ } else {
+ checkedItems.remove(connector);
+ }
+ }
+
+ protected void postDiscovery() {
+ for (CatalogItem connector : catalog.getItems()) {
+ connector.setInstalled(installedFeatures != null
+ && installedFeatures.containsAll(connector.getInstallableUnits()));
+ }
+ }
+
+ public void refresh() {
+ if (viewer != null && !viewer.getControl().isDisposed()) {
+ viewer.refresh();
+ }
+ }
+
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ selectionProvider.removeSelectionChangedListener(listener);
+ }
+
+ public void setComplete(boolean complete) {
+ this.complete = complete;
+ }
+
+ public void setSelection(IStructuredSelection selection) {
+ Set<CatalogItem> selected = new HashSet<CatalogItem>();
+ for (Object descriptor : selection.toArray()) {
+ if (descriptor instanceof CatalogItem) {
+ selected.add((CatalogItem) descriptor);
+ }
+ }
+ for (CatalogItem connector : catalog.getItems()) {
+ modifySelectionInternal(connector, selected.contains(connector));
+ }
+ updateState();
+ }
+
+ public void setShowInstalled(boolean showInstalled) {
+ this.showInstalled = showInstalled;
+ showInstalledCheckbox.setSelection(showInstalled);
+ refresh();
+ }
+
+ public void updateCatalog() {
+ boolean wasCancelled = false;
+ try {
+ final IStatus[] result = new IStatus[1];
+ context.run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ if (installedFeatures == null) {
+ installedFeatures = getInstalledFeatures(monitor);
+ }
+
+ result[0] = catalog.performDiscovery(monitor);
+ if (monitor.isCanceled()) {
+ throw new InterruptedException();
+ }
+
+ postDiscovery();
+ }
+ });
+
+ if (result[0] != null && !result[0].isOK()) {
+ StatusManager.getManager().handle(result[0],
+ StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ }
+ } catch (InvocationTargetException e) {
+ IStatus status = computeStatus(e, Messages.ConnectorDiscoveryWizardMainPage_unexpectedException);
+ StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ } catch (InterruptedException e) {
+ // cancelled by user so nothing to do here.
+ wasCancelled = true;
+ }
+ if (catalog != null) {
+ catalogUpdated(wasCancelled);
+ if (configuration.isVerifyUpdateSiteAvailability() && !catalog.getItems().isEmpty()) {
+ try {
+ context.run(true, true, new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException,
+ InterruptedException {
+ //discovery.verifySiteAvailability(monitor);
+ }
+ });
+ } catch (InvocationTargetException e) {
+ IStatus status = computeStatus(e, Messages.ConnectorDiscoveryWizardMainPage_unexpectedException);
+ StatusManager.getManager().handle(status,
+ StatusManager.SHOW | StatusManager.BLOCK | StatusManager.LOG);
+ } catch (InterruptedException e) {
+ // cancelled by user so nothing to do here.
+ wasCancelled = true;
+ }
+ }
+ }
+ // help UI tests
+ viewer.setData("discoveryComplete", "true"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ private void updateState() {
+ setComplete(!checkedItems.isEmpty());
+ selectionProvider.setSelection(new StructuredSelection(getCheckedItems()));
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CategoryItem.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CategoryItem.java
new file mode 100644
index 000000000..27ca14cf7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/CategoryItem.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.GradientCanvas;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * @author Steffen Pingel
+ */
+public class CategoryItem<T extends CatalogCategory> extends AbstractDiscoveryItem<T> {
+
+ public CategoryItem(Composite parent, int style, DiscoveryResources resources, T category) {
+ super(parent, style, resources, category);
+ createContent(category);
+ }
+
+ protected boolean hasTooltip(final CatalogCategory category) {
+ return category.getOverview() != null && category.getOverview().getSummary() != null
+ && category.getOverview().getSummary().length() > 0;
+ }
+
+ private void createContent(T category) {
+ setLayout(new FillLayout());
+
+ final GradientCanvas categoryHeaderContainer = new GradientCanvas(this, SWT.NONE);
+ categoryHeaderContainer.setSeparatorVisible(true);
+ categoryHeaderContainer.setSeparatorAlignment(SWT.TOP);
+ categoryHeaderContainer.setBackgroundGradient(new Color[] { resources.getGradientBeginColor(),
+ resources.getGradientEndColor() }, new int[] { 100 }, true);
+ categoryHeaderContainer.putColor(GradientCanvas.H_BOTTOM_KEYLINE1, resources.getGradientBeginColor());
+ categoryHeaderContainer.putColor(GradientCanvas.H_BOTTOM_KEYLINE2, resources.getGradientEndColor());
+
+ //GridDataFactory.fillDefaults().span(2, 1).applyTo(categoryHeaderContainer);
+ GridLayoutFactory.fillDefaults().numColumns(3).margins(5, 5).equalWidth(false).applyTo(categoryHeaderContainer);
+
+ Label iconLabel = new Label(categoryHeaderContainer, SWT.NULL);
+ if (category.getIcon() != null) {
+ iconLabel.setImage(resources.getIconImage(category.getSource(), category.getIcon(), 48, true));
+ }
+ iconLabel.setBackground(null);
+ GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).span(1, 2).applyTo(iconLabel);
+
+ Label nameLabel = new Label(categoryHeaderContainer, SWT.NULL);
+ nameLabel.setFont(resources.getHeaderFont());
+ nameLabel.setText(category.getName());
+ nameLabel.setBackground(null);
+
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameLabel);
+ if (hasTooltip(category)) {
+ ToolBar toolBar = new ToolBar(categoryHeaderContainer, SWT.FLAT);
+ toolBar.setBackground(null);
+ ToolItem infoButton = new ToolItem(toolBar, SWT.PUSH);
+ infoButton.setImage(resources.getInfoImage());
+ infoButton.setToolTipText(Messages.ConnectorDiscoveryWizardMainPage_tooltip_showOverview);
+ hookTooltip(toolBar, infoButton, categoryHeaderContainer, nameLabel, category.getSource(),
+ category.getOverview(), null);
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toolBar);
+ } else {
+ new Label(categoryHeaderContainer, SWT.NULL).setText(" "); //$NON-NLS-1$
+ }
+ if (category.getDescription() != null) {
+ Label description = new Label(categoryHeaderContainer, SWT.WRAP);
+ GridDataFactory.fillDefaults().grab(true, false).span(2, 1).hint(100, SWT.DEFAULT).applyTo(description);
+ description.setBackground(null);
+ description.setText(category.getDescription());
+ }
+ }
+
+ @Override
+ protected void refresh() {
+ // ignore
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryItem.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryItem.java
new file mode 100644
index 000000000..d27fb3658
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryItem.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+
+/**
+ * @author Steffen Pingel
+ */
+public class DiscoveryItem<T extends CatalogItem> extends AbstractDiscoveryItem<T> implements PropertyChangeListener {
+
+ private Button checkbox;
+
+ private Composite checkboxContainer;
+
+ private final CatalogItem connector;
+
+ private Label description;
+
+ private Label iconLabel;
+
+ private ToolItem infoButton;
+
+ private Label nameLabel;
+
+ private Link providerLabel;
+
+ private final IShellProvider shellProvider;
+
+ private ToolItem updateButton;
+
+ private final CatalogViewer viewer;
+
+ public DiscoveryItem(Composite parent, int style, DiscoveryResources resources, IShellProvider shellProvider,
+ final T connector, CatalogViewer viewer) {
+ super(parent, style, resources, connector);
+ this.shellProvider = shellProvider;
+ this.connector = connector;
+ this.viewer = viewer;
+ connector.addPropertyChangeListener(this);
+ this.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ connector.removePropertyChangeListener(DiscoveryItem.this);
+ }
+ });
+ createContent();
+ initializeListeners();
+ }
+
+ private void createContent() {
+ GridLayout layout = new GridLayout(4, false);
+ layout.marginLeft = 7;
+ layout.marginTop = 2;
+ layout.marginBottom = 2;
+ setLayout(layout);
+
+ checkboxContainer = new Composite(this, SWT.INHERIT_NONE);
+ GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.BEGINNING).span(1, 2).applyTo(checkboxContainer);
+ GridLayoutFactory.fillDefaults().spacing(1, 1).numColumns(2).applyTo(checkboxContainer);
+
+ checkbox = new Button(checkboxContainer, SWT.CHECK | SWT.INHERIT_FORCE);
+ checkbox.setSelection(connector.isSelected());
+ checkbox.setText(" "); //$NON-NLS-1$
+ // help UI tests
+ checkbox.setData("connectorId", connector.getId()); //$NON-NLS-1$
+ // FIXME
+// checkbox.addFocusListener(new FocusAdapter() {
+// @Override
+// public void focusGained(FocusEvent e) {
+// bodyScrolledComposite.showControl(this);
+// }
+// });
+ GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(checkbox);
+
+ iconLabel = new Label(checkboxContainer, SWT.NONE);
+ GridDataFactory.swtDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(iconLabel);
+ if (connector.getIcon() != null) {
+ iconLabel.setImage(resources.getIconImage(connector.getSource(), connector.getIcon(), 32, false));
+ }
+
+ nameLabel = new Label(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(nameLabel);
+ nameLabel.setFont(resources.getSmallHeaderFont());
+ nameLabel.setText(connector.getName());
+
+ providerLabel = new Link(this, SWT.RIGHT);
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(providerLabel);
+ // always disabled color to make it less prominent
+ providerLabel.setForeground(resources.getColorDisabled());
+ if (connector.getCertification() != null) {
+ providerLabel.setText(NLS.bind(Messages.DiscoveryViewer_Certification_Label0, new String[] {
+ connector.getProvider(), connector.getLicense(), connector.getCertification().getName() }));
+ if (connector.getCertification().getUrl() != null) {
+ providerLabel.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ WorkbenchUtil.openUrl(connector.getCertification().getUrl(),
+ IWorkbenchBrowserSupport.AS_EXTERNAL);
+ }
+ });
+ }
+ Overview overview = new Overview();
+ overview.setSummary(connector.getCertification().getDescription());
+ overview.setUrl(connector.getCertification().getUrl());
+ Image image = resources.getIconImage(connector.getSource(), connector.getCertification().getIcon(), 48,
+ true);
+ hookTooltip(providerLabel, providerLabel, this, providerLabel, connector.getSource(), overview, image);
+ } else {
+ providerLabel.setText(NLS.bind(Messages.ConnectorDiscoveryWizardMainPage_provider_and_license,
+ connector.getProvider(), connector.getLicense()));
+ }
+
+ if (hasTooltip(connector) || connector.isInstalled()) {
+ ToolBar toolBar = new ToolBar(this, SWT.FLAT);
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toolBar);
+
+ if (connector.isInstalled()) {
+ updateButton = new ToolItem(toolBar, SWT.PUSH);
+ updateButton.setImage(resources.getUpdateImage());
+ updateButton.setToolTipText("Check for Updates");
+ }
+
+ if (hasTooltip(connector)) {
+ infoButton = new ToolItem(toolBar, SWT.PUSH);
+ infoButton.setImage(resources.getInfoImage());
+ infoButton.setToolTipText(Messages.ConnectorDiscoveryWizardMainPage_tooltip_showOverview);
+ hookTooltip(toolBar, infoButton, this, nameLabel, connector.getSource(), connector.getOverview(), null);
+ }
+ } else {
+ Label label = new Label(this, SWT.NULL);
+ label.setText(" "); //$NON-NLS-1$
+ }
+
+ description = new Label(this, SWT.NULL | SWT.WRAP);
+ GridDataFactory.fillDefaults().grab(true, false).span(3, 1).hint(100, SWT.DEFAULT).applyTo(description);
+ String descriptionText = connector.getDescription();
+ int maxDescriptionLength = 162;
+ if (descriptionText == null) {
+ descriptionText = ""; //$NON-NLS-1$
+ }
+ if (descriptionText.length() > maxDescriptionLength) {
+ descriptionText = descriptionText.substring(0, maxDescriptionLength);
+ }
+ description.setText(descriptionText.replaceAll("(\\r\\n)|\\n|\\r", " ")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected boolean hasTooltip(final CatalogItem connector) {
+ return connector.getOverview() != null && connector.getOverview().getSummary() != null
+ && connector.getOverview().getSummary().length() > 0;
+ }
+
+ public void initializeListeners() {
+ checkbox.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ boolean selected = checkbox.getSelection();
+ maybeModifySelection(selected);
+ }
+ });
+ MouseListener connectorItemMouseListener = new MouseAdapter() {
+ @Override
+ public void mouseUp(MouseEvent e) {
+ boolean selected = !checkbox.getSelection();
+ if (maybeModifySelection(selected)) {
+ checkbox.setSelection(selected);
+ }
+ }
+ };
+ checkboxContainer.addMouseListener(connectorItemMouseListener);
+ this.addMouseListener(connectorItemMouseListener);
+ iconLabel.addMouseListener(connectorItemMouseListener);
+ nameLabel.addMouseListener(connectorItemMouseListener);
+ // the provider has clickable links
+ //providerLabel.addMouseListener(connectorItemMouseListener);
+ description.addMouseListener(connectorItemMouseListener);
+ }
+
+ protected boolean maybeModifySelection(boolean selected) {
+ if (selected) {
+ if (connector.isInstalled()) {
+ MessageDialog.openWarning(shellProvider.getShell(), "Install Connector", NLS.bind(
+ "{0} is already installed.", connector.getName()));
+ return false;
+ }
+ if (connector.getAvailable() != null && !connector.getAvailable()) {
+ MessageDialog.openWarning(shellProvider.getShell(),
+ Messages.ConnectorDiscoveryWizardMainPage_warningTitleConnectorUnavailable, NLS.bind(
+ Messages.ConnectorDiscoveryWizardMainPage_warningMessageConnectorUnavailable,
+ connector.getName()));
+ return false;
+ }
+ }
+ viewer.modifySelection(connector, selected);
+ return true;
+ }
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (!isDisposed()) {
+ getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ if (!isDisposed()) {
+ refresh();
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void refresh() {
+ boolean enabled = connector.getAvailable() == null || connector.getAvailable();
+
+ checkbox.setEnabled(!connector.isInstalled() && enabled);
+ nameLabel.setEnabled(connector.isInstalled() || enabled);
+ providerLabel.setEnabled(connector.isInstalled() || enabled);
+ description.setEnabled(connector.isInstalled() || enabled);
+ Color foreground;
+ if (connector.isInstalled() || enabled) {
+ foreground = getForeground();
+ } else {
+ foreground = resources.getColorDisabled();
+ }
+ nameLabel.setForeground(foreground);
+ description.setForeground(foreground);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryResources.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryResources.java
new file mode 100644
index 000000000..2811f4524
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryResources.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.net.URL;
+
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.model.Icon;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryImages;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.jface.resource.FontDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Steffen Pingel
+ */
+public class DiscoveryResources {
+
+ private final ResourceManager resourceManager;
+
+ private final FontDescriptor h1FontDescriptor;
+
+ private final Display display;
+
+ private final FontDescriptor h2FontDescriptor;
+
+ private final RGB disabledColorDescriptor;
+
+ public DiscoveryResources(Display display) {
+ this.display = display;
+ this.resourceManager = new LocalResourceManager(JFaceResources.getResources(display));
+ this.h1FontDescriptor = createFontDescriptor(SWT.BOLD, 1.35f);
+ this.h2FontDescriptor = createFontDescriptor(SWT.BOLD, 1.25f);
+ this.disabledColorDescriptor = new RGB(0x69, 0x69, 0x69);
+ }
+
+ public Cursor getHandCursor() {
+ return display.getSystemCursor(SWT.CURSOR_HAND);
+ }
+
+ private FontDescriptor createFontDescriptor(int style, float heightMultiplier) {
+ Font baseFont = JFaceResources.getDialogFont();
+ FontData[] fontData = baseFont.getFontData();
+ for (FontData data : fontData) {
+ data.setStyle(data.getStyle() | style);
+ data.height = data.height * heightMultiplier;
+ }
+ return FontDescriptor.createFrom(fontData);
+ }
+
+ public void dispose() {
+ resourceManager.dispose();
+ }
+
+ public Font getHeaderFont() {
+ return resourceManager.createFont(h1FontDescriptor);
+ }
+
+ public Font getSmallHeaderFont() {
+ return resourceManager.createFont(h2FontDescriptor);
+ }
+
+ public Image getInfoImage() {
+ return resourceManager.createImage(DiscoveryImages.MESSAGE_INFO);
+ }
+
+ public Image getIconImage(AbstractCatalogSource discoverySource, Icon icon, int dimension, boolean fallback) {
+ String imagePath;
+ switch (dimension) {
+ case 64:
+ imagePath = icon.getImage64();
+ if (imagePath != null || !fallback) {
+ break;
+ }
+ case 48:
+ imagePath = icon.getImage48();
+ if (imagePath != null || !fallback) {
+ break;
+ }
+ case 32:
+ imagePath = icon.getImage32();
+ break;
+ default:
+ throw new IllegalArgumentException();
+ }
+ if (imagePath != null && imagePath.length() > 0) {
+ URL resource = discoverySource.getResource(imagePath);
+ if (resource != null) {
+ ImageDescriptor descriptor = ImageDescriptor.createFromURL(resource);
+ return resourceManager.createImage(descriptor);
+ }
+ }
+ return null;
+ }
+
+ public Color getGradientBeginColor() {
+ return DiscoveryUi.getCommonsColors().getGradientBegin();
+ }
+
+ public Color getGradientEndColor() {
+ return DiscoveryUi.getCommonsColors().getGradientEnd();
+ }
+
+ public Color getColorDisabled() {
+ return resourceManager.createColor(disabledColorDescriptor);
+ }
+
+ public Image getUpdateImage() {
+ return resourceManager.createImage(DiscoveryImages.IU_UPDATABLE);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryWizard.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryWizard.java
new file mode 100644
index 000000000..d2066b4f7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/DiscoveryWizard.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.equinox.internal.p2.discovery.Catalog;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryImages;
+import org.eclipse.equinox.internal.p2.ui.discovery.DiscoveryUi;
+import org.eclipse.equinox.internal.p2.ui.discovery.operations.DiscoveryInstallOperation;
+import org.eclipse.jface.wizard.Wizard;
+
+/**
+ * A wizard for performing discovery and selecting items from a catalog to install. When finish is pressed, selected
+ * items are downloaded and installed.
+ *
+ * @see DiscoveryInstallOperation
+ * @see CatalogPage
+ * @author David Green
+ * @author Steffen Pingel
+ */
+public class DiscoveryWizard extends Wizard {
+
+ private final Catalog catalog;
+
+ private CatalogPage catalogPage;
+
+ private final CatalogConfiguration configuration;
+
+ public DiscoveryWizard(Catalog catalog, CatalogConfiguration configuration) {
+ Assert.isNotNull(catalog);
+ Assert.isNotNull(configuration);
+ this.catalog = catalog;
+ this.configuration = configuration;
+ setWindowTitle(Messages.ConnectorDiscoveryWizard_connectorDiscovery);
+ setNeedsProgressMonitor(true);
+ setDefaultPageImageDescriptor(DiscoveryImages.BANNER_DISOVERY);
+ }
+
+ @Override
+ public void addPages() {
+ addPage(getCatalogPage());
+ }
+
+ protected CatalogPage doCreateCatalogPage() {
+ return new CatalogPage(getCatalog());
+ }
+
+ public Catalog getCatalog() {
+ return catalog;
+ }
+
+ public CatalogPage getCatalogPage() {
+ if (catalogPage == null) {
+ catalogPage = doCreateCatalogPage();
+ }
+ return catalogPage;
+ }
+
+ public CatalogConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public boolean performFinish() {
+ return DiscoveryUi.install(catalogPage.getInstallableConnectors(), getContainer());
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/Messages.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/Messages.java
new file mode 100644
index 000000000..84e7b02c6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/Messages.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author David Green
+ */
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.ui.discovery.wizards.messages"; //$NON-NLS-1$
+
+ public static String CatalogViewer_All_Categories;
+
+ public static String ConnectorDescriptorToolTip_detailsLink;
+
+ public static String ConnectorDescriptorToolTip_detailsLink_tooltip;
+
+ public static String ConnectorDiscoveryWizard_connectorDiscovery;
+
+ public static String ConnectorDiscoveryWizard_installProblems;
+
+ public static String InstallConnectorsJob_commaSeparator;
+
+ public static String InstallConnectorsJob_connectorsNotAvailable;
+
+ public static String InstallConnectorsJob_questionProceed;
+
+ public static String InstallConnectorsJob_questionProceed_long;
+
+ public static String InstallConnectorsJob_task_configuring;
+
+ public static String InstallConnectorsJob_unexpectedError_url;
+
+ public static String ConnectorDiscoveryWizardMainPage_clearButton_accessibleListener;
+
+ public static String ConnectorDiscoveryWizardMainPage_clearButton_toolTip;
+
+ public static String ConnectorDiscoveryWizardMainPage_connectorDiscovery;
+
+ public static String ConnectorDiscoveryWizardMainPage_filterLabel;
+
+ public static String ConnectorDiscoveryWizardMainPage_message_with_cause;
+
+ public static String ConnectorDiscoveryWizardMainPage_noConnectorsFound;
+
+ public static String ConnectorDiscoveryWizardMainPage_noConnectorsFound_description;
+
+ public static String ConnectorDiscoveryWizardMainPage_pageDescription;
+
+ public static String ConnectorDiscoveryWizardMainPage_provider_and_license;
+
+ public static String ConnectorDiscoveryWizardMainPage_tooltip_showOverview;
+
+ public static String ConnectorDiscoveryWizardMainPage_unexpectedException;
+
+ public static String ConnectorDiscoveryWizardMainPage_warningMessageConnectorUnavailable;
+
+ public static String ConnectorDiscoveryWizardMainPage_warningTitleConnectorUnavailable;
+
+ public static String DiscoveryViewer_Certification_Label0;
+
+ public static String DiscoveryViewer_Show_Installed;
+
+ public static String PrepareInstallProfileJob_notFoundDescriptorDetail;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/OverviewToolTip.java b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/OverviewToolTip.java
new file mode 100644
index 000000000..c6efd7324
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/OverviewToolTip.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Tasktop Technologies 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
+ *******************************************************************************/
+
+package org.eclipse.equinox.internal.p2.ui.discovery.wizards;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
+import org.eclipse.equinox.internal.p2.discovery.model.Overview;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.GradientToolTip;
+import org.eclipse.equinox.internal.p2.ui.discovery.util.WorkbenchUtil;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+
+/**
+ * @author David Green
+ */
+class OverviewToolTip extends GradientToolTip {
+
+ private final Overview overview;
+
+ private final AbstractCatalogSource source;
+
+ private final Control parent;
+
+ private final Image leftImage;
+
+ public OverviewToolTip(Control control, AbstractCatalogSource source, Overview overview, Image leftImage) {
+ super(control, ToolTip.RECREATE, true);
+ Assert.isNotNull(source);
+ Assert.isNotNull(overview);
+ this.parent = control;
+ this.source = source;
+ this.overview = overview;
+ this.leftImage = leftImage;
+ setHideOnMouseDown(false); // required for links to work
+ }
+
+ @Override
+ protected Composite createToolTipArea(Event event, final Composite parent) {
+ GridLayoutFactory.fillDefaults().applyTo(parent);
+
+ Composite container = new Composite(parent, SWT.NULL);
+ container.setBackground(null);
+
+ Image image = null;
+ if (overview.getScreenshot() != null) {
+ image = computeImage(source, overview.getScreenshot());
+ if (image != null) {
+ final Image fimage = image;
+ container.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ fimage.dispose();
+ }
+ });
+ }
+ }
+ final boolean hasLearnMoreLink = overview.getUrl() != null && overview.getUrl().length() > 0;
+
+ final int borderWidth = 1;
+ final int fixedImageHeight = 240;
+ final int fixedImageWidth = 320;
+ final int heightHint = fixedImageHeight + (borderWidth * 2);
+ final int widthHint = fixedImageWidth;
+
+ final int containerWidthHintWithImage = 650;
+ final int containerWidthHintWithoutImage = 500;
+
+ GridDataFactory.fillDefaults().grab(true, true).hint(
+ image == null ? containerWidthHintWithoutImage : containerWidthHintWithImage, SWT.DEFAULT).applyTo(
+ container);
+
+ GridLayoutFactory.fillDefaults().numColumns((leftImage != null) ? 3 : 2).margins(5, 5).spacing(3, 0).applyTo(
+ container);
+
+ if (leftImage != null) {
+ Label imageLabel = new Label(container, SWT.NONE);
+ imageLabel.setImage(leftImage);
+ int imageWidthHint = leftImage.getBounds().width + 5;
+ GridDataFactory.fillDefaults()
+ .align(SWT.BEGINNING, SWT.BEGINNING)
+ .hint(imageWidthHint, SWT.DEFAULT)
+ .applyTo(imageLabel);
+ }
+
+ String summary = overview.getSummary();
+
+ Composite summaryContainer = new Composite(container, SWT.NULL);
+ summaryContainer.setBackground(null);
+ GridLayoutFactory.fillDefaults().applyTo(summaryContainer);
+
+ GridDataFactory gridDataFactory = GridDataFactory.fillDefaults()
+ .grab(true, true)
+ .span(image == null ? 2 : 1, 1);
+ if (image != null) {
+ gridDataFactory.hint(widthHint, heightHint);
+ }
+ gridDataFactory.applyTo(summaryContainer);
+
+ StyledText summaryLabel = new StyledText(summaryContainer, SWT.WRAP | SWT.READ_ONLY | SWT.NO_FOCUS);
+ summaryLabel.setText(summary);
+ Point size = summaryLabel.computeSize(widthHint, SWT.DEFAULT);
+ if (size.y > heightHint - 20) {
+ summaryLabel.dispose();
+ summaryLabel = new StyledText(summaryContainer, SWT.WRAP | SWT.READ_ONLY | SWT.NO_FOCUS | SWT.V_SCROLL);
+ summaryLabel.setText(summary);
+ }
+ summaryLabel.setBackground(null);
+
+ GridDataFactory.fillDefaults().grab(true, true).align(SWT.BEGINNING, SWT.BEGINNING).applyTo(summaryLabel);
+
+ if (image != null) {
+ final Composite imageContainer = new Composite(container, SWT.BORDER);
+ GridLayoutFactory.fillDefaults().applyTo(imageContainer);
+
+ GridDataFactory.fillDefaults().grab(false, false).align(SWT.CENTER, SWT.BEGINNING).hint(
+ widthHint + (borderWidth * 2), heightHint).applyTo(imageContainer);
+
+ Label imageLabel = new Label(imageContainer, SWT.NULL);
+ GridDataFactory.fillDefaults().hint(widthHint, fixedImageHeight).indent(borderWidth, borderWidth).applyTo(
+ imageLabel);
+ imageLabel.setImage(image);
+ imageLabel.setBackground(null);
+ imageLabel.setSize(widthHint, fixedImageHeight);
+
+ // creates a border
+ imageContainer.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
+ }
+ if (hasLearnMoreLink) {
+ Link link = new Link(summaryContainer, SWT.NULL);
+ GridDataFactory.fillDefaults().grab(false, false).align(SWT.BEGINNING, SWT.CENTER).applyTo(link);
+ link.setText(Messages.ConnectorDescriptorToolTip_detailsLink);
+ link.setBackground(null);
+ link.setToolTipText(NLS.bind(Messages.ConnectorDescriptorToolTip_detailsLink_tooltip, overview.getUrl()));
+ link.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ WorkbenchUtil.openUrl(overview.getUrl(), IWorkbenchBrowserSupport.AS_EXTERNAL);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+ }
+ if (image == null) {
+ // prevent overviews with no image from providing unlimited text.
+ Point optimalSize = summaryContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ if (optimalSize.y > (heightHint + 10)) {
+ ((GridData) summaryContainer.getLayoutData()).heightHint = heightHint;
+ container.layout(true);
+ }
+ }
+ // hack: cause the tooltip to gain focus so that we can capture the escape key
+ // this must be done async since the tooltip is not yet visible.
+ Display.getCurrent().asyncExec(new Runnable() {
+ public void run() {
+ if (!parent.isDisposed()) {
+ parent.setFocus();
+ }
+ }
+ });
+ return container;
+ }
+
+ private Image computeImage(AbstractCatalogSource discoverySource, String imagePath) {
+ URL resource = discoverySource.getResource(imagePath);
+ if (resource != null) {
+ ImageDescriptor descriptor = ImageDescriptor.createFromURL(resource);
+ Image image = descriptor.createImage();
+ return image;
+ }
+ return null;
+ }
+
+ public void show(Control titleControl) {
+ Point titleAbsLocation = titleControl.getParent().toDisplay(titleControl.getLocation());
+ Point containerAbsLocation = parent.getParent().toDisplay(parent.getLocation());
+ Rectangle bounds = titleControl.getBounds();
+ int relativeX = titleAbsLocation.x - containerAbsLocation.x;
+ int relativeY = titleAbsLocation.y - containerAbsLocation.y;
+
+ relativeY += bounds.height + 3;
+ show(new Point(relativeX, relativeY));
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/messages.properties b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/messages.properties
new file mode 100644
index 000000000..36dee75ff
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.discovery/src/org/eclipse/equinox/internal/p2/ui/discovery/wizards/messages.properties
@@ -0,0 +1,39 @@
+###############################################################################
+# Copyright (c) 2009 Tasktop Technologies 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
+###############################################################################
+CatalogViewer_All_Categories=All Categories
+ConnectorDescriptorToolTip_detailsLink=<a>Learn More</a>
+ConnectorDescriptorToolTip_detailsLink_tooltip=Open {0} in an external browser
+ConnectorDiscoveryWizard_connectorDiscovery=Install Connectors
+ConnectorDiscoveryWizard_installProblems=Problems occurred while performing installation: {0}
+ConnectorDiscoveryWizardMainPage_clearButton_accessibleListener=Clear filter field
+ConnectorDiscoveryWizardMainPage_clearButton_toolTip=Clear
+ConnectorDiscoveryWizardMainPage_connectorDiscovery=Mylyn Connector Discovery
+ConnectorDiscoveryWizardMainPage_filterLabel=Find:
+ConnectorDiscoveryWizardMainPage_message_with_cause={0}: {1}
+ConnectorDiscoveryWizardMainPage_noConnectorsFound=No Connectors Found
+ConnectorDiscoveryWizardMainPage_noConnectorsFound_description=Connector discovery completed without finding any connectors. Please check your Internet connection and try again.
+ConnectorDiscoveryWizardMainPage_pageDescription=\
+ Select connectors to install. Press Finish to proceed with installation.\n\
+ Press the information button to see a detailed overview and a link to more information.
+ConnectorDiscoveryWizardMainPage_provider_and_license=by {0}, {1}
+ConnectorDiscoveryWizardMainPage_tooltip_showOverview=Show Overview
+ConnectorDiscoveryWizardMainPage_unexpectedException=Unexpected exception
+ConnectorDiscoveryWizardMainPage_warningMessageConnectorUnavailable=Sorry, {0} is unavailable. Please try again later.
+ConnectorDiscoveryWizardMainPage_warningTitleConnectorUnavailable=Connector Unavailable
+DiscoveryViewer_Certification_Label0=by {0}, {1}, <a>Certified</a>
+DiscoveryViewer_Show_Installed=Show Installed
+InstallConnectorsJob_commaSeparator=,
+InstallConnectorsJob_connectorsNotAvailable=The following connectors are not available: {0}
+InstallConnectorsJob_questionProceed=Proceed With Installation?
+InstallConnectorsJob_questionProceed_long=The following connectors are not available: {0}\nProceed with the installation anyways?
+InstallConnectorsJob_task_configuring=Configuring installation selection
+InstallConnectorsJob_unexpectedError_url=Unexpected error handling repository URL
+PrepareInstallProfileJob_notFoundDescriptorDetail={0} (id={1}, site={2})

Back to the top