blob: e60710225e0f6371bb181326f8b740cf03e68e7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 WindRiver Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* WindRiver Corporation - initial API and implementation
* Ericsson AB (Pascal Rapicault) - Bug 387115 - Allow to export everything
*******************************************************************************/
package org.eclipse.equinox.internal.p2.importexport.internal.wizard;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Properties;
import java.util.concurrent.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.extensionlocation.ExtensionLocationArtifactRepositoryFactory;
import org.eclipse.equinox.internal.p2.extensionlocation.ExtensionLocationMetadataRepositoryFactory;
import org.eclipse.equinox.internal.p2.importexport.internal.Constants;
import org.eclipse.equinox.internal.p2.importexport.internal.Messages;
import org.eclipse.equinox.internal.p2.ui.ProvUI;
import org.eclipse.equinox.internal.p2.ui.dialogs.ISelectableIUsPage;
import org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard;
import org.eclipse.equinox.internal.p2.ui.model.ProfileElement;
import org.eclipse.equinox.internal.p2.ui.viewers.IUDetailsLabelProvider;
import org.eclipse.equinox.p2.core.*;
import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactRepositoryFactory;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.repository.metadata.spi.MetadataRepositoryFactory;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.*;
import org.osgi.util.tracker.ServiceTracker;
public class ImportFromInstallationPage extends AbstractImportPage implements ISelectableIUsPage {
protected IProvisioningAgent otherInstanceAgent = null;
IProfile toBeImportedProfile = null;
private File instancePath = null;
private URI[] metaURIs = null;
private URI[] artiURIs = null;
private IProvisioningAgentProvider agentProvider;
public ImportFromInstallationPage(ProvisioningUI ui, ProvisioningOperationWizard wizard) {
super("importfrominstancepage", ui, wizard); //$NON-NLS-1$
setTitle(Messages.ImportFromInstallationPage_DIALOG_TITLE);
setDescription(Messages.ImportFromInstallationPage_DIALOG_DESCRIPTION);
}
@Override
protected void createContents(Composite composite) {
createDestinationGroup(composite, true);
createInstallationTable(composite);
}
@Override
protected String getDestinationLabel() {
return Messages.ImportFromInstallationPage_DESTINATION_LABEL;
}
@Override
protected String getDialogTitle() {
return Messages.ImportFromInstallationPage_DIALOG_TITLE;
}
@Override
protected Object getInput() {
return new IInstallableUnit[0];
}
@Override
protected String getInvalidDestinationMessage() {
return Messages.ImportFromInstallationPage_INVALID_DESTINATION;
}
@Override
protected String getNoOptionsMessage() {
return Messages.ImportFromInstallationPage_SELECT_COMPONENT;
}
@Override
protected boolean validateDestinationGroup() {
return validateDestinationGroup(new NullProgressMonitor());
}
private IProvisioningAgentProvider getAgentProvider() {
if (agentProvider == null) {
ServiceTracker<IProvisioningAgentProvider, IProvisioningAgentProvider> tracker = new ServiceTracker<IProvisioningAgentProvider, IProvisioningAgentProvider>(Platform.getBundle(Constants.Bundle_ID).getBundleContext(), IProvisioningAgentProvider.class, null);
tracker.open();
agentProvider = tracker.getService();
tracker.close();
}
return agentProvider;
}
boolean validateDestinationGroup(IProgressMonitor monitor) {
SubMonitor progress = SubMonitor.convert(monitor, 100);
boolean rt;
if (Display.findDisplay(Thread.currentThread()) == null) {
Callable<Boolean> getSuperValidateDest = new Callable<Boolean>() {
Boolean validated;
public Boolean call() throws Exception {
Display.getDefault().syncExec(new Runnable() {
public void run() {
validated = ImportFromInstallationPage.super.validateDestinationGroup();
}
});
return validated;
}
};
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Future<Boolean> getSuperDestTask = executor.submit(getSuperValidateDest);
try {
rt = getSuperDestTask.get().booleanValue();
} catch (Exception e) {
return false;
} finally {
executor.shutdown();
}
} else
rt = super.validateDestinationGroup();
if (rt) {
try {
String destination;
if (Display.findDisplay(Thread.currentThread()) == null) {
Callable<String> getDestinationValue = new Callable<String>() {
String des;
public String call() throws Exception {
if (Display.findDisplay(Thread.currentThread()) == null) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
des = getDestinationValue();
}
});
} else
des = getDestinationValue();
return des;
}
};
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Future<String> getDestTask = executor.submit(getDestinationValue);
try {
destination = getDestTask.get();
} finally {
executor.shutdown();
}
} else
destination = getDestinationValue();
String toBeImportedProfileId = null;
try {
File config = new File(destination, "configuration/config.ini"); //$NON-NLS-1$
URI configArea = config.getParentFile().toURI();
InputStream is = null;
// default area
File p2DataArea = new File(destination, "p2"); //$NON-NLS-1$
try {
Properties props = new Properties();
is = new FileInputStream(config);
props.load(is);
toBeImportedProfileId = props.getProperty("eclipse.p2.profile"); //$NON-NLS-1$
String url = props.getProperty("eclipse.p2.data.area"); //$NON-NLS-1$
if (url != null) {
final String CONFIG_DIR = "@config.dir/"; //$NON-NLS-1$
final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$
if (url.startsWith(CONFIG_DIR))
url = FILE_PROTOCOL + url.substring(CONFIG_DIR.length());
p2DataArea = new File(URIUtil.makeAbsolute(URIUtil.fromString(new File(url.substring(FILE_PROTOCOL.length())).isAbsolute() ? url : url.substring(FILE_PROTOCOL.length())), configArea));
}
} catch (IOException ioe) {
//ignore
} finally {
try {
is.close();
} catch (IOException ioe) {
//ignore
}
is = null;
}
if (p2DataArea.exists()) {
boolean createAgent = true;
if (otherInstanceAgent != null) {
// don't create agent again if the selection is not changed
if (!p2DataArea.equals(instancePath)) {
otherInstanceAgent.stop();
otherInstanceAgent = null;
// update cached specified path by users
instancePath = p2DataArea;
cleanLocalRepository();
} else
createAgent = false;
}
if (createAgent)
otherInstanceAgent = getAgentProvider().createAgent(p2DataArea.toURI());
ArtifactRepositoryFactory factory = new ExtensionLocationArtifactRepositoryFactory();
factory.setAgent(agent);
IArtifactRepository artiRepo = factory.load(new File(destination).toURI(), 0, progress.newChild(50));
artiURIs = new URI[] {artiRepo.getLocation()};
MetadataRepositoryFactory metaFatory = new ExtensionLocationMetadataRepositoryFactory();
metaFatory.setAgent(agent);
IMetadataRepository metaRepo = metaFatory.load(new File(destination).toURI(), 0, progress.newChild(50));
metaURIs = new URI[] {metaRepo.getLocation()};
} else
throw new FileNotFoundException();
} catch (ProvisionException e) {
if (otherInstanceAgent != null) {
toBeImportedProfile = null;
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) agent.getService(IArtifactRepositoryManager.SERVICE_NAME);
IProfileRegistry registry = (IProfileRegistry) otherInstanceAgent.getService(IProfileRegistry.SERVICE_NAME);
if (toBeImportedProfileId != null)
toBeImportedProfile = registry.getProfile(toBeImportedProfileId);
if (toBeImportedProfile == null) {
IProfile[] existingProfiles = registry.getProfiles();
if (existingProfiles.length == 1) {
toBeImportedProfile = existingProfiles[0];
} else {
for (IProfile existingProfile : existingProfiles) {
if (toBeImportedProfile == null)
toBeImportedProfile = existingProfile;
else if ((toBeImportedProfile.getTimestamp() < existingProfile.getTimestamp())) // assuming last modified one is we are looking for
toBeImportedProfile = existingProfile;
}
}
}
IAgentLocation location = (IAgentLocation) otherInstanceAgent.getService(IAgentLocation.SERVICE_NAME);
URI engineDataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$
progress.setWorkRemaining(50);
IMetadataRepository metaRepo = manager.loadRepository(engineDataArea.resolve("profileRegistry/" + toBeImportedProfile.getProfileId() + ".profile"), progress.newChild(25)); //$NON-NLS-1$//$NON-NLS-2$
metaURIs = new URI[] {metaRepo.getLocation()};
IArtifactRepository artiRepo = artifactManager.loadRepository(new File(destination).toURI(), progress.newChild(25));
artiURIs = new URI[] {artiRepo.getLocation()};
} else
throw new Exception();
}
} catch (Exception e) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
setErrorMessage(getInvalidDestinationMessage());
}
});
rt = false;
if (otherInstanceAgent != null)
otherInstanceAgent.stop();
otherInstanceAgent = null;
toBeImportedProfile = null;
cleanLocalRepository();
} finally {
monitor.done();
}
}
return rt;
}
@Override
protected void giveFocusToDestination() {
destinationBrowseButton.setFocus();
}
@Override
protected void handleDestinationBrowseButtonPressed() {
DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell());
dialog.setText(getDialogTitle());
dialog.setFilterPath(getDestinationValue());
final String selectedFileName = dialog.open();
if (selectedFileName != null) {
setDestinationValue(selectedFileName);
}
}
@Override
protected void handleDestinationChanged(String newDestination) {
try {
getContainer().run(true, false, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) {
Object input = null;
if (validateDestinationGroup(monitor)) {
final IProfile currentProfile = toBeImportedProfile;
final ProfileElement element = new ProfileElement(null, currentProfile.getProfileId()) {
@Override
public org.eclipse.equinox.p2.query.IQueryable<?> getQueryable() {
return currentProfile;
}
};
element.setQueryable(currentProfile);
input = element;
}
final Object viewerInput = input;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
viewer.setInput(viewerInput);
updatePageCompletion();
}
});
}
});
} catch (InvocationTargetException e) {
setErrorMessage(e.getLocalizedMessage());
setPageComplete(false);
} catch (InterruptedException e) {
// won't happen
}
}
@Override
protected boolean validDestination() {
if (this.destinationNameField == null)
return true;
File file = new File(getDestinationValue());
return file.exists() && file.isDirectory();
}
class ImportFromInstallationLabelProvider extends IUDetailsLabelProvider {
@Override
public String getColumnText(Object element, int columnIndex) {
String text = super.getColumnText(element, columnIndex);
// it's the order of label provider
if (columnIndex == 0) {
IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class);
return getIUNameWithDetail(iu);
}
return text;
}
@Override
public Color getForeground(Object element) {
IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class);
if (hasInstalled(iu))
return Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
return super.getForeground(element);
}
}
@Override
protected ITableLabelProvider getLabelProvider() {
return new ImportFromInstallationLabelProvider();
}
@Override
public void dispose() {
super.dispose();
if (otherInstanceAgent != null) {
otherInstanceAgent.stop();
otherInstanceAgent = null;
toBeImportedProfile = null;
}
if (getWizard().performCancel())
cleanLocalRepository();
}
public void cleanLocalRepository() {
if (metaURIs != null && metaURIs.length > 0) {
IProvisioningAgent runningAgent = getProvisioningUI().getSession().getProvisioningAgent();
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) runningAgent.getService(IMetadataRepositoryManager.SERVICE_NAME);
for (URI uri : metaURIs)
manager.removeRepository(uri);
IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) runningAgent.getService(IArtifactRepositoryManager.SERVICE_NAME);
for (URI uri : artiURIs)
artifactManager.removeRepository(uri);
}
}
public Object[] getCheckedIUElements() {
return viewer.getCheckedElements();
}
public Object[] getSelectedIUElements() {
// TODO Auto-generated method stub
return null;
}
public void setCheckedElements(Object[] elements) {
new UnsupportedOperationException();
}
public ProvisioningContext getProvisioningContext() {
ProvisioningContext context = new ProvisioningContext(getProvisioningUI().getSession().getProvisioningAgent());
context.setArtifactRepositories(artiURIs);
context.setMetadataRepositories(metaURIs);
return context;
}
}