blob: 6fc549aed4dab8cfb8de940ca9ec3d7cedf63223 [file] [log] [blame]
/*
* Copyright (c) 2015, 2016 Eike Stepper (Loehne, 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.oomph.setup.internal.installer;
import org.eclipse.oomph.internal.ui.AccessUtil;
import org.eclipse.oomph.p2.core.CertificateConfirmer;
import org.eclipse.oomph.p2.internal.ui.P2ServiceUI;
import org.eclipse.oomph.setup.Index;
import org.eclipse.oomph.setup.Installation;
import org.eclipse.oomph.setup.Macro;
import org.eclipse.oomph.setup.MacroTask;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.Trigger;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
import org.eclipse.oomph.setup.p2.util.MarketPlaceListing;
import org.eclipse.oomph.setup.ui.UnsignedContentDialog;
import org.eclipse.oomph.setup.ui.wizards.ExtensionsDialog;
import org.eclipse.oomph.setup.ui.wizards.ProjectPage;
import org.eclipse.oomph.setup.ui.wizards.ProjectPage.ConfigurationListener;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard;
import org.eclipse.oomph.util.Confirmer;
import org.eclipse.oomph.util.PropertiesUtil;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.equinox.p2.core.UIServices;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* @author Eike Stepper
*/
public class Installer extends SetupWizard
{
private final SelectionMemento selectionMemento;
public final UIServices uiServices;
private final Set<URI> delayedResourceURIs = new LinkedHashSet<URI>();
private final Map<ConfigurationListener, ToolItem> extensionButtons = new HashMap<ConfigurationListener, ToolItem>();
private final Listener openListener;
private boolean indexLoaded;
public Installer(SelectionMemento theSelectionMemento)
{
selectionMemento = theSelectionMemento;
setTrigger(Trigger.BOOTSTRAP);
getResourceSet().getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING, ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);
setSetupContext(SetupContext.createUserOnly(getResourceSet()));
setWindowTitle(PropertiesUtil.getProductName());
uiServices = new P2ServiceUI()
{
@Override
protected Confirmer getUnsignedContentConfirmer()
{
return UnsignedContentDialog.createUnsignedContentConfirmer(getUser(), false);
}
@Override
protected CertificateConfirmer getCertificateConfirmer()
{
return SetupCoreUtil.createCertificateConfirmer(getUser(), false);
}
@Override
protected UIServices getDelegate()
{
return null;
}
};
openListener = new Listener()
{
public void handleEvent(Event event)
{
handleArgument(event.text);
}
};
Display display = Display.getDefault();
display.addListener(SWT.OpenDocument, openListener);
display.addListener(SWT.OpenUrl, openListener);
}
public void handleArgument(String argument)
{
handleURI(URISchemeUtil.getResourceURI(argument));
}
public void handleURI(URI uri)
{
delayedResourceURIs.add(uri);
}
protected boolean canHandleDelayedResourceURIs()
{
// Avoid doing anything until the index is loaded.
if (!indexLoaded)
{
return false;
}
if (isSimple())
{
// Only this page supports drag and drop of configurations, so only process for that page.
SimpleInstallerDialog simpleInstallerDialog = (SimpleInstallerDialog)getShell();
return simpleInstallerDialog.getTopPage() instanceof SimpleProductPage;
}
// Only these pages support drag and drop of configurations, so only process for these pages.
IWizardPage currentPage = getCurrentPage();
return currentPage instanceof ProductPage || currentPage instanceof ProjectPage;
}
public UIServices getUiServices()
{
return uiServices;
}
public SelectionMemento getSelectionMemento()
{
return selectionMemento;
}
@Override
public String getHelpPath()
{
return HELP_FOLDER + "DocInstallWizard.html";
}
@Override
public void addPages()
{
addPage(new ProductPage(selectionMemento));
addPage(new ProjectPage(selectionMemento));
addPage(new ExtensionPage());
super.addPages();
getShell().getDisplay().asyncExec(new Runnable()
{
public void run()
{
loadIndex();
}
});
}
@Override
protected void indexLoaded(Index index)
{
super.indexLoaded(index);
getCatalogManager().indexLoaded(index);
IWizardPage currentPage = getCurrentPage();
if (currentPage instanceof ProjectPage)
{
((ProjectPage)currentPage).gotoPreviousPage();
}
indexLoaded = true;
}
@Override
public void addAppliedConfigurationResource(Resource configurationResource)
{
super.addAppliedConfigurationResource(configurationResource);
if (isSimple())
{
SimpleInstallerDialog simpleInstallerDialog = (SimpleInstallerDialog)getShell();
simpleInstallerDialog.setExtensionsAvailable(true);
}
else
{
for (Map.Entry<ConfigurationListener, ToolItem> entry : extensionButtons.entrySet())
{
ToolItem toolItem = entry.getValue();
if (toolItem == null)
{
entry.setValue(createExtensionsButton(entry.getKey()));
}
entry.getKey().checkConfigurationAvailability();
}
}
}
@Override
public void removeAppliedConfigurationResource(Resource configurationResource)
{
super.removeAppliedConfigurationResource(configurationResource);
if (getAppliedConfigurationResources().isEmpty())
{
if (isSimple())
{
SimpleInstallerDialog simpleInstallerDialog = (SimpleInstallerDialog)getShell();
simpleInstallerDialog.setExtensionsAvailable(false);
}
else
{
for (final Map.Entry<ConfigurationListener, ToolItem> entry : extensionButtons.entrySet())
{
ToolItem toolItem = entry.getValue();
toolItem.dispose();
entry.setValue(null);
entry.getKey().checkConfigurationAvailability();
}
}
}
}
@Override
public void addConfigurationListener(ConfigurationListener configurationListener)
{
extensionButtons.put(configurationListener, null);
}
private ToolItem createExtensionsButton(ConfigurationListener configurationListener)
{
ToolBar toolBar = configurationListener.getToolBar();
int index = toolBar.getItemCount() > 0 && toolBar.getItem(0).getData("ConfigurationSelectionAdapter") != null ? 1 : 0;
ToolItem extensionsButton = new ToolItem(toolBar, SWT.NONE, index);
extensionsButton.setToolTipText(SimpleInstallerDialog.EXTENSIONS_MENU_ITEM_DESCRIPTION);
extensionsButton.setImage(SetupInstallerPlugin.INSTANCE.getSWTImage("simple/extension_notification_overlay.png"));
AccessUtil.setKey(extensionsButton, "manageExtensions");
extensionsButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
Collection<? extends Resource> appliedConfigurationResources = getAppliedConfigurationResources();
ExtensionsDialog extensionsDialog = new ExtensionsDialog(getShell(), appliedConfigurationResources);
if (extensionsDialog.open() == Window.OK)
{
Installation installation = getSetupContext().getInstallation();
boolean reset = false;
Collection<? extends Resource> result = extensionsDialog.getResult();
for (Resource resource : appliedConfigurationResources)
{
if (!result.contains(resource))
{
removeAppliedConfigurationResource(resource);
if (installation != null)
{
URI uri = resource.getURI();
if (MarketPlaceListing.isMarketPlaceListing(uri))
{
for (SetupTask setupTask : installation.getSetupTasks())
{
if (setupTask instanceof MacroTask)
{
Macro macro = ((MacroTask)setupTask).getMacro();
if (macro == null || macro.eResource() == null || macro.eResource().getURI().equals(uri))
{
EcoreUtil.delete(macro);
break;
}
}
}
}
else
{
reset = true;
}
}
}
}
IWizardContainer container = getContainer();
if (reset && container instanceof InstallerDialog)
{
InstallerDialog installerDialog = (InstallerDialog)container;
installerDialog.reset();
}
}
}
});
extensionButtons.put(configurationListener, extensionsButton);
toolBar.getParent().layout(true);
toolBar.layout(true);
return extensionsButton;
}
@Override
public void setPerformer(SetupTaskPerformer performer)
{
super.setPerformer(performer);
if (performer != null)
{
performer.put(UIServices.class, getUiServices());
}
}
public boolean handleMissingIndex(Shell shell)
{
int answer = new MessageDialog(shell, "Network Problem", null,
"The catalog could not be loaded. Please ensure that you have network access and, if needed, have configured your network proxy.", MessageDialog.ERROR,
new String[] { "Retry", "Configure Network Proxy...", "Exit" }, 0).open();
switch (answer)
{
case 1:
{
new NetworkConnectionsDialog(shell).open();
}
//$FALL-THROUGH$
case 0:
{
ResourceSet resourceSet = getResourceSet();
URI currentIndexLocation = resourceSet.getURIConverter().normalize(SetupContext.INDEX_SETUP_URI);
ECFURIHandlerImpl.clearExpectedETags();
reloadIndex(currentIndexLocation);
return true;
}
default:
{
return false;
}
}
}
public void runEventLoop(Shell shell)
{
// Use our own even loop so we can process delayed events.
// This ensures that we do not process delayed events while any other modal dialog is in its own event loop.
Display display = shell.getDisplay();
while (!shell.isDisposed())
{
try
{
if (!display.readAndDispatch())
{
if (canHandleDelayedResourceURIs() && !delayedResourceURIs.isEmpty())
{
// Consume the resources one at a time.
Iterator<URI> it = delayedResourceURIs.iterator();
URI resourceURI = it.next();
it.remove();
getTransferSupport().urisDropped(Collections.singleton(resourceURI));
}
else
{
display.sleep();
}
}
}
catch (Throwable throwable)
{
SetupInstallerPlugin.INSTANCE.log(throwable);
}
}
if (!display.isDisposed())
{
display.update();
}
// Clean up out listeners, because we might restart a new installer but with the same display instance.
display.removeListener(SWT.OpenDocument, openListener);
display.removeListener(SWT.OpenUrl, openListener);
}
}