/******************************************************************************* | |
* 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; | |
} | |
} |