diff options
author | Ed Merks | 2019-07-02 14:54:32 +0000 |
---|---|---|
committer | Ed Merks | 2019-07-02 14:54:32 +0000 |
commit | 80ae6f69423a99adf7a5711d6261553a723cfbda (patch) | |
tree | e0a6d2d747c531a05efadd52e186bbe2b3809c99 | |
parent | 49844241728f4c932c04ae4199c4d8202fac8d48 (diff) | |
download | org.eclipse.oomph-80ae6f69423a99adf7a5711d6261553a723cfbda.tar.gz org.eclipse.oomph-80ae6f69423a99adf7a5711d6261553a723cfbda.tar.xz org.eclipse.oomph-80ae6f69423a99adf7a5711d6261553a723cfbda.zip |
[548868] Provide support for installing marketplace listings
https://bugs.eclipse.org/bugs/show_bug.cgi?id=548868
52 files changed, 1932 insertions, 209 deletions
diff --git a/features/org.eclipse.oomph.p2-feature/feature.xml b/features/org.eclipse.oomph.p2-feature/feature.xml index 6fd265ebb..cd1901144 100644 --- a/features/org.eclipse.oomph.p2-feature/feature.xml +++ b/features/org.eclipse.oomph.p2-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.oomph.p2" label="%featureName" - version="1.12.0.qualifier" + version="1.13.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.oomph.license" license-feature-version="0.0.0"> diff --git a/features/org.eclipse.oomph.p2-feature/pom.xml b/features/org.eclipse.oomph.p2-feature/pom.xml index bb2f0de3d..8a92153c2 100644 --- a/features/org.eclipse.oomph.p2-feature/pom.xml +++ b/features/org.eclipse.oomph.p2-feature/pom.xml @@ -20,6 +20,6 @@ </parent> <groupId>org.eclipse.oomph.features</groupId> <artifactId>org.eclipse.oomph.p2</artifactId> - <version>1.12.0-SNAPSHOT</version> + <version>1.13.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/features/org.eclipse.oomph.setup.core-feature/feature.xml b/features/org.eclipse.oomph.setup.core-feature/feature.xml index ddf622dd2..2ddc39fe0 100644 --- a/features/org.eclipse.oomph.setup.core-feature/feature.xml +++ b/features/org.eclipse.oomph.setup.core-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.oomph.setup.core" label="%featureName" - version="1.13.0.qualifier" + version="1.14.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.oomph.license" license-feature-version="0.0.0"> diff --git a/features/org.eclipse.oomph.setup.core-feature/pom.xml b/features/org.eclipse.oomph.setup.core-feature/pom.xml index d91e4bc72..d1a59242b 100644 --- a/features/org.eclipse.oomph.setup.core-feature/pom.xml +++ b/features/org.eclipse.oomph.setup.core-feature/pom.xml @@ -20,6 +20,6 @@ </parent> <groupId>org.eclipse.oomph.features</groupId> <artifactId>org.eclipse.oomph.setup.core</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/features/org.eclipse.oomph.setup.installer-feature/feature.xml b/features/org.eclipse.oomph.setup.installer-feature/feature.xml index a122db8ae..ba4d4a8ce 100644 --- a/features/org.eclipse.oomph.setup.installer-feature/feature.xml +++ b/features/org.eclipse.oomph.setup.installer-feature/feature.xml @@ -12,7 +12,7 @@ <feature id="org.eclipse.oomph.setup.installer" label="%featureName" - version="1.13.0.qualifier" + version="1.14.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.oomph.license" license-feature-version="0.0.0"> diff --git a/features/org.eclipse.oomph.setup.installer-feature/pom.xml b/features/org.eclipse.oomph.setup.installer-feature/pom.xml index b44355755..ccea827d9 100644 --- a/features/org.eclipse.oomph.setup.installer-feature/pom.xml +++ b/features/org.eclipse.oomph.setup.installer-feature/pom.xml @@ -22,7 +22,7 @@ Eike Stepper - initial API and implementation <groupId>org.eclipse.oomph.features</groupId> <artifactId>org.eclipse.oomph.setup.installer</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> <build> diff --git a/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF index 7396404bf..9ed40d187 100644 --- a/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.base.edit/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.base.edit;singleton:=true -Bundle-Version: 1.11.0.qualifier +Bundle-Version: 1.12.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.base.provider.BaseEditPlugin$Implementation Bundle-Vendor: %providerName @@ -12,6 +12,6 @@ Export-Package: org.eclipse.oomph.base.provider;version="1.5.0";x-internal:=true org.eclipse.oomph.edit;version="1.5.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.base;bundle-version="[1.11.0,2.0.0)";visibility:=reexport + org.eclipse.oomph.base;bundle-version="[1.12.0,2.0.0)";visibility:=reexport Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.base.edit diff --git a/plugins/org.eclipse.oomph.base.edit/pom.xml b/plugins/org.eclipse.oomph.base.edit/pom.xml index 610f14ba1..eba275282 100644 --- a/plugins/org.eclipse.oomph.base.edit/pom.xml +++ b/plugins/org.eclipse.oomph.base.edit/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.base.edit</artifactId> - <version>1.11.0-SNAPSHOT</version> + <version>1.12.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/BaseAdapterFactoryEditingDomain.java b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/BaseAdapterFactoryEditingDomain.java index 6ee57496d..a77a75b4f 100644 --- a/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/BaseAdapterFactoryEditingDomain.java +++ b/plugins/org.eclipse.oomph.base.edit/src/org/eclipse/oomph/edit/BaseAdapterFactoryEditingDomain.java @@ -23,6 +23,9 @@ import org.eclipse.emf.edit.command.PasteFromClipboardCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Map; /** @@ -30,6 +33,8 @@ import java.util.Map; */ public class BaseAdapterFactoryEditingDomain extends AdapterFactoryEditingDomain { + private LinkedList<CommandParameter> commandParameters = new LinkedList<CommandParameter>(); + public BaseAdapterFactoryEditingDomain(AdapterFactory adapterFactory, CommandStack commandStack) { super(adapterFactory, commandStack); @@ -45,40 +50,57 @@ public class BaseAdapterFactoryEditingDomain extends AdapterFactoryEditingDomain super(adapterFactory, commandStack, resourceSet); } + public List<CommandParameter> getCommandParameters() + { + return Collections.unmodifiableList(commandParameters); + } + + public void handledAdditions(Collection<?> collection) + { + } + @Override public Command createCommand(Class<? extends Command> commandClass, CommandParameter commandParameter) { - if (commandClass == CopyCommand.class) + commandParameters.push(commandParameter); + try { - Object owner = commandParameter.getOwner(); - if (owner instanceof URI || owner instanceof String) + if (commandClass == CopyCommand.class) { - return new IdentityCommand(owner); + Object owner = commandParameter.getOwner(); + if (owner instanceof URI || owner instanceof String) + { + return new IdentityCommand(owner); + } } - } - if (commandClass == PasteFromClipboardCommand.class) - { - Object owner = commandParameter.getOwner(); - Collection<Object> clipboard = getClipboard(); - Object feature = commandParameter.getFeature(); - int index = commandParameter.getIndex(); - Command primaryPasteCommand = new BasePasteFromClipboardCommand(this, owner, feature, clipboard, index, true); - if (!primaryPasteCommand.canExecute()) + if (commandClass == PasteFromClipboardCommand.class) { - BasePasteFromClipboardCommand alternativePasteCommand = new BasePasteFromClipboardCommand(this, owner, feature, clipboard, index, false); - if (alternativePasteCommand.canExecute()) + Object owner = commandParameter.getOwner(); + Collection<Object> clipboard = getClipboard(); + Object feature = commandParameter.getFeature(); + int index = commandParameter.getIndex(); + Command primaryPasteCommand = new BasePasteFromClipboardCommand(this, owner, feature, clipboard, index, true); + if (!primaryPasteCommand.canExecute()) { - primaryPasteCommand.dispose(); - return alternativePasteCommand; + BasePasteFromClipboardCommand alternativePasteCommand = new BasePasteFromClipboardCommand(this, owner, feature, clipboard, index, false); + if (alternativePasteCommand.canExecute()) + { + primaryPasteCommand.dispose(); + return alternativePasteCommand; + } + + alternativePasteCommand.dispose(); } - alternativePasteCommand.dispose(); + return primaryPasteCommand; } - return primaryPasteCommand; + return super.createCommand(commandClass, commandParameter); + } + finally + { + commandParameters.pop(); } - - return super.createCommand(commandClass, commandParameter); } } diff --git a/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF index dd636098a..de8aaf951 100644 --- a/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.base/META-INF/MANIFEST.MF @@ -2,16 +2,16 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.base;singleton:=true -Bundle-Version: 1.11.0.qualifier +Bundle-Version: 1.12.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.internal.base.BasePlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.base;version="1.11.0";x-internal:=true, - org.eclipse.oomph.base.impl;version="1.11.0";x-internal:=true, - org.eclipse.oomph.base.util;version="1.11.0";x-internal:=true, - org.eclipse.oomph.internal.base;version="1.11.0";x-internal:=true +Export-Package: org.eclipse.oomph.base;version="1.12.0";x-internal:=true, + org.eclipse.oomph.base.impl;version="1.12.0";x-internal:=true, + org.eclipse.oomph.base.util;version="1.12.0";x-internal:=true, + org.eclipse.oomph.internal.base;version="1.12.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.ecore;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, diff --git a/plugins/org.eclipse.oomph.base/pom.xml b/plugins/org.eclipse.oomph.base/pom.xml index c70a398c5..2f821c880 100644 --- a/plugins/org.eclipse.oomph.base/pom.xml +++ b/plugins/org.eclipse.oomph.base/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.base</artifactId> - <version>1.11.0-SNAPSHOT</version> + <version>1.12.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/util/BaseResourceFactoryImpl.java b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/util/BaseResourceFactoryImpl.java index 2b76b8a64..aea4411c8 100644 --- a/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/util/BaseResourceFactoryImpl.java +++ b/plugins/org.eclipse.oomph.base/src/org/eclipse/oomph/base/util/BaseResourceFactoryImpl.java @@ -46,7 +46,7 @@ public class BaseResourceFactoryImpl extends ResourceFactoryImpl @Override public Resource createResource(URI uri) { - BaseResourceImpl result = new BaseResourceImpl(uri); + BaseResource result = basicCreateResource(uri); result.setEncoding("UTF-8"); Map<Object, Object> defaultLoadOptions = result.getDefaultLoadOptions(); @@ -66,4 +66,9 @@ public class BaseResourceFactoryImpl extends ResourceFactoryImpl return result; } + protected BaseResource basicCreateResource(URI uri) + { + return new BaseResourceImpl(uri); + } + } // SetupResourceFactoryImpl diff --git a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF index 03ced3c76..37999e442 100644 --- a/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.p2.ui/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.p2.ui;singleton:=true -Bundle-Version: 1.10.0.qualifier +Bundle-Version: 1.11.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.p2.internal.ui.P2UIPlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.10.0";x-internal:=true +Export-Package: org.eclipse.oomph.p2.internal.ui;version="1.11.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.0.0,4.0.0)";resolution:=optional, org.eclipse.equinox.p2.core;bundle-version="[2.0.0,3.0.0)", @@ -17,9 +17,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.p2.repository;bundle-version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.artifact.repository;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.ui;bundle-version="[2.0.0,3.0.0)", - org.eclipse.oomph.ui;bundle-version="[1.10.0,2.0.0)", - org.eclipse.oomph.p2.core;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.p2.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.ui;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.p2.core;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, org.eclipse.ui;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";resolution:=optional, org.eclipse.ui.forms;bundle-version="[3.5.0,4.0.0)" diff --git a/plugins/org.eclipse.oomph.p2.ui/pom.xml b/plugins/org.eclipse.oomph.p2.ui/pom.xml index a8d8974e5..7123d4721 100644 --- a/plugins/org.eclipse.oomph.p2.ui/pom.xml +++ b/plugins/org.eclipse.oomph.p2.ui/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.p2.ui</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.11.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java index 8318deac6..9eb0f8ad9 100644 --- a/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java +++ b/plugins/org.eclipse.oomph.p2.ui/src/org/eclipse/oomph/p2/internal/ui/RepositoryExplorer.java @@ -78,6 +78,7 @@ import org.eclipse.equinox.p2.metadata.expression.IMatchExpression; import org.eclipse.equinox.p2.query.CollectionResult; import org.eclipse.equinox.p2.query.IQueryResult; import org.eclipse.equinox.p2.query.QueryUtil; +import org.eclipse.equinox.p2.repository.IRepositoryManager; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.jface.action.Action; @@ -1754,6 +1755,7 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler agent.flushRepositoryCaches(); IMetadataRepositoryManager repositoryManager = agent.getMetadataRepositoryManager(); + List<URI> originalKnownRepositories = Arrays.asList(repositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)); if (repositoryProvider == null || !repositoryProvider.getLocation().equals(location)) { disposeRepositoryProvider(); @@ -1797,6 +1799,17 @@ public class RepositoryExplorer extends ViewPart implements FilterHandler throw ex; } + finally + { + URI[] finalKnownRepositories = repositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); + for (URI uri : finalKnownRepositories) + { + if (!originalKnownRepositories.contains(uri)) + { + repositoryManager.removeRepository(uri); + } + } + } if (repository instanceof org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository) { diff --git a/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF index 7adb55ec9..5b412ce5b 100644 --- a/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.setup.core;singleton:=true -Bundle-Version: 1.13.0.qualifier +Bundle-Version: 1.14.0.qualifier Bundle-ClassPath: . Bundle-Name: %pluginName Bundle-Vendor: %providerName @@ -31,15 +31,15 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.p2.touchpoint.natives;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.updatesite;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)", - org.eclipse.oomph.base.edit;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)", org.eclipse.oomph.p2.core;bundle-version="[1.12.0,2.0.0)", - org.eclipse.oomph.setup;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.p2;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.setup;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.p2;bundle-version="[1.12.0,2.0.0)", org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)", org.eclipse.core.net;bundle-version="[1.2.0,2.0.0)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.oomph.setup.internal.core;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.internal.core.util;version="1.13.0";x-internal:=true +Export-Package: org.eclipse.oomph.setup.internal.core;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.internal.core.util;version="1.14.0";x-internal:=true Bundle-Activator: org.eclipse.oomph.setup.internal.core.SetupCorePlugin$Implementation Automatic-Module-Name: org.eclipse.oomph.setup.core diff --git a/plugins/org.eclipse.oomph.setup.core/pom.xml b/plugins/org.eclipse.oomph.setup.core/pom.xml index 305860647..566e656c9 100644 --- a/plugins/org.eclipse.oomph.setup.core/pom.xml +++ b/plugins/org.eclipse.oomph.setup.core/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.core</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StringFilterRegistry.java b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StringFilterRegistry.java index c2a66a656..15f935dcc 100644 --- a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StringFilterRegistry.java +++ b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StringFilterRegistry.java @@ -741,6 +741,26 @@ public class StringFilterRegistry } } }); + + registerFilter(new DocumentedStringFilter() + { + public String getName() + { + return "not"; + } + + @Override + public String getDescription() + { + return "The boolean logical negation, i.e., 'false' if the value is 'true', and 'true' if the value is 'false' (or anything else)."; + } + + public String filter(String value) + { + return "true".equalsIgnoreCase(value) ? "false" : "true"; + } + }); + } public static void main(String[] args) throws UnsupportedEncodingException diff --git a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/util/SetupCoreUtil.java b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/util/SetupCoreUtil.java index be3f0b85c..5412e8c4f 100644 --- a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/util/SetupCoreUtil.java +++ b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/util/SetupCoreUtil.java @@ -16,18 +16,30 @@ import org.eclipse.oomph.base.BaseFactory; import org.eclipse.oomph.base.BasePackage; import org.eclipse.oomph.base.ModelElement; import org.eclipse.oomph.base.util.ArchiveResourceImpl; +import org.eclipse.oomph.base.util.BaseResource; import org.eclipse.oomph.base.util.BaseResourceFactoryImpl; +import org.eclipse.oomph.base.util.BaseResourceImpl; import org.eclipse.oomph.base.util.BaseUtil; import org.eclipse.oomph.internal.setup.SetupProperties; +import org.eclipse.oomph.p2.P2Factory; +import org.eclipse.oomph.p2.P2Package; +import org.eclipse.oomph.p2.Repository; +import org.eclipse.oomph.p2.Requirement; import org.eclipse.oomph.p2.core.P2Util; import org.eclipse.oomph.preferences.impl.PreferencesURIHandlerImpl; import org.eclipse.oomph.preferences.util.PreferencesUtil; import org.eclipse.oomph.setup.AnnotationConstants; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.Parameter; import org.eclipse.oomph.setup.Scope; +import org.eclipse.oomph.setup.SetupFactory; import org.eclipse.oomph.setup.internal.core.SetupContext; import org.eclipse.oomph.setup.internal.core.SetupCorePlugin; import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl.AuthorizationHandler; import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl.AuthorizationHandlerImpl; +import org.eclipse.oomph.setup.p2.P2Task; +import org.eclipse.oomph.setup.p2.SetupP2Factory; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.oomph.setup.util.SetupUtil; import org.eclipse.oomph.util.IORuntimeException; import org.eclipse.oomph.util.IOUtil; @@ -61,8 +73,10 @@ import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.resource.URIHandler; import org.eclipse.emf.ecore.resource.impl.ArchiveURIHandlerImpl; import org.eclipse.emf.ecore.resource.impl.FileURIHandlerImpl; +import org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMIException; import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl; import org.eclipse.core.runtime.IStatus; @@ -142,6 +156,78 @@ public final class SetupCoreUtil AUTHORIZATION_HANDLER = new AuthorizationHandlerImpl(uiServices, securePreferences); } + private static Resource.Factory MARKET_PLACE_LISTING_RESOURCE_FACTORY = new BaseResourceFactoryImpl() + { + @Override + protected BaseResource basicCreateResource(URI uri) + { + return new BaseResourceImpl(uri) + { + @Override + public void load(Map<?, ?> options) throws IOException + { + Macro macro = SetupFactory.eINSTANCE.createMacro(); + MarketPlaceListing marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, getURIConverter()); + if (marketPlaceListing != null) + { + IOException exception = marketPlaceListing.getException(); + if (exception != null) + { + getErrors().add(new XMIException(exception)); + } + else + { + macro.setLabel(marketPlaceListing.getLabel()); + macro.setName(marketPlaceListing.getListing().lastSegment()); + macro.setDescription("<a href='" + marketPlaceListing.getListing() + "?'>" + marketPlaceListing.getLabel() + "</a>"); + P2Task p2Task = SetupP2Factory.eINSTANCE.createP2Task(); + p2Task.setLabel(marketPlaceListing.getLabel()); + EList<Parameter> parameters = macro.getParameters(); + List<Requirement> requirements = marketPlaceListing.getRequirements(); + for (Requirement requirement : requirements) + { + if (!MarketPlaceListing.isRequired(requirement)) + { + String name = requirement.getName(); + if (name.endsWith(Requirement.FEATURE_SUFFIX)) + { + name = name.substring(0, name.length() - Requirement.FEATURE_SUFFIX.length()); + } + + name += ".enabled"; + + Parameter parameter = SetupFactory.eINSTANCE.createParameter(); + parameter.setName(name); + parameter.setDescription("Whether to include '" + name + "' in the installation"); + parameter.setDefaultValue(MarketPlaceListing.isSelected(requirement) ? "true" : "false"); + parameters.add(parameter); + + Annotation featureSubstitutionAnnotation = BaseFactory.eINSTANCE.createAnnotation(AnnotationConstants.ANNOTATION_FEATURE_SUBSTITUTION); + featureSubstitutionAnnotation.getDetails().put(P2Package.Literals.REQUIREMENT__OPTIONAL.getName(), "${" + name + "|not}"); + featureSubstitutionAnnotation.getDetails().put(P2Package.Literals.REQUIREMENT__GREEDY.getName(), "${" + name + "}"); + requirement.getAnnotations().add(featureSubstitutionAnnotation); + } + } + + p2Task.getRequirements().addAll(requirements); + + URI updateSite = marketPlaceListing.getUpdateSite(); + if (updateSite != null) + { + Repository repository = P2Factory.eINSTANCE.createRepository(marketPlaceListing.getUpdateSite().toString()); + p2Task.getRepositories().add(repository); + } + + macro.getSetupTasks().add(p2Task); + } + } + + getContents().add(macro); + } + }; + } + }; + private SetupCoreUtil() { } @@ -176,7 +262,39 @@ public final class SetupCoreUtil private static void configureResourceSet(final ResourceSet resourceSet, boolean configureURIMappings) { - resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().putAll(RESOURCE_FACTORY_REGISTRY.getExtensionToFactoryMap()); + final Resource.Factory.Registry resourceFactoryRegistry = resourceSet.getResourceFactoryRegistry(); + + final Resource.Factory.Registry specializedResourceFactoryRegistry = new ResourceFactoryRegistryImpl() + { + @Override + protected Resource.Factory delegatedGetFactory(URI uri, String contentTypeIdentifier) + { + if (MarketPlaceListing.isMarketPlaceListing(uri)) + { + return MARKET_PLACE_LISTING_RESOURCE_FACTORY; + } + + return resourceFactoryRegistry.getFactory(uri, contentTypeIdentifier); + } + + @Override + protected URIConverter getURIConverter() + { + return resourceSet.getURIConverter(); + } + + @Override + protected Map<?, ?> getContentDescriptionOptions() + { + Map<?, ?> contentDescriptionOptions = super.getContentDescriptionOptions(); + Map<Object, Object> result = new HashMap<Object, Object>(contentDescriptionOptions); + result.putAll(resourceSet.getLoadOptions()); + return result; + } + }; + + specializedResourceFactoryRegistry.getExtensionToFactoryMap().putAll(RESOURCE_FACTORY_REGISTRY.getExtensionToFactoryMap()); + resourceSet.setResourceFactoryRegistry(specializedResourceFactoryRegistry); URIConverter uriConverter = resourceSet.getURIConverter(); Map<URI, URI> uriMap = uriConverter.getURIMap(); @@ -191,7 +309,7 @@ public final class SetupCoreUtil { uriConverter = resourceSet.getURIConverter(); packageRegistry = resourceSet.getPackageRegistry(); - resourceFactoryRegistry = resourceSet.getResourceFactoryRegistry(); + resourceFactoryRegistry = specializedResourceFactoryRegistry; loadOptions = resourceSet.getLoadOptions(); } diff --git a/plugins/org.eclipse.oomph.setup.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.edit/META-INF/MANIFEST.MF index af5032bd9..074c5d989 100644 --- a/plugins/org.eclipse.oomph.setup.edit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.edit/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.setup.edit;singleton:=true -Bundle-Version: 1.13.0.qualifier +Bundle-Version: 1.14.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.setup.provider.SetupEditPlugin$Implementation Bundle-Vendor: %providerName @@ -10,8 +10,8 @@ Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.oomph.setup.provider;version="1.5.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", - org.eclipse.oomph.setup;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.base.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport + org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.setup.edit diff --git a/plugins/org.eclipse.oomph.setup.edit/pom.xml b/plugins/org.eclipse.oomph.setup.edit/pom.xml index 358e657a8..138c3e483 100644 --- a/plugins/org.eclipse.oomph.setup.edit/pom.xml +++ b/plugins/org.eclipse.oomph.setup.edit/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.edit</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java index 7ed814f00..ba0ebb4bd 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/CompoundTaskItemProvider.java @@ -17,6 +17,7 @@ import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.domain.EditingDomain; @@ -224,6 +225,12 @@ public class CompoundTaskItemProvider extends SetupTaskItemProvider } @Override + protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) + { + return SetupTaskContainerItemProvider.createAddCommandWithMacroTaskSupport(domain, owner, feature, collection, index); + } + + @Override protected Command factorAddCommand(EditingDomain domain, CommandParameter commandParameter) { return super.factorAddCommand(domain, SetupTaskContainerItemProvider.transformCommandParameter(domain, commandParameter)); diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java index 28ad57aba..9b072a9dc 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/MacroItemProvider.java @@ -137,7 +137,7 @@ public class MacroItemProvider extends ScopeItemProvider public String getText(Object object) { String label = ((Macro)object).getLabel(); - return label == null || label.length() == 0 ? getString("_UI_Fragment_type") : label; + return label == null || label.length() == 0 ? getString("_UI_Macro_type") : label; } /** diff --git a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java index 390d9dcbd..1d9efb02b 100644 --- a/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.edit/src/org/eclipse/oomph/setup/provider/SetupTaskContainerItemProvider.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.provider; import org.eclipse.oomph.base.provider.ModelElementItemProvider; +import org.eclipse.oomph.edit.BaseAdapterFactoryEditingDomain; import org.eclipse.oomph.setup.Argument; import org.eclipse.oomph.setup.InstallationTask; import org.eclipse.oomph.setup.Macro; @@ -31,6 +32,7 @@ import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; @@ -247,6 +249,30 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider return super.factorAddCommand(domain, transformCommandParameter(domain, commandParameter)); } + @Override + protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) + { + return createAddCommandWithMacroTaskSupport(domain, owner, feature, collection, index); + } + + public static Command createAddCommandWithMacroTaskSupport(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, + int index) + { + return new AddCommand(domain, owner, feature, collection, index) + { + @Override + public void doExecute() + { + super.doExecute(); + + if (domain instanceof BaseAdapterFactoryEditingDomain) + { + ((BaseAdapterFactoryEditingDomain)domain).handledAdditions(collection); + } + } + }; + } + public static CommandParameter transformCommandParameter(EditingDomain domain, CommandParameter commandParameter) { Collection<?> collection = commandParameter.getCollection(); @@ -264,48 +290,7 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider Macro macro = (Macro)unwrappedObject; if (macro.eResource() != null) { - MacroTask macroTask = SetupFactory.eINSTANCE.createMacroTask(); - macroTask.setMacro(macro); - - String id = getID(macro.getName()); - String uniqueID = id; - Resource resource = eOwner.eResource(); - if (resource != null) - { - int count = 0; - while (resource.getEObject(uniqueID) != null) - { - if (Character.isDigit(id.charAt(id.length() - 1))) - { - uniqueID = id + "_" + ++count; - } - else - { - uniqueID = id + ++count; - } - } - } - - macroTask.setID(uniqueID); - - EList<Parameter> parameters = macro.getParameters(); - if (!parameters.isEmpty()) - { - List<Argument> arguments = macroTask.getArguments(); - for (Parameter parameter : parameters) - { - Argument argument = SetupFactory.eINSTANCE.createArgument(); - argument.setParameter(parameter); - if (parameter.getDefaultValue() == null) - { - String parameterName = parameter.getName(); - argument.setValue(parameterName + "_value"); - } - - arguments.add(argument); - } - } - + MacroTask macroTask = createMacroTask((SetupTaskContainer)eOwner, macro); augmentedCollection.add(macroTask); } else @@ -350,4 +335,51 @@ public class SetupTaskContainerItemProvider extends ModelElementItemProvider return implode; } + + public static MacroTask createMacroTask(SetupTaskContainer setupTaskContainer, Macro macro) + { + MacroTask macroTask = SetupFactory.eINSTANCE.createMacroTask(); + macroTask.setMacro(macro); + + String id = getID(macro.getName()); + String uniqueID = id; + Resource resource = setupTaskContainer.eResource(); + if (resource != null) + { + int count = 0; + while (resource.getEObject(uniqueID) != null) + { + if (Character.isDigit(id.charAt(id.length() - 1))) + { + uniqueID = id + "_" + ++count; + } + else + { + uniqueID = id + ++count; + } + } + } + + macroTask.setID(uniqueID); + + EList<Parameter> parameters = macro.getParameters(); + if (!parameters.isEmpty()) + { + List<Argument> arguments = macroTask.getArguments(); + for (Parameter parameter : parameters) + { + Argument argument = SetupFactory.eINSTANCE.createArgument(); + argument.setParameter(parameter); + if (parameter.getDefaultValue() == null) + { + String parameterName = parameter.getName(); + argument.setValue(parameterName + "_value"); + } + + arguments.add(argument); + } + } + + return macroTask; + } } diff --git a/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF index 8dc1806b0..154ddb300 100644 --- a/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.editor/META-INF/MANIFEST.MF @@ -19,8 +19,8 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", org.eclipse.oomph.predicates.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.resources.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)", - org.eclipse.oomph.setup.edit;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.ui;bundle-version="[1.13.0,2.0.0)", + org.eclipse.oomph.setup.edit;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.ui;bundle-version="[1.14.0,2.0.0)", org.eclipse.oomph.setup.sync;bundle-version="[1.10.0,2.0.0)", org.eclipse.oomph.workingsets.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.workingsets.editor;bundle-version="[1.10.0,2.0.0)", @@ -29,9 +29,9 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", org.eclipse.equinox.p2.metadata;bundle-version="[2.0.0,3.0.0)", org.eclipse.oomph.ui;bundle-version="[1.11.0,2.0.0)", org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)";visibility:=reexport, - org.eclipse.oomph.base.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.p2.edit;bundle-version="[1.10.0,2.0.0)", + org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.p2.edit;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.p2.ui;bundle-version="[1.10.0,2.0.0)" + org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.setup.editor diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java index 07d677903..dab1c5511 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupActionBarContributor.java @@ -35,6 +35,7 @@ import org.eclipse.oomph.setup.VariableTask; import org.eclipse.oomph.setup.WorkspaceTask; import org.eclipse.oomph.setup.impl.DynamicSetupTaskImpl; import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.oomph.setup.presentation.SetupEditor.BrowserDialog; import org.eclipse.oomph.setup.ui.SetupEditorSupport; import org.eclipse.oomph.setup.ui.SetupUIPlugin; @@ -96,6 +97,7 @@ import org.eclipse.jface.action.Separator; import org.eclipse.jface.action.SubContributionItem; import org.eclipse.jface.bindings.Binding; import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; @@ -142,6 +144,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Queue; import java.util.Set; @@ -334,23 +337,54 @@ public class SetupActionBarContributor extends OomphEditingDomainActionBarContri { ResourceSet resourceSet = domain.getResourceSet(); EList<Resource> resources = resourceSet.getResources(); - List<Resource> originalResources = new ArrayList<Resource>(resources); - super.run(); - synchronized (resourceSet) + final Set<URI> loadedURIs = new LinkedHashSet<URI>(); + LoadResourceDialog loadResourceDialog = new LoadResourceDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), domain) + { + @Override + public List<URI> getURIs() + { + List<URI> uris = super.getURIs(); + for (ListIterator<URI> it = uris.listIterator(); it.hasNext();) + { + URI uri = it.next(); + MarketPlaceListing marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, domain.getResourceSet().getURIConverter()); + if (marketPlaceListing != null) + { + it.set(marketPlaceListing.getListing()); + } + } + + loadedURIs.clear(); + loadedURIs.addAll(uris); + + return uris; + } + }; + + if (loadResourceDialog.open() == IDialogConstants.OK_ID) { - List<Resource> finalResources = new ArrayList<Resource>(resources); - finalResources.removeAll(originalResources); - if (!finalResources.isEmpty()) + synchronized (resourceSet) { int index = 0; - for (Resource resource : finalResources) + List<Resource> loadedResources = new ArrayList<Resource>(); + for (URI uri : loadedURIs) { - resources.move(++index, resource); + Resource resource = resourceSet.getResource(uri, false); + if (resource != null) + { + loadedResources.add(resource); + resources.move(++index, resource); + } } - if (!toggleViewerInputAction.isChecked()) + if (!loadedResources.isEmpty()) { - toggleViewerInputAction.run(); + if (!toggleViewerInputAction.isChecked()) + { + toggleViewerInputAction.run(); + } + + toggleViewerInputAction.select(new StructuredSelection(loadedResources)); } } } @@ -1699,6 +1733,11 @@ public class SetupActionBarContributor extends OomphEditingDomainActionBarContri setupEditor.toggleInput(); } + public void select(ISelection selection) + { + setupEditor.selectionViewer.setSelection(selection, true); + } + public void setActiveWorkbenchPart(IWorkbenchPart workbenchPart) { if (workbenchPart instanceof SetupEditor) diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java index a2035cec4..d46f6f2b1 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/SetupEditor.java @@ -49,6 +49,7 @@ import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl; import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl.AuthorizationHandler.Authorization; import org.eclipse.oomph.setup.internal.core.util.ResourceMirror; import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.oomph.setup.presentation.SetupActionBarContributor.ToggleViewerInputAction; import org.eclipse.oomph.setup.provider.PreferenceTaskItemProvider; import org.eclipse.oomph.setup.provider.SetupItemProviderAdapterFactory; @@ -56,6 +57,7 @@ import org.eclipse.oomph.setup.ui.SetupEditorSupport; import org.eclipse.oomph.setup.ui.SetupLabelProvider; import org.eclipse.oomph.setup.ui.SetupTransferSupport; import org.eclipse.oomph.setup.ui.ToolTipLabelProvider; +import org.eclipse.oomph.setup.ui.actions.ConfigureMarketPlaceListingAction; import org.eclipse.oomph.ui.DockableDialog; import org.eclipse.oomph.ui.UIUtil; import org.eclipse.oomph.util.OS; @@ -111,7 +113,9 @@ import org.eclipse.emf.ecore.util.InternalEList; import org.eclipse.emf.edit.EMFEditPlugin; import org.eclipse.emf.edit.command.AbstractOverrideableCommand; import org.eclipse.emf.edit.command.AddCommand; +import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.command.CopyCommand; +import org.eclipse.emf.edit.command.DragAndDropCommand; import org.eclipse.emf.edit.command.DragAndDropFeedback; import org.eclipse.emf.edit.command.RemoveCommand; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; @@ -213,6 +217,7 @@ import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.LocationEvent; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.dnd.DND; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; @@ -1275,6 +1280,23 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } @Override + public Object getImage(Object object) + { + Resource resource = (Resource)object; + URI uri = resource.getURI(); + ResourceSet resourceSet = resource.getResourceSet(); + if (uri != null && resourceSet != null) + { + if (MarketPlaceListing.getMarketPlaceListing(uri, resourceSet.getURIConverter()) != null) + { + return SetupEditorPlugin.INSTANCE.getImage("marketplace16.png"); + } + } + + return super.getImage(object); + } + + @Override public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) { if (itemPropertyDescriptors == null) @@ -1351,38 +1373,51 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr { @Override protected Command createDragAndDropCommand(EditingDomain domain, Object owner, float location, int operations, int operation, - final Collection<?> collection) + Collection<?> collection) { + final List<CommandParameter> commandParameters = domain instanceof OomphEditingDomain + ? new ArrayList<CommandParameter>(((OomphEditingDomain)domain).getCommandParameters()) + : Collections.<CommandParameter> emptyList(); + + final Set<URI> uris = new LinkedHashSet<URI>(); + for (Object object : collection) + { + if (object instanceof URI) + { + URI uri = (URI)object; + MarketPlaceListing marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, domain.getResourceSet().getURIConverter()); + uris.add(marketPlaceListing == null ? uri : marketPlaceListing.getListing()); + } + else + { + return UnexecutableCommand.INSTANCE; + } + } + final ResourceSet resourceSet = (ResourceSet)owner; class LoadResourceCommand extends AbstractOverrideableCommand implements AbstractCommand.NonDirtying, DragAndDropFeedback { + protected List<Resource> resources; + protected LoadResourceCommand(EditingDomain domain) { super(domain); } - protected List<Resource> resources; - @Override protected boolean prepare() { - for (Object object : collection) - { - if (!(object instanceof URI)) - { - return false; - } - } - return true; + return !uris.isEmpty(); } @Override public void doExecute() { resources = new ArrayList<Resource>(); - for (Object object : collection) + int index = 1; + Macro macro = null; + for (URI uri : uris) { - URI uri = (URI)object; Resource resource = resourceSet.getResource(uri, false); if (resource == null) { @@ -1398,15 +1433,46 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr if (resource != null) { + macro = (Macro)EcoreUtil.getObjectByType(resource.getContents(), SetupPackage.Literals.MACRO); + EList<Resource> resourceSetResources = resourceSet.getResources(); if (resourceSetResources.indexOf(resource) != 0) { - resourceSetResources.move(1, resource); + resourceSetResources.move(index++, resource); } resources.add(resource); } } + + if (macro != null && !commandParameters.isEmpty()) + { + CommandParameter commandParameter = commandParameters.get(commandParameters.size() - 1); + final Object feature = commandParameter.getFeature(); + final Object rootOwner = commandParameter.getOwner(); + final Macro finalMacro = macro; + UIUtil.asyncExec(getContainer(), new Runnable() + { + public void run() + { + // Drop the macro onto the original owner. + float location = 0.5f; + int operations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + int operation = DND.DROP_LINK; + if (feature instanceof DragAndDropCommand.Detail) + { + DragAndDropCommand.Detail detail = (DragAndDropCommand.Detail)feature; + location = detail.location; + operations = detail.operations; + operation = detail.operation; + } + + Command dragAndDropCommand = DragAndDropCommand.create(domain, rootOwner, location, operations, operation, + Collections.singleton(finalMacro)); + domain.getCommandStack().execute(dragAndDropCommand); + } + }); + } } @Override @@ -1488,7 +1554,27 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } }; - editingDomain = new OomphEditingDomain(adapterFactory, editingDomain.getCommandStack(), readOnlyMap, SetupTransferSupport.USER_RESOLVING_DELEGATES); + editingDomain = new OomphEditingDomain(adapterFactory, editingDomain.getCommandStack(), readOnlyMap, SetupTransferSupport.USER_RESOLVING_DELEGATES) + { + @Override + public void handledAdditions(final Collection<?> collection) + { + UIUtil.asyncExec(new Runnable() + { + public void run() + { + for (Object object : collection) + { + if (object instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)object; + ConfigureMarketPlaceListingAction.configure(getSite().getShell(), editingDomain, macroTask); + } + } + } + }); + } + }; // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus. // @@ -4835,7 +4921,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr * <!-- end-user-doc --> * @generated */ - protected void doSaveAs(URI uri, IEditorInput editorInput) + protected void doSaveAsGen(URI uri, IEditorInput editorInput) { editingDomain.getResourceSet().getResources().get(0).setURI(uri); setInputWithNotify(editorInput); @@ -4845,6 +4931,12 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr doSave(progressMonitor); } + protected void doSaveAs(URI uri, IEditorInput editorInput) + { + editingDomain.getResourceToReadOnlyMap().remove(editingDomain.getResourceSet().getResources().get(0)); + doSaveAsGen(uri, editorInput); + } + /** * <!-- begin-user-doc --> * <!-- end-user-doc --> @@ -4878,6 +4970,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr Resource resource = editingDomain.getResourceSet().getResources().get(0); selectionViewer.setInput(resource); + getActionBarContributor().getToggleViewerInputAction().setChecked(false); } else if (input instanceof Resource) { @@ -4891,6 +4984,7 @@ public class SetupEditor extends MultiPageEditorPart implements IEditingDomainPr } selectionViewer.setInput(loadingResourceSetInput); + getActionBarContributor().getToggleViewerInputAction().setChecked(true); } else if (input == loadingResourceSetInput) { diff --git a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/handlers/RefreshCacheHandler.java b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/handlers/RefreshCacheHandler.java index 4ac13d59f..bba35942b 100644 --- a/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/handlers/RefreshCacheHandler.java +++ b/plugins/org.eclipse.oomph.setup.editor/src/org/eclipse/oomph/setup/presentation/handlers/RefreshCacheHandler.java @@ -11,6 +11,7 @@ package org.eclipse.oomph.setup.presentation.handlers; import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.oomph.setup.presentation.SetupEditorPlugin; import org.eclipse.emf.common.util.URI; @@ -37,6 +38,7 @@ public class RefreshCacheHandler extends AbstractDropdownItemHandler try { Set<? extends URI> uris = ECFURIHandlerImpl.clearExpectedETags(); + MarketPlaceListing.flush(); Job mirror = ECFURIHandlerImpl.mirror(uris); IWorkbench workbench = PlatformUI.getWorkbench(); IProgressService progressService = workbench.getProgressService(); diff --git a/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF index 9524fdf44..24dab7958 100644 --- a/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.installer/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.setup.installer;singleton:=true -Bundle-Version: 1.13.0.qualifier +Bundle-Version: 1.14.0.qualifier Bundle-ClassPath: . Bundle-Name: %pluginName Bundle-Vendor: %providerName @@ -10,9 +10,9 @@ Bundle-Activator: org.eclipse.oomph.setup.internal.installer.SetupInstallerPlugi Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)", org.eclipse.emf.edit.ui;bundle-version="[2.10.0,3.0.0)", - org.eclipse.oomph.setup;bundle-version="[1.13.0,2.0.0)", - org.eclipse.oomph.setup.edit;bundle-version="[1.13.0,2.0.0)", - org.eclipse.oomph.setup.ui;bundle-version="[1.13.0,2.0.0)", + org.eclipse.oomph.setup;bundle-version="[1.14.0,2.0.0)", + org.eclipse.oomph.setup.edit;bundle-version="[1.14.0,2.0.0)", + org.eclipse.oomph.setup.ui;bundle-version="[1.14.0,2.0.0)", org.eclipse.equinox.p2.operations;bundle-version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.metadata;bundle-version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.core;bundle-version="[2.0.0,3.0.0)", @@ -23,9 +23,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.p2.console;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.engine;bundle-version="[2.2.0,3.0.0)", org.eclipse.oomph.ui;bundle-version="[1.11.0,2.0.0)", - org.eclipse.oomph.p2.ui;bundle-version="[1.10.0,2.0.0)", - org.eclipse.oomph.setup.p2;bundle-version="[1.11.0,2.0.0)", - org.eclipse.oomph.setup.core;bundle-version="[1.13.0,2.0.0)", + org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)", + org.eclipse.oomph.setup.p2;bundle-version="[1.12.0,2.0.0)", + org.eclipse.oomph.setup.core;bundle-version="[1.14.0,2.0.0)", org.eclipse.oomph.jreinfo.ui;bundle-version="[1.10.0,2.0.0)", org.eclipse.help;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.net;bundle-version="[1.0.0,2.0.0)", @@ -34,5 +34,5 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.equinox.security.ui;bundle-version="[1.1.0,2.0.0)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.oomph.setup.internal.installer;version="1.13.0";x-internal:=true +Export-Package: org.eclipse.oomph.setup.internal.installer;version="1.14.0";x-internal:=true Automatic-Module-Name: org.eclipse.oomph.setup.installer diff --git a/plugins/org.eclipse.oomph.setup.installer/pom.xml b/plugins/org.eclipse.oomph.setup.installer/pom.xml index afe9d6ad0..012c1f009 100644 --- a/plugins/org.eclipse.oomph.setup.installer/pom.xml +++ b/plugins/org.eclipse.oomph.setup.installer/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.installer</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java index bf1f2d3ca..487135266 100644 --- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java +++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/ProductPage.java @@ -47,6 +47,7 @@ import org.eclipse.oomph.setup.ui.SetupTransferSupport; import org.eclipse.oomph.setup.ui.SetupUIPlugin; import org.eclipse.oomph.setup.ui.wizards.CatalogSelector; import org.eclipse.oomph.setup.ui.wizards.ConfigurationProcessor; +import org.eclipse.oomph.setup.ui.wizards.MarketPlaceListingProcessor; import org.eclipse.oomph.setup.ui.wizards.ProjectPage; import org.eclipse.oomph.setup.ui.wizards.SetupWizard; import org.eclipse.oomph.setup.ui.wizards.SetupWizard.IndexLoader; @@ -827,6 +828,19 @@ public class ProductPage extends SetupWizardPage SetupWizard setupWizard = getWizard(); setupWizard.setConfigurationResources(resources); + MarketPlaceListingProcessor marketPlaceListingProcessor = new MarketPlaceListingProcessor(setupWizard); + if (marketPlaceListingProcessor.isMarketPlaceListing()) + { + marketPlaceListingProcessor.processMarketPlaceListing(); + IStatus status = marketPlaceListingProcessor.getStatus(); + if (!status.isOK()) + { + new StatusDialog(getShell(), "Marketplace Listing Problems", null, status, Diagnostic.ERROR).open(); + } + + return; + } + ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(getWizard()) { @Override diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SelfUpdate.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SelfUpdate.java index b8f36b2e7..67fefe475 100644 --- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SelfUpdate.java +++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SelfUpdate.java @@ -121,7 +121,7 @@ public class SelfUpdate { Agent agent = P2Util.getAgentManager().getCurrentAgent(); Profile profile = agent.getCurrentProfile(); - if (profile == null) + if (profile == null || profile.isSelfHosting()) { return null; } diff --git a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java index 6198bdc89..ff7d6cd66 100644 --- a/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java +++ b/plugins/org.eclipse.oomph.setup.installer/src/org/eclipse/oomph/setup/internal/installer/SimpleInstallerDialog.java @@ -11,6 +11,7 @@ */ package org.eclipse.oomph.setup.internal.installer; +import org.eclipse.oomph.internal.setup.SetupProperties; import org.eclipse.oomph.internal.ui.AccessUtil; import org.eclipse.oomph.internal.ui.FlatButton; import org.eclipse.oomph.internal.ui.ImageHoverButton; @@ -32,6 +33,7 @@ import org.eclipse.oomph.setup.internal.installer.SimpleInstallerMenu.InstallerM import org.eclipse.oomph.setup.internal.installer.SimpleMessageOverlay.ControlRelocator; import org.eclipse.oomph.setup.ui.SetupUIPlugin; import org.eclipse.oomph.setup.ui.wizards.ConfigurationProcessor; +import org.eclipse.oomph.setup.ui.wizards.MarketPlaceListingProcessor; import org.eclipse.oomph.setup.ui.wizards.ProjectPage; import org.eclipse.oomph.setup.ui.wizards.SetupWizard.SelectionMemento; import org.eclipse.oomph.ui.ErrorDialog; @@ -96,7 +98,9 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements private static final String UPDATE_MENU_ITEM_TEXT = "UPDATE"; - private static final String ADVANCED_MENU_ITEM_TEXT = "ADVANCED MODE..."; + private static final String ADVANCED_MENU_ITEM_TEXT = "ADVANCED MODE" + StringUtil.HORIZONTAL_ELLIPSIS; + + private static final String MARKET_PLACE_MENU_ITEM_TEXT = "MARKETPLACE" + StringUtil.HORIZONTAL_ELLIPSIS; private static final String ABOUT_MENU_ITEM_TEXT = "ABOUT"; @@ -110,6 +114,8 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements private static final boolean SHOW_BUNDLE_POOL_UI = PropertiesUtil.getProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION) == null || !AgentManager.BUNDLE_POOL_LOCATION_NONE.equalsIgnoreCase(PropertiesUtil.getProperty(AgentManager.PROP_BUNDLE_POOL_LOCATION)); + private static final boolean MARKETPLACE_MENU_ITEM_ENABLED = !"false".equals(PropertiesUtil.getProperty(SetupProperties.PROP_SETUP_INSTALLER_MARKETPLACE)); + private static Font defaultFont; private static Point defaultSize; @@ -171,42 +177,55 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements protected void applyConfiguration() { - ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(installer) + MarketPlaceListingProcessor marketPlaceListingProcessor = new MarketPlaceListingProcessor(installer); + if (marketPlaceListingProcessor.isMarketPlaceListing()) { - @Override - protected void handleSwitchToAdvancedMode() + marketPlaceListingProcessor.processMarketPlaceListing(); + IStatus status = marketPlaceListingProcessor.getStatus(); + if (!status.isOK()) { - switchToAdvancedMode(); + new StatusDialog(getShell(), "Marketplace Listing Problems", null, status, Diagnostic.ERROR).open(); } + } + else + { + ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(installer) + { + @Override + protected void handleSwitchToAdvancedMode() + { + switchToAdvancedMode(); + } - @Override - protected boolean applyEmptyProductVersion() + @Override + protected boolean applyEmptyProductVersion() + { + applyInstallation(); + return true; + } + + @Override + protected boolean applyProductVersion(ProductVersion productVersion) + { + applyInstallation(); + + productPage.handleFilter(""); + productPage.productSelected(productVersion.getProduct()); + variablePage.setProductVersion(productVersion); + return true; + } + }; + + if (configurationProcessor.processWorkspace()) { - applyInstallation(); - return true; + configurationProcessor.processInstallation(); } - @Override - protected boolean applyProductVersion(ProductVersion productVersion) + IStatus status = configurationProcessor.getStatus(); + if (!status.isOK()) { - applyInstallation(); - - productPage.handleFilter(""); - productPage.productSelected(productVersion.getProduct()); - variablePage.setProductVersion(productVersion); - return true; + new StatusDialog(getShell(), "Configuration Problems", null, status, Diagnostic.ERROR).open(); } - }; - - if (configurationProcessor.processWorkspace()) - { - configurationProcessor.processInstallation(); - } - - IStatus status = configurationProcessor.getStatus(); - if (!status.isOK()) - { - new StatusDialog(getShell(), "Configuration Problems", null, status, Diagnostic.ERROR).open(); } } @@ -540,6 +559,21 @@ public final class SimpleInstallerDialog extends AbstractSimpleDialog implements }); } + if (MARKETPLACE_MENU_ITEM_ENABLED) + { + SimpleInstallerMenu.InstallerMenuItem marketPlaceItem = new SimpleInstallerMenu.InstallerMenuItem(menu); + marketPlaceItem.setText(MARKET_PLACE_MENU_ITEM_TEXT); + marketPlaceItem.setToolTipText("Browse for marketplace listings and drag them onto the installer's title"); + marketPlaceItem.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + OS.INSTANCE.openSystemBrowser("https://marketplace.eclipse.org"); + } + }); + } + SimpleInstallerMenu.InstallerMenuItem aboutItem = new SimpleInstallerMenu.InstallerMenuItem(menu); aboutItem.setText(ABOUT_MENU_ITEM_TEXT); aboutItem.setToolTipText("Show information about this installer"); diff --git a/plugins/org.eclipse.oomph.setup.p2.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.p2.edit/META-INF/MANIFEST.MF index 37f0b3cb2..ab177c279 100644 --- a/plugins/org.eclipse.oomph.setup.p2.edit/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.p2.edit/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.setup.p2.edit;singleton:=true -Bundle-Version: 1.10.0.qualifier +Bundle-Version: 1.11.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.setup.p2.provider.SetupP2EditPlugin$Implementation Bundle-Vendor: %providerName @@ -10,10 +10,10 @@ Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.oomph.setup.p2.provider;version="1.5.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", - org.eclipse.oomph.setup.p2;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.p2;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.base.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.p2.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport + org.eclipse.oomph.base.edit;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.edit;bundle-version="[1.14.0,2.0.0)";visibility:=reexport Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.oomph.setup.p2.edit diff --git a/plugins/org.eclipse.oomph.setup.p2.edit/pom.xml b/plugins/org.eclipse.oomph.setup.p2.edit/pom.xml index 582a91f53..bf0f15ce2 100644 --- a/plugins/org.eclipse.oomph.setup.p2.edit/pom.xml +++ b/plugins/org.eclipse.oomph.setup.p2.edit/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.p2.edit</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.11.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.p2.edit/src/org/eclipse/oomph/setup/p2/provider/P2TaskItemProvider.java b/plugins/org.eclipse.oomph.setup.p2.edit/src/org/eclipse/oomph/setup/p2/provider/P2TaskItemProvider.java index 54dd135b3..75ebc20fe 100644 --- a/plugins/org.eclipse.oomph.setup.p2.edit/src/org/eclipse/oomph/setup/p2/provider/P2TaskItemProvider.java +++ b/plugins/org.eclipse.oomph.setup.p2.edit/src/org/eclipse/oomph/setup/p2/provider/P2TaskItemProvider.java @@ -11,18 +11,24 @@ package org.eclipse.oomph.setup.p2.provider; import org.eclipse.oomph.p2.P2Factory; +import org.eclipse.oomph.p2.Requirement; import org.eclipse.oomph.p2.provider.RequirementItemProvider; import org.eclipse.oomph.setup.p2.P2Task; import org.eclipse.oomph.setup.p2.SetupP2Package; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.oomph.setup.provider.SetupTaskItemProvider; import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.util.ResourceLocator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.command.DragAndDropCommand; import org.eclipse.emf.edit.domain.EditingDomain; @@ -265,13 +271,32 @@ public class P2TaskItemProvider extends SetupTaskItemProvider protected Command createAddCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Collection<?> collection, int index) { List<Object> filteredCollection = new ArrayList<Object>(); + List<Requirement> requirements = new ArrayList<Requirement>(); if (collection != null) { for (Object object : collection) { if (object instanceof URI) { - filteredCollection.add(P2Factory.eINSTANCE.createRepository(object.toString())); + URI uri = (URI)object; + Resource resource = owner.eResource(); + if (resource != null) + { + ResourceSet resourceSet = resource.getResourceSet(); + if (resourceSet != null) + { + URIConverter uriConverter = resourceSet.getURIConverter(); + MarketPlaceListing marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, uriConverter); + if (marketPlaceListing != null && marketPlaceListing.getUpdateSite() != null) + { + filteredCollection.add(P2Factory.eINSTANCE.createRepository(marketPlaceListing.getUpdateSite().toString())); + requirements.addAll(marketPlaceListing.getRequirements()); + continue; + } + } + } + + filteredCollection.add(P2Factory.eINSTANCE.createRepository(uri.toString())); } else { @@ -280,7 +305,17 @@ public class P2TaskItemProvider extends SetupTaskItemProvider } } - return super.createAddCommand(domain, owner, feature, filteredCollection, index); + Command result = super.createAddCommand(domain, owner, feature, filteredCollection, index); + if (!requirements.isEmpty()) + { + CompoundCommand compoundCommand = new CompoundCommand(CompoundCommand.MERGE_COMMAND_ALL); + compoundCommand.append(result); + compoundCommand + .append(createAddCommand(domain, owner, (EStructuralFeature)SetupP2Package.Literals.P2_TASK__REQUIREMENTS, requirements, CommandParameter.NO_INDEX)); + result = compoundCommand; + } + + return result; } /** diff --git a/plugins/org.eclipse.oomph.setup.p2/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.p2/META-INF/MANIFEST.MF index 374190876..f052a0f69 100644 --- a/plugins/org.eclipse.oomph.setup.p2/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.p2/META-INF/MANIFEST.MF @@ -2,20 +2,20 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.setup.p2;singleton:=true -Bundle-Version: 1.11.0.qualifier +Bundle-Version: 1.12.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.setup.internal.p2.SetupP2Plugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.setup.internal.p2;version="1.11.0";x-internal:=true, - org.eclipse.oomph.setup.p2;version="1.11.0";x-internal:=true, - org.eclipse.oomph.setup.p2.impl;version="1.11.0";x-internal:=true, - org.eclipse.oomph.setup.p2.util;version="1.11.0";x-internal:=true +Export-Package: org.eclipse.oomph.setup.internal.p2;version="1.12.0";x-internal:=true, + org.eclipse.oomph.setup.p2;version="1.12.0";x-internal:=true, + org.eclipse.oomph.setup.p2.impl;version="1.12.0";x-internal:=true, + org.eclipse.oomph.setup.p2.util;version="1.12.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.emf.ecore;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.oomph.p2.core;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, org.eclipse.equinox.p2.artifact.repository;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.console;bundle-version="[1.0.0,2.0.0)", org.eclipse.equinox.p2.core;bundle-version="[2.0.0,3.0.0)", diff --git a/plugins/org.eclipse.oomph.setup.p2/pom.xml b/plugins/org.eclipse.oomph.setup.p2/pom.xml index 7537f1ed1..756a314a1 100644 --- a/plugins/org.eclipse.oomph.setup.p2/pom.xml +++ b/plugins/org.eclipse.oomph.setup.p2/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.p2</artifactId> - <version>1.11.0-SNAPSHOT</version> + <version>1.12.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/util/MarketPlaceListing.java b/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/util/MarketPlaceListing.java new file mode 100644 index 000000000..7ffdbadd6 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.p2/src/org/eclipse/oomph/setup/p2/util/MarketPlaceListing.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2019 Ed Merks and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.p2.util; + +import org.eclipse.oomph.base.Annotation; +import org.eclipse.oomph.base.BaseFactory; +import org.eclipse.oomph.p2.P2Factory; +import org.eclipse.oomph.p2.Requirement; +import org.eclipse.oomph.util.IOUtil; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.emf.ecore.util.EcoreUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Ed Merks + */ +public class MarketPlaceListing +{ + private static final String MARKET_PLACE_ANNOTATION = "https://marketplace.eclipse.org"; + + private static final Pattern MARKET_PLACE_CONTENT_PATTERN = Pattern.compile("(https?://marketplace\\.eclipse\\.org/content/[^/?#]*+)"); + + private static final Pattern MARKET_PLACE_INSTALL_PATTERN = Pattern + .compile("https?://marketplace\\.eclipse\\.org/marketplace-client-intro\\?mpc_install=([0-9]+)"); + + private static final Pattern IU_PATTERN = Pattern.compile(" *<iu( ?[^>]*)>([^<]+)</iu>"); + + private static final Pattern UPDATE_URL_PATTERN = Pattern.compile(" *<updateurl>([^<]+)</updateurl>"); + + private static final Pattern NODE_PATTERN = Pattern.compile(" *<node.*name=\"([^\"]*)\".*url=\"([^\"]*)\".*>"); + + private static final Map<URI, MarketPlaceListing> MARKET_PLACE_LISTINGS = Collections.synchronizedMap(new WeakHashMap<URI, MarketPlaceListing>()); + + private final String label; + + private final URI updateSite; + + private final URI listing; + + private final IOException exception; + + private final List<Requirement> requirements = new ArrayList<Requirement>(); + + private MarketPlaceListing(URI uri, URIConverter uriConverter) + { + URI updateSite = null; + URI listing = null; + String label = uri.toString(); + InputStream inputStream = null; + IOException exception = null; + try + { + inputStream = uriConverter.createInputStream(uri); + List<String> lines = IOUtil.readLines(inputStream, "UTF-8"); + if (!lines.contains("<marketplace>")) + { + throw new IOException("Missing market place entry: " + (lines.isEmpty() ? "<no-content>" : lines.get(0))); + } + + for (String line : lines) + { + Matcher iuMatcher = IU_PATTERN.matcher(line); + if (iuMatcher.matches()) + { + String iu = iuMatcher.group(2); + Requirement requirement = P2Factory.eINSTANCE.createRequirement(iu.endsWith(Requirement.FEATURE_SUFFIX) ? iu : iu + Requirement.FEATURE_SUFFIX); + requirements.add(requirement); + + String attributes = iuMatcher.group(1); + if (attributes.contains("required=\"TRUE\"")) + { + setRequired(requirement); + } + + if (attributes.contains("selected=\"TRUE\"")) + { + setSelected(requirement); + } + } + + Matcher updateURLMatcher = UPDATE_URL_PATTERN.matcher(line); + if (updateURLMatcher.matches()) + { + updateSite = URI.createURI(updateURLMatcher.group(1)); + } + + Matcher nodeMatcher = NODE_PATTERN.matcher(line); + if (nodeMatcher.matches()) + { + label = nodeMatcher.group(1); + String listingValue = nodeMatcher.group(2); + if (listingValue.startsWith("http:")) + { + listingValue = "https:" + listingValue.substring("http:".length()); + } + + listing = URI.createURI(listingValue); + } + } + } + catch (IOException ex) + { + exception = ex; + listing = uri; + } + finally + { + IOUtil.closeSilent(inputStream); + } + + this.updateSite = updateSite; + this.listing = listing; + this.label = label; + this.exception = exception; + } + + public IOException getException() + { + return exception; + } + + public URI getUpdateSite() + { + return updateSite; + } + + public URI getListing() + { + return listing; + } + + public String getLabel() + { + return label; + } + + public List<Requirement> getRequirements() + { + return new ArrayList<Requirement>(EcoreUtil.copyAll(requirements)); + } + + public static boolean isRequired(Requirement requirement) + { + Annotation annotation = requirement.getAnnotation(MARKET_PLACE_ANNOTATION); + return annotation != null && "true".equals(annotation.getDetails().get("required")); + } + + private static void setRequired(Requirement requirement) + { + Annotation annotation = requirement.getAnnotation(MARKET_PLACE_ANNOTATION); + if (annotation == null) + { + annotation = BaseFactory.eINSTANCE.createAnnotation(); + annotation.setSource(MARKET_PLACE_ANNOTATION); + requirement.getAnnotations().add(annotation); + } + annotation.getDetails().put("required", "true"); + } + + public static boolean isSelected(Requirement requirement) + { + Annotation annotation = requirement.getAnnotation(MARKET_PLACE_ANNOTATION); + return annotation != null && "true".equals(annotation.getDetails().get("selected")); + } + + private static void setSelected(Requirement requirement) + { + Annotation annotation = requirement.getAnnotation(MARKET_PLACE_ANNOTATION); + if (annotation == null) + { + annotation = BaseFactory.eINSTANCE.createAnnotation(); + annotation.setSource(MARKET_PLACE_ANNOTATION); + requirement.getAnnotations().add(annotation); + } + annotation.getDetails().put("selected", "true"); + } + + public static boolean isMarketPlaceListing(URI uri) + { + return getMarketPlaceListingURI(uri) != null; + } + + public static MarketPlaceListing getMarketPlaceListing(URI uri, URIConverter uriConverter) + { + MarketPlaceListing marketPlaceListing = MARKET_PLACE_LISTINGS.get(uri); + if (marketPlaceListing == null) + { + URI marketPlaceListingURI = getMarketPlaceListingURI(uri); + if (marketPlaceListingURI != null) + { + marketPlaceListing = MARKET_PLACE_LISTINGS.get(marketPlaceListingURI); + if (marketPlaceListing == null) + { + marketPlaceListing = new MarketPlaceListing(marketPlaceListingURI, uriConverter); + MARKET_PLACE_LISTINGS.put(uri, marketPlaceListing); + MARKET_PLACE_LISTINGS.put(marketPlaceListingURI, marketPlaceListing); + MARKET_PLACE_LISTINGS.put(marketPlaceListing.getListing(), marketPlaceListing); + } + } + } + + return marketPlaceListing; + } + + public static void flush() + { + MARKET_PLACE_LISTINGS.clear(); + } + + private static URI getMarketPlaceListingURI(URI uri) + { + Matcher matcher = MARKET_PLACE_CONTENT_PATTERN.matcher(uri.toString()); + if (matcher.find()) + { + return URI.createURI(matcher.group(1) + "/api/p"); + } + + matcher = MARKET_PLACE_INSTALL_PATTERN.matcher(uri.toString()); + if (matcher.matches()) + { + return URI.createURI("https://marketplace.eclipse.org/node/" + matcher.group(1) + "/api/p"); + } + + return null; + } +} diff --git a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF index 165bb1940..c8ca4bed5 100644 --- a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF @@ -2,17 +2,17 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.oomph.setup.ui;singleton:=true -Bundle-Version: 1.13.0.qualifier +Bundle-Version: 1.14.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.oomph.setup.ui.SetupUIPlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 -Export-Package: org.eclipse.oomph.setup.ui;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.ui.actions;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.ui.recorder;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.ui.synchronizer;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.ui.wizards;version="1.13.0";x-internal:=true +Export-Package: org.eclipse.oomph.setup.ui;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.ui.actions;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.ui.recorder;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.ui.synchronizer;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.ui.wizards;version="1.14.0";x-internal:=true Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", org.eclipse.core.filesystem;bundle-version="[1.0.0,2.0.0)", @@ -26,14 +26,14 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.nebula.widgets.tablecombo;bundle-version="[1.0.0,2.0.0)", org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.edit.ui;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.core;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.edit;bundle-version="[1.13.0,2.0.0)";visibility:=reexport, - org.eclipse.oomph.setup.p2.edit;bundle-version="[1.10.0,2.0.0)", + org.eclipse.oomph.setup.core;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.edit;bundle-version="[1.14.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.setup.p2.edit;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.setup.sync;bundle-version="[1.10.0,2.0.0)", org.eclipse.oomph.ui;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.p2.edit;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, org.eclipse.oomph.p2.core;bundle-version="[1.12.0,2.0.0)", - org.eclipse.oomph.p2.ui;bundle-version="[1.10.0,2.0.0)", + org.eclipse.oomph.p2.ui;bundle-version="[1.11.0,2.0.0)", org.eclipse.oomph.jreinfo.ui;bundle-version="[1.10.0,2.0.0)", org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)" Bundle-ActivationPolicy: lazy diff --git a/plugins/org.eclipse.oomph.setup.ui/icons/marketplace16.png b/plugins/org.eclipse.oomph.setup.ui/icons/marketplace16.png Binary files differnew file mode 100644 index 000000000..180fc9789 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/icons/marketplace16.png diff --git a/plugins/org.eclipse.oomph.setup.ui/icons/marketplace_banner.png b/plugins/org.eclipse.oomph.setup.ui/icons/marketplace_banner.png Binary files differnew file mode 100644 index 000000000..e8da1c0ec --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/icons/marketplace_banner.png diff --git a/plugins/org.eclipse.oomph.setup.ui/plugin.xml b/plugins/org.eclipse.oomph.setup.ui/plugin.xml index c4dc1c868..168b9cab5 100644 --- a/plugins/org.eclipse.oomph.setup.ui/plugin.xml +++ b/plugins/org.eclipse.oomph.setup.ui/plugin.xml @@ -67,7 +67,19 @@ id="org.eclipse.oomph.setup.InlineMacroTaskAction" label="Inline" style="push" - tooltip="Replace the macro task with an inline copy"> + tooltip="Replace the macro expansion task with an inline copy"> + </action> + </objectContribution> + <objectContribution + id="org.eclipse.oomph.setup.contribution3" + objectClass="org.eclipse.oomph.setup.MacroTask"> + <action + class="org.eclipse.oomph.setup.ui.actions.ConfigureMarketPlaceListingAction" + enablesFor="1" + id="org.eclipse.oomph.setup.ConfigureMarketPlaceListingAction" + label="Configure Marketplace Listing..." + style="push" + tooltip="Configure the marketplace listing to select the features to install"> </action> </objectContribution> </extension> diff --git a/plugins/org.eclipse.oomph.setup.ui/pom.xml b/plugins/org.eclipse.oomph.setup.ui/pom.xml index 67d697889..d9fdcd7e1 100644 --- a/plugins/org.eclipse.oomph.setup.ui/pom.xml +++ b/plugins/org.eclipse.oomph.setup.ui/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup.ui</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/SetupTransferSupport.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/SetupTransferSupport.java index 4ffc6c86d..1eec56750 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/SetupTransferSupport.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/SetupTransferSupport.java @@ -16,6 +16,7 @@ import org.eclipse.oomph.internal.ui.OomphEditingDomain; import org.eclipse.oomph.internal.ui.OomphTransferDelegate; import org.eclipse.oomph.setup.internal.core.SetupContext; import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; import org.eclipse.emf.common.command.AbstractCommand; import org.eclipse.emf.common.command.BasicCommandStack; @@ -411,7 +412,8 @@ class LoadResourceCommand extends ResourceCommand URI uri = (URI)object; String fileExtension = uri.fileExtension(); - if (!"setup".equals(fileExtension) && !"zip".equals(fileExtension)) + if (!"setup".equals(fileExtension) && !"zip".equals(fileExtension) + && MarketPlaceListing.getMarketPlaceListing(uri, domain.getResourceSet().getURIConverter()) == null) { return false; } @@ -428,7 +430,13 @@ class LoadResourceCommand extends ResourceCommand for (Object object : collection) { URI uri = (URI)object; - Resource resource = resourceSet.getResource(uri, false); + MarketPlaceListing marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, resourceSet.getURIConverter()); + if (marketPlaceListing != null) + { + uri = marketPlaceListing.getListing(); + } + + Resource resource = resourceSet.getResource(uri, marketPlaceListing != null); if (resource == null) { resource = resourceSet.createResource(uri); diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/ConfigureMarketPlaceListingAction.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/ConfigureMarketPlaceListingAction.java new file mode 100644 index 000000000..617f2894e --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/ConfigureMarketPlaceListingAction.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.ui.actions; + +import org.eclipse.oomph.p2.Requirement; +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.CompoundTask; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupFactory; +import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; +import org.eclipse.oomph.setup.ui.SetupUIPlugin; +import org.eclipse.oomph.setup.ui.wizards.MarketPlaceListingProcessor; + +import org.eclipse.emf.common.command.CompoundCommand; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.Diagnostician; +import org.eclipse.emf.edit.command.SetCommand; +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; +import org.eclipse.emf.edit.domain.EditingDomain; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Ed Merks + */ +public class ConfigureMarketPlaceListingAction implements IObjectActionDelegate +{ + private final Set<MacroTask> macroTasks = new HashSet<MacroTask>(); + + private Shell shell; + + public ConfigureMarketPlaceListingAction() + { + } + + public void setActivePart(IAction action, IWorkbenchPart targetPart) + { + shell = targetPart == null ? null : targetPart.getSite().getShell(); + } + + public void selectionChanged(IAction action, ISelection selection) + { + macroTasks.clear(); + if (selection instanceof IStructuredSelection) + { + for (Object element : ((IStructuredSelection)selection).toArray()) + { + if (element instanceof MacroTask) + { + MacroTask macroTask = (MacroTask)element; + if (isValid(macroTask)) + { + macroTasks.add(macroTask); + } + } + } + } + + action.setEnabled(shell != null && macroTasks.size() == 1); + action.setImageDescriptor(SetupUIPlugin.INSTANCE.getImageDescriptor("marketplace16.png")); + } + + public void run(IAction action) + { + MacroTask macroTask = macroTasks.iterator().next(); + EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(macroTask); + if (domain != null) + { + execute(shell, domain, macroTask); + } + } + + public static void configure(Shell shell, EditingDomain domain, MacroTask macroTask) + { + if (isValid(macroTask)) + { + execute(shell, domain, macroTask); + } + } + + private static boolean isValid(MacroTask macroTask) + { + Macro macro = macroTask.getMacro(); + return macro != null && macro.eResource() != null + && Diagnostician.INSTANCE.validate(macro.eClass(), macro, null, Diagnostician.INSTANCE.createDefaultContext()) + && MarketPlaceListing.isMarketPlaceListing(macro.eResource().getURI()); + } + + private static void execute(Shell shell, final EditingDomain domain, final MacroTask macroTask) + { + final Macro macro = macroTask.getMacro(); + Resource resource = macro.eResource(); + URI uri = resource.getURI(); + final Map<String, Argument> arguments = new LinkedHashMap<String, Argument>(); + for (Argument argument : macroTask.getArguments()) + { + Parameter parameter = argument.getParameter(); + if (parameter != null) + { + String name = parameter.getName(); + if (name != null) + { + arguments.put(name, argument); + } + } + } + + new MarketPlaceListingProcessor(shell, MarketPlaceListing.getMarketPlaceListing(uri, domain.getResourceSet().getURIConverter()), resource) + { + @Override + protected boolean isSelected(Requirement requirement) + { + String correspondParameterName = getCorrespondParameterName(requirement); + Argument argument = arguments.get(correspondParameterName); + return argument != null && "true".equals(argument.getValue()); + } + + @Override + protected void applyMarketPlaceListing(Set<Requirement> checkedRequirements) + { + CompoundTask compoundTask = SetupFactory.eINSTANCE.createCompoundTask(); + MacroTask newMacroTask = createMacroTask(compoundTask, macro, checkedRequirements); + + Map<String, Parameter> parameters = new LinkedHashMap<String, Parameter>(); + for (Parameter parameter : macro.getParameters()) + { + String name = parameter.getName(); + parameters.put(name, parameter); + } + + List<Argument> newArguments = new ArrayList<Argument>(); + Map<Argument, String> newArgumentValues = new LinkedHashMap<Argument, String>(); + boolean addArgument = false; + for (Argument argument : newMacroTask.getArguments()) + { + String name = argument.getParameter().getName(); + Argument otherArgument = arguments.get(name); + if (otherArgument == null) + { + otherArgument = SetupFactory.eINSTANCE.createArgument(); + otherArgument.setParameter(parameters.get(name)); + otherArgument.setValue(argument.getValue()); + addArgument = true; + } + else + { + newArgumentValues.put(otherArgument, argument.getValue()); + } + + newArguments.add(otherArgument); + } + + CompoundCommand compoundCommand = new CompoundCommand("Configure Marketplace Listing"); + if (addArgument) + { + // The command isn't executable unless we really change something, i.e., add a missing argument. + compoundCommand.append(SetCommand.create(domain, macroTask, SetupPackage.Literals.MACRO_TASK__ARGUMENTS, newArguments)); + } + + for (Map.Entry<Argument, String> entry : newArgumentValues.entrySet()) + { + compoundCommand.append(SetCommand.create(domain, entry.getKey(), SetupPackage.Literals.ARGUMENT__VALUE, entry.getValue())); + } + + domain.getCommandStack().execute(compoundCommand); + } + }.processMarketPlaceListing(); + } +} diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java index 1de3ecb90..f743a7475 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/actions/InlineMacroTaskAction.java @@ -13,15 +13,16 @@ package org.eclipse.oomph.setup.ui.actions; import org.eclipse.oomph.setup.CompoundTask; import org.eclipse.oomph.setup.Macro; import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.SetupPackage; import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer; import org.eclipse.oomph.setup.ui.SetupUIPlugin; -import org.eclipse.oomph.util.StringUtil; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.Diagnostician; import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.edit.command.ReplaceCommand; @@ -65,7 +66,7 @@ public class InlineMacroTaskAction implements IObjectActionDelegate { MacroTask macroTask = (MacroTask)element; Macro macro = macroTask.getMacro(); - if (macro != null && macroTask.getArguments().size() == macro.getParameters().size() && !StringUtil.isEmpty(macroTask.getID())) + if (macro != null && Diagnostician.INSTANCE.validate(macro.eClass(), macro, null, Diagnostician.INSTANCE.createDefaultContext())) { macroTasks.add(macroTask); } @@ -94,8 +95,11 @@ public class InlineMacroTaskAction implements IObjectActionDelegate Collection<EStructuralFeature.Setting> inverseReferences = eCrossReferenceAdapter.getInverseReferences(macroTask); for (EStructuralFeature.Setting setting : inverseReferences) { - compoundCommand - .append(ReplaceCommand.create(domain, setting.getEObject(), setting.getEStructuralFeature(), macroTask, Collections.singleton(replacement))); + if (setting.getEStructuralFeature() != SetupPackage.Literals.ARGUMENT__MACRO_TASK) + { + compoundCommand + .append(ReplaceCommand.create(domain, setting.getEObject(), setting.getEStructuralFeature(), macroTask, Collections.singleton(replacement))); + } } } diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/MarketPlaceListingProcessor.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/MarketPlaceListingProcessor.java new file mode 100644 index 000000000..8f038a200 --- /dev/null +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/MarketPlaceListingProcessor.java @@ -0,0 +1,818 @@ +/* + * Copyright (c) 2019 Ed Merks (Berlin, Germany) and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Ed Merks - initial API and implementation + */ +package org.eclipse.oomph.setup.ui.wizards; + +import org.eclipse.oomph.p2.Requirement; +import org.eclipse.oomph.p2.core.P2Util; +import org.eclipse.oomph.setup.Argument; +import org.eclipse.oomph.setup.Installation; +import org.eclipse.oomph.setup.Macro; +import org.eclipse.oomph.setup.MacroTask; +import org.eclipse.oomph.setup.Parameter; +import org.eclipse.oomph.setup.SetupPackage; +import org.eclipse.oomph.setup.SetupTask; +import org.eclipse.oomph.setup.SetupTaskContainer; +import org.eclipse.oomph.setup.internal.core.SetupContext; +import org.eclipse.oomph.setup.p2.util.MarketPlaceListing; +import org.eclipse.oomph.setup.provider.SetupTaskContainerItemProvider; +import org.eclipse.oomph.setup.ui.SetupUIPlugin; +import org.eclipse.oomph.setup.ui.ToolTipLabelProvider; +import org.eclipse.oomph.ui.BackgroundProgressPart; +import org.eclipse.oomph.ui.OomphDialog; +import org.eclipse.oomph.ui.StatusDialog; +import org.eclipse.oomph.ui.UIUtil; +import org.eclipse.oomph.util.OS; +import org.eclipse.oomph.util.StringUtil; + +import org.eclipse.emf.common.ui.DiagnosticComposite; +import org.eclipse.emf.common.ui.viewer.ColumnViewerInformationControlToolTipSupport; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMIException; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.IItemFontProvider; +import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator; +import org.eclipse.emf.edit.ui.provider.ExtendedFontRegistry; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.ProgressMonitorWrapper; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.equinox.p2.core.ProvisionException; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.QueryUtil; +import org.eclipse.equinox.p2.repository.IRepositoryManager; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; +import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.ProgressMonitorPart; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.LocationEvent; +import org.eclipse.swt.browser.LocationListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author Ed Merks + */ +public class MarketPlaceListingProcessor +{ + protected final Shell shell; + + protected final SetupWizard setupWizard; + + protected final Resource marketPlaceListingResource; + + protected final MarketPlaceListing marketPlaceListing; + + private final MarketPlaceListingStatus status; + + private boolean hasOptionalFeatures; + + public MarketPlaceListingProcessor(SetupWizard setupWizard) + { + this.setupWizard = setupWizard; + Resource marketPlaceListingResource = null; + MarketPlaceListing marketPlaceListing = null; + URI uri = URI.createURI("unknown"); + for (Resource resource : setupWizard.getUnappliedConfigurationResources()) + { + uri = resource.getURI(); + if (MarketPlaceListing.isMarketPlaceListing(uri)) + { + marketPlaceListingResource = resource; + marketPlaceListing = MarketPlaceListing.getMarketPlaceListing(uri, setupWizard.getResourceSet().getURIConverter()); + break; + } + } + + this.marketPlaceListing = marketPlaceListing; + this.marketPlaceListingResource = marketPlaceListingResource; + + status = new MarketPlaceListingStatus("Problems were encountered processing the marketplace listing for '" + uri + "'"); + shell = this.setupWizard.getShell(); + } + + public MarketPlaceListingProcessor(Shell shell, MarketPlaceListing marketPlaceListing, Resource marketPlaceListingResource) + { + this.marketPlaceListing = marketPlaceListing; + this.marketPlaceListingResource = marketPlaceListingResource; + this.shell = shell; + + setupWizard = null; + status = new MarketPlaceListingStatus("Problems were encountered processing the marketplace listing for '" + marketPlaceListingResource.getURI() + "'"); + } + + public boolean isMarketPlaceListing() + { + return marketPlaceListing != null; + } + + public IStatus getStatus() + { + status.computeSeverity(); + + int okCount = 0; + IStatus result = null; + for (IStatus status : status.getChildren()) + { + if (status.isOK()) + { + ++okCount; + } + else + { + result = status; + } + } + + if (okCount == 1) + { + return result; + } + + return status; + } + + public boolean processMarketPlaceListing() + { + if (marketPlaceListing == null) + { + if (marketPlaceListingResource != null) + { + status.add(createResourceStatus(Collections.singleton(marketPlaceListingResource), SetupPackage.Literals.MACRO)); + } + + return false; + } + + if (!marketPlaceListingResource.getErrors().isEmpty()) + { + status.add(createResourceStatus(Collections.singleton(marketPlaceListingResource), SetupPackage.Literals.MACRO)); + return false; + } + + if (marketPlaceListing.getUpdateSite() == null) + { + status.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The listing does not include an update site")); + return false; + } + + if (marketPlaceListing.getRequirements().isEmpty()) + { + status.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The listing does not specify any installable units")); + return false; + } + + Point size = getSize(); + final Set<Requirement> checkedRequirements = new LinkedHashSet<Requirement>(); + OomphDialog marketPlaceListingDialog = new OomphDialog(shell, "", size.x, size.y, SetupUIPlugin.INSTANCE, false) + { + private ProgressMonitorPart progressMonitorPart; + + private Job repositoryLoaderJob; + + private CheckboxTableViewer requirementsViewer; + + private ICheckStateListener checkStateListener; + + { + setShellStyle(SWT.SHELL_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.ON_TOP); + } + + @Override + protected String getShellText() + { + return "Marketplace Install"; + } + + @Override + protected String getImagePath() + { + return "marketplace_banner.png"; + } + + @Override + protected String getDefaultMessage() + { + return "Choose the features to install."; + } + + @Override + protected void createUI(final Composite parent) + { + setTitle(marketPlaceListing.getLabel()); + + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + }); + + List<Requirement> requirements = marketPlaceListing.getRequirements(); + final Set<Requirement> requiredRequirements = new HashSet<Requirement>(); + Set<Requirement> selectedRequirements = new HashSet<Requirement>(); + final Map<Requirement, IInstallableUnit> installableUnits = new LinkedHashMap<Requirement, IInstallableUnit>(); + for (Requirement requirement : requirements) + { + installableUnits.put(requirement, null); + if (MarketPlaceListing.isRequired(requirement)) + { + requiredRequirements.add(requirement); + selectedRequirements.add(requirement); + } + else if (isSelected(requirement)) + { + selectedRequirements.add(requirement); + } + } + + hasOptionalFeatures = requiredRequirements.size() < requirements.size(); + + requirementsViewer = CheckboxTableViewer.newCheckList(parent, SWT.MULTI); + requirementsViewer.getTable().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + final Font tableFont = requirementsViewer.getTable().getFont(); + final Font boldFont = ExtendedFontRegistry.INSTANCE.getFont(tableFont, IItemFontProvider.BOLD_FONT); + final Font disabledFont = ExtendedFontRegistry.INSTANCE.getFont(tableFont, IItemFontProvider.ITALIC_FONT); + final Font disabledBoldFont = ExtendedFontRegistry.INSTANCE.getFont(tableFont, IItemFontProvider.BOLD_ITALIC_FONT); + ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); + + ColumnViewerInformationControlToolTipSupport toolTipSupport = new ColumnViewerInformationControlToolTipSupport(requirementsViewer, + new LocationListener() + { + public void changing(LocationEvent event) + { + if (!"about:blank".equals(event.location)) + { + OS.INSTANCE.openSystemBrowser(event.location); + event.doit = false; + } + } + + public void changed(LocationEvent event) + { + } + }); + + checkStateListener = new ICheckStateListener() + { + public void checkStateChanged(CheckStateChangedEvent event) + { + checkedRequirements.clear(); + for (Requirement requirement : requiredRequirements) + { + requirementsViewer.setChecked(requirement, true); + } + + for (Object object : requirementsViewer.getCheckedElements()) + { + if (installableUnits.get(object) != null) + { + checkedRequirements.add((Requirement)object); + } + } + + getButton(IDialogConstants.OK_ID).setEnabled(!checkedRequirements.isEmpty()); + } + }; + requirementsViewer.addCheckStateListener(checkStateListener); + + class RequirementLabelProvider extends ToolTipLabelProvider + { + private RequirementLabelProvider(ComposedAdapterFactory adapterFactory, ColumnViewerInformationControlToolTipSupport toolTipSupport) + { + super(adapterFactory, toolTipSupport); + } + + @Override + public String getText(Object object) + { + IInstallableUnit installableUnit = installableUnits.get(object); + if (installableUnit != null) + { + String name = installableUnit.getProperty(IInstallableUnit.PROP_NAME, null); + if (name != null) + { + return name; + } + } + + return super.getText(object); + } + + @Override + public Image getImage(Object object) + { + Image result = super.getImage(object); + IInstallableUnit installableUnit = installableUnits.get(object); + if (installableUnit == null) + { + return ExtendedImageRegistry.INSTANCE.getImage(ImageDescriptor.createWithFlags(ImageDescriptor.createFromImage(result), SWT.IMAGE_DISABLE)); + } + + return result; + } + + @Override + public Font getFont(Object object) + { + if (installableUnits.get(object) == null) + { + return requiredRequirements.contains(object) ? disabledBoldFont : disabledFont; + } + + return requiredRequirements.contains(object) ? boldFont : null; + } + + @Override + public String getToolTipText(Object element) + { + IInstallableUnit installableUnit = installableUnits.get(element); + if (installableUnit != null) + { + String localBrandingImageURI = installableUnit.getProperty(IInstallableUnit.PROP_ICON); + String brandingSiteURI = installableUnit.getProperty(IInstallableUnit.PROP_DOC_URL); + if (brandingSiteURI == null) + { + brandingSiteURI = marketPlaceListing.getListing().toString(); + } + + String label = installableUnit.getProperty(IInstallableUnit.PROP_NAME, null); + + StringBuilder result = new StringBuilder(); + result.append("<span style='white-space: nowrap; font-size: 150%;'><b>"); + if (brandingSiteURI != null) + { + result.append("<a style='text-decoration: none; color: inherit;' href='"); + result.append(brandingSiteURI); + result.append("'>"); + } + + if (localBrandingImageURI != null) + { + result.append("<img style='padding-top: 4px;' src='"); + result.append(localBrandingImageURI); + result.append("' width='42' height='42' align='absmiddle'/> "); + } + + result.append(DiagnosticDecorator.escapeContent(label).replace(" ", " ")); + result.append("</b></span>"); + + if (brandingSiteURI != null) + { + result.append("</a>"); + } + + String description = installableUnit.getProperty(IInstallableUnit.PROP_DESCRIPTION, null); + if (!StringUtil.isEmpty(description)) + { + result.append("<br/>"); + result.append("<span style='font-size: 50%;'><br/></span>"); + result.append(description); + result.append("<br/>"); + } + + // Add extra invisible lines to convince the tool tip size calculation that the text is 3 lines longer. + // result.append("<div style='height=0px; display:none;'> &nbps;&nbps;&nbps;&nbps;&nbps;&nbps;&nbps;<br/><br/></br></div>"); + result.append("<div style='height=0px; display:none;'>&nbps;&nbps;&nbps;&nbps;&nbps;<br/><br/></br></div>"); + + return result.toString(); + } + + return "Loading..."; + } + } + + requirementsViewer.setContentProvider(new ArrayContentProvider()); + requirementsViewer.setLabelProvider(new RequirementLabelProvider(adapterFactory, toolTipSupport)); + + requirementsViewer.setInput(installableUnits.keySet()); + requirementsViewer.setCheckedElements(selectedRequirements.toArray()); + + Composite progressArea = new Composite(parent, SWT.BORDER); + FillLayout fillLayout = new FillLayout(); + fillLayout.marginHeight = 5; + fillLayout.marginWidth = 5; + progressArea.setLayout(fillLayout); + progressMonitorPart = new BackgroundProgressPart(progressArea, null, true); + + final GridData progressAreaGridData = new GridData(GridData.FILL_HORIZONTAL); + progressArea.setLayoutData(progressAreaGridData); + + repositoryLoaderJob = new Job("Repository Loader") + { + @Override + protected IStatus run(IProgressMonitor monitor) + { + ProgressMonitorWrapper progressMonitorWrapper = new ProgressMonitorWrapper(monitor) + { + @Override + public void beginTask(String name, int totalWork) + { + super.beginTask(name, totalWork); + progressMonitorPart.beginTask(name, totalWork); + } + + @Override + public void done() + { + super.done(); + progressMonitorPart.done(); + } + + @Override + public void setTaskName(String name) + { + super.setTaskName(name); + progressMonitorPart.setTaskName(name); + } + + @Override + public void subTask(String name) + { + super.subTask(name); + progressMonitorPart.subTask(name); + } + + @Override + public void worked(int work) + { + super.worked(work); + progressMonitorPart.worked(work); + } + + @Override + public boolean isCanceled() + { + return super.isCanceled() || progressMonitorPart.isCanceled(); + } + + @Override + public void setCanceled(boolean canceled) + { + super.setCanceled(canceled); + progressMonitorPart.setCanceled(canceled); + } + + @Override + public void clearBlocked() + { + super.clearBlocked(); + progressMonitorPart.clearBlocked(); + } + + @Override + public void internalWorked(double work) + { + super.internalWorked(work); + progressMonitorPart.internalWorked(work); + } + + @Override + public void setBlocked(IStatus reason) + { + super.setBlocked(reason); + progressMonitorPart.setBlocked(reason); + } + }; + + String updateSite = marketPlaceListing.getUpdateSite().toString(); + IMetadataRepositoryManager metadataRepositoryManager = P2Util.getAgentManager().getCurrentAgent().getMetadataRepositoryManager(); + List<java.net.URI> originalKnownRepositories = Arrays.asList(metadataRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)); + try + { + final IMetadataRepository repository = metadataRepositoryManager.loadRepository(new java.net.URI(updateSite), progressMonitorWrapper); + progressMonitorWrapper.done(); + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + handleRepository(repository, installableUnits); + requirementsViewer.refresh(); + checkStateListener.checkStateChanged(null); + } + }); + } + catch (final ProvisionException ex) + { + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + new StatusDialog(parent.getShell(), "Problems", "Problem Loading Repository", + new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, ex.getLocalizedMessage(), ex), DiagnosticComposite.ERROR_WARNING_MASK).open(); + } + }); + } + catch (OperationCanceledException ex) + { + progressMonitorWrapper.done(); + } + catch (final URISyntaxException ex) + { + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + new StatusDialog(parent.getShell(), "Problems", "Problem Loading Repository", + new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, ex.getLocalizedMessage(), ex), DiagnosticComposite.ERROR_WARNING_MASK).open(); + } + }); + } + finally + { + java.net.URI[] finalKnownRepositories = metadataRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); + for (java.net.URI uri : finalKnownRepositories) + { + if (!originalKnownRepositories.contains(uri)) + { + metadataRepositoryManager.removeRepository(uri); + } + } + } + + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + progressAreaGridData.exclude = true; + parent.layout(); + requirementsViewer.getTable().setFocus(); + } + }); + + return Status.OK_STATUS; + } + }; + + repositoryLoaderJob.schedule(); + progressMonitorPart.attachToCancelComponent(null); + + UIUtil.asyncExec(parent, new Runnable() + { + public void run() + { + requirementsViewer.setSelection(new StructuredSelection(installableUnits.keySet().iterator().next())); + } + }); + } + + private void handleRepository(IMetadataRepository repository, Map<Requirement, IInstallableUnit> requiredUnits) + { + for (Map.Entry<Requirement, IInstallableUnit> entry : requiredUnits.entrySet()) + { + Requirement requirement = entry.getKey(); + IQueryResult<IInstallableUnit> queryResult = repository.query(QueryUtil.createIUQuery(requirement.getName()), null); + for (IInstallableUnit installableUnit : P2Util.asIterable(queryResult)) + { + entry.setValue(installableUnit); + break; + } + } + } + + @Override + protected void createButtonsForButtonBar(Composite parent) + { + if (hasOptionalFeatures) + { + createButton(parent, IDialogConstants.CLIENT_ID, "Select &All", true); + createButton(parent, IDialogConstants.CLIENT_ID + 1, "&Deselect All", true); + } + + super.createButtonsForButtonBar(parent); + } + + @Override + protected void buttonPressed(int buttonId) + { + if (buttonId == IDialogConstants.CLIENT_ID) + { + requirementsViewer.setCheckedElements(((Collection<?>)requirementsViewer.getInput()).toArray()); + requirementsViewer.getTable().notifyListeners(SWT.Selection, new Event()); + checkStateListener.checkStateChanged(null); + } + else if (buttonId == IDialogConstants.CLIENT_ID + 1) + { + requirementsViewer.setCheckedElements(new Object[0]); + checkStateListener.checkStateChanged(null); + } + else + { + super.buttonPressed(buttonId); + } + } + + @Override + protected void cancelPressed() + { + super.cancelPressed(); + if (repositoryLoaderJob != null) + { + repositoryLoaderJob.cancel(); + } + } + }; + + if (marketPlaceListingDialog.open() == Window.OK) + { + applyMarketPlaceListing(checkedRequirements); + return true; + } + + return false; + } + + protected boolean isSelected(Requirement requirement) + { + return MarketPlaceListing.isSelected(requirement); + } + + protected Point getSize() + { + Point size = shell.getSize(); + if (setupWizard == null) + { + size.x /= 2; + size.y /= 2; + } + return size; + } + + protected String getCorrespondParameterName(Requirement requirement) + { + String name = requirement.getName(); + return name.substring(0, name.length() - Requirement.FEATURE_SUFFIX.length()) + ".enabled"; + } + + protected void applyMarketPlaceListing(Set<Requirement> checkedRequirements) + { + SetupContext setupContext = SetupContext.create(setupWizard.getResourceSet(), null); + Installation setupInstallation = setupContext.getInstallation(); + + applySetupTasks(setupInstallation, checkedRequirements); + + setupWizard.addAppliedConfigurationResource(marketPlaceListingResource); + } + + protected void applySetupTasks(SetupTaskContainer targetSetupTaskContainer, Set<Requirement> checkedRequirements) + { + Macro macro = (Macro)EcoreUtil.getObjectByType(marketPlaceListingResource.getContents(), SetupPackage.Literals.MACRO); + if (macro != null) + { + MacroTask macroTask = createMacroTask(targetSetupTaskContainer, macro, checkedRequirements); + EList<SetupTask> setupTasks = targetSetupTaskContainer.getSetupTasks(); + setupTasks.add(macroTask); + } + } + + protected MacroTask createMacroTask(SetupTaskContainer targetSetupTaskContainer, Macro macro, Set<Requirement> checkedRequirements) + { + Set<String> checkedParameterNames = new HashSet<String>(); + for (Requirement requirement : checkedRequirements) + { + checkedParameterNames.add(getCorrespondParameterName(requirement)); + } + + MacroTask macroTask = SetupTaskContainerItemProvider.createMacroTask(targetSetupTaskContainer, macro); + for (Argument argument : macroTask.getArguments()) + { + Parameter parameter = argument.getParameter(); + String name = parameter.getName(); + argument.setValue(checkedParameterNames.contains(name) ? "true" : "false"); + } + + return macroTask; + } + + protected IStatus createResourceStatus(Collection<? extends Resource> resources, EClass expectedEClass) + { + StringBuilder uris = new StringBuilder(); + List<IStatus> childStatuses = new ArrayList<IStatus>(); + for (Resource resource : resources) + { + if (uris.length() != 0) + { + uris.append(' '); + } + + uris.append(resource.getURI()); + + EList<Resource.Diagnostic> errors = resource.getErrors(); + if (errors.isEmpty()) + { + EList<EObject> contents = resource.getContents(); + if (contents.isEmpty()) + { + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The resource is empty")); + } + else + { + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, "The resource contains a " + contents.get(0).eClass().getName())); + } + } + else + { + for (Resource.Diagnostic diagnostic : errors) + { + String message = diagnostic.getMessage(); + Throwable throwable = null; + if (diagnostic instanceof Throwable) + { + throwable = (Throwable)diagnostic; + if (throwable instanceof XMIException) + { + Throwable cause = throwable.getCause(); + if (cause != null) + { + XMIException xmiException = (XMIException)throwable; + message = cause.getMessage(); + int line = xmiException.getLine(); + if (line != 0) + { + message += " (" + line + ", " + xmiException.getColumn() + ")"; + } + } + } + } + + childStatuses.add(new Status(IStatus.ERROR, SetupUIPlugin.PLUGIN_ID, message, throwable)); + } + } + } + + return new MultiStatus(SetupUIPlugin.PLUGIN_ID, 0, childStatuses.toArray(new IStatus[childStatuses.size()]), + "No " + expectedEClass.getName() + " could be loaded from " + uris, null); + } + + private static class MarketPlaceListingStatus extends MultiStatus + { + public MarketPlaceListingStatus(Resource resource) + { + super(SetupUIPlugin.PLUGIN_ID, 0, "Processing " + resource.getURI(), null); + } + + public MarketPlaceListingStatus(String message) + { + super(SetupUIPlugin.PLUGIN_ID, 0, message, null); + } + + public int computeSeverity() + { + for (IStatus status : getChildren()) + { + int newSev = status instanceof MarketPlaceListingStatus ? ((MarketPlaceListingStatus)status).computeSeverity() : status.getSeverity(); + if (newSev > getSeverity()) + { + setSeverity(newSev); + } + } + + return getSeverity(); + } + } +} diff --git a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java index 17de2cc5e..e6ec76d07 100644 --- a/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java +++ b/plugins/org.eclipse.oomph.setup.ui/src/org/eclipse/oomph/setup/ui/wizards/ProjectPage.java @@ -986,6 +986,12 @@ public class ProjectPage extends SetupWizardPage SetupWizard setupWizard = getWizard(); setupWizard.setConfigurationResources(resources); + MarketPlaceListingProcessor marketPlaceListingProcessor = new MarketPlaceListingProcessor(setupWizard); + if (marketPlaceListingProcessor.isMarketPlaceListing()) + { + return; + } + ConfigurationProcessor configurationProcessor = new ConfigurationProcessor(getWizard()) { @Override diff --git a/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF index 37c8b7632..525368813 100644 --- a/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.oomph.setup/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.oomph.setup;singleton:=true -Bundle-Version: 1.13.0.qualifier +Bundle-Version: 1.14.0.qualifier Bundle-ClassPath: . Bundle-Name: %pluginName Bundle-Vendor: %providerName @@ -12,14 +12,14 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)", org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)";visibility:=reexport, org.eclipse.emf.edit;bundle-version="[2.10.0,3.0.0)", - org.eclipse.oomph.base;bundle-version="[1.11.0,2.0.0)";visibility:=reexport, + org.eclipse.oomph.base;bundle-version="[1.12.0,2.0.0)";visibility:=reexport, org.eclipse.emf.ecore;bundle-version="[2.10.0,3.0.0)";visibility:=reexport Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.oomph.internal.setup;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.impl;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.log;version="1.13.0";x-internal:=true, - org.eclipse.oomph.setup.util;version="1.13.0";x-internal:=true +Export-Package: org.eclipse.oomph.internal.setup;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.impl;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.log;version="1.14.0";x-internal:=true, + org.eclipse.oomph.setup.util;version="1.14.0";x-internal:=true Bundle-Activator: org.eclipse.oomph.internal.setup.SetupPlugin$Implementation Automatic-Module-Name: org.eclipse.oomph.setup diff --git a/plugins/org.eclipse.oomph.setup/pom.xml b/plugins/org.eclipse.oomph.setup/pom.xml index 05ecde1a5..f59d49486 100644 --- a/plugins/org.eclipse.oomph.setup/pom.xml +++ b/plugins/org.eclipse.oomph.setup/pom.xml @@ -20,7 +20,7 @@ </parent> <groupId>org.eclipse.oomph</groupId> <artifactId>org.eclipse.oomph.setup</artifactId> - <version>1.13.0-SNAPSHOT</version> + <version>1.14.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> diff --git a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/internal/setup/SetupProperties.java b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/internal/setup/SetupProperties.java index ff3044c18..91f7af8a5 100644 --- a/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/internal/setup/SetupProperties.java +++ b/plugins/org.eclipse.oomph.setup/src/org/eclipse/oomph/internal/setup/SetupProperties.java @@ -56,6 +56,8 @@ public class SetupProperties */ public static final String PROP_SETUP_INSTALLER_MODE = "oomph.setup.installer.mode"; + public static final String PROP_SETUP_INSTALLER_MARKETPLACE = "oomph.setup.installer.marketplace"; + public static final String PROP_SETUP_PRODUCT_CATALOG_FILTER = "oomph.setup.product.catalog.filter"; public static final String PROP_SETUP_PRODUCT_FILTER = "oomph.setup.product.filter"; |