/*****************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
*****************************************************************************/
package org.eclipse.buckminster.ui.wizards;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.buckminster.core.CorePlugin;
import org.eclipse.buckminster.core.RMContext;
import org.eclipse.buckminster.core.commands.SetPreference;
import org.eclipse.buckminster.core.common.model.ExpandingProperties;
import org.eclipse.buckminster.core.helpers.AccessibleByteArrayOutputStream;
import org.eclipse.buckminster.core.helpers.FileUtils;
import org.eclipse.buckminster.core.metadata.model.BillOfMaterials;
import org.eclipse.buckminster.core.mspec.builder.MaterializationSpecBuilder;
import org.eclipse.buckminster.core.mspec.model.MaterializationSpec;
import org.eclipse.buckminster.core.parser.IParserFactory;
import org.eclipse.buckminster.core.query.model.ComponentQuery;
import org.eclipse.buckminster.core.resolver.IResolver;
import org.eclipse.buckminster.core.resolver.MainResolver;
import org.eclipse.buckminster.core.resolver.ResolutionContext;
import org.eclipse.buckminster.download.DownloadManager;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.buckminster.runtime.IOUtils;
import org.eclipse.buckminster.runtime.MonitorUtils;
import org.eclipse.buckminster.runtime.URLUtils;
import org.eclipse.buckminster.ui.Messages;
import org.eclipse.buckminster.ui.UiUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/**
* @author Thomas Hallgren
*/
public class SelectBOMPage extends AbstractQueryPage {
private Label topComponentLabel;
private Text fileNameText;
private Text topComponent;
private Button loadButton;
private URL bomOrMSpecURL;
public SelectBOMPage(IStructuredSelection selection) {
super(""); //$NON-NLS-1$
if (selection != null && selection.size() == 1) {
Object selected = selection.getFirstElement();
if (selected instanceof IFile) {
IPath location = ((IFile) selected).getLocation();
if (location != null) {
try {
bomOrMSpecURL = location.toFile().toURI().toURL();
} catch (MalformedURLException e) {
// ignore
}
}
}
}
}
@Override
public void pageIsShowing() {
QueryWizard qw = getQueryWizard();
if (bomOrMSpecURL != null && !qw.hasBOM()) {
loadBomOrMSpec();
if (bomOrMSpecURL != null)
fileNameText.setText(bomOrMSpecURL.toString());
}
}
@Override
public void setErrorMessage(String message) {
QueryWizard qw = getQueryWizard();
if (message != null) {
bomOrMSpecURL = null;
qw.resetBOM();
}
super.setErrorMessage(message);
if (qw.hasBOM()) {
if (!isPageComplete()) {
try {
topComponent.setText(qw.getBOM().getViewName());
topComponentLabel.setVisible(true);
topComponent.setVisible(true);
setPageComplete(true);
} catch (CoreException e) {
displayException(e);
qw.resetBOM();
}
}
} else {
if (isPageComplete()) {
topComponentLabel.setVisible(false);
topComponent.setVisible(false);
setPageComplete(false);
}
}
}
@Override
protected Composite createControls(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Label lbl = new Label(composite, SWT.NONE);
lbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));
lbl.setText(Messages.enter_url_of_mspec_bom_cquery);
lbl.setToolTipText(Messages.enter_url_that_appoints_mspec_bom_cquery);
fileNameText = new Text(composite, SWT.BORDER);
fileNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
fileNameText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent me) {
setBomOrMSpecFile(UiUtils.trimmedValue((Text) me.widget));
}
});
Button browseButton = UiUtils.createPushButton(composite, Messages.browse_with_dots, new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent se) {
FileDialog dlg = new FileDialog(getShell());
dlg.setFilterExtensions(new String[] { "*.mspec", "*.cquery", "*.bom" }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String name = dlg.open();
if (name != null)
fileNameText.setText(name);
}
});
browseButton.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
loadButton = UiUtils.createPushButton(composite, Messages.load, new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent se) {
loadBomOrMSpec();
}
});
loadButton.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
loadButton.setEnabled(false);
topComponentLabel = new Label(composite, SWT.NONE);
topComponentLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 3, 1));
topComponentLabel.setText(Messages.top_component_of_loaded_bom);
topComponentLabel.setVisible(false);
topComponent = new Text(composite, SWT.BORDER);
topComponent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
topComponent.setEditable(false);
topComponent.setVisible(false);
setControl(composite);
setPageComplete(false);
return composite;
}
void loadBomOrMSpec() {
try {
getContainer().run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
URL urlToParse = bomOrMSpecURL;
InputStream input = null;
monitor.beginTask(null, 100);
try {
AccessibleByteArrayOutputStream byteBld = new AccessibleByteArrayOutputStream();
QueryWizard wizard = getQueryWizard();
MaterializationSpecBuilder mspecBld = wizard.getMaterializationSpec();
DownloadManager.readInto(urlToParse, null, byteBld, MonitorUtils.subMonitor(monitor, 20));
input = byteBld.getInputStream();
IParserFactory pf = CorePlugin.getDefault().getParserFactory();
MaterializationSpec mspec = null;
String path = urlToParse.getPath();
if (!(path.endsWith(".cquery") || path.endsWith(".bom"))) //$NON-NLS-1$ //$NON-NLS-2$
{
try {
mspec = pf.getMaterializationSpecParser(true).parse(urlToParse.toString(), input);
} catch (CoreException e) {
// Assume this was not an mspec
//
if (urlToParse.getPath().endsWith(".mspec")) //$NON-NLS-1$
throw e;
}
}
MonitorUtils.worked(monitor, 5);
IPath newTpLocation = null;
if (mspec != null) {
mspecBld.initFrom(mspec);
urlToParse = mspec.getResolvedURL();
byteBld.reset();
DownloadManager.readInto(urlToParse, null, byteBld, MonitorUtils.subMonitor(monitor, 20));
newTpLocation = mspec.getInstallLocation();
} else {
mspecBld.setURL(urlToParse.toString());
MonitorUtils.worked(monitor, 20);
}
input = byteBld.getInputStream();
BillOfMaterials bom;
ComponentQuery cquery = null;
if (!urlToParse.getPath().endsWith(".bom")) //$NON-NLS-1$
{
try {
cquery = ComponentQuery.fromStream(urlToParse, null, input, true);
} catch (CoreException e) {
// Assume this was not a cquery, restart input
//
if (urlToParse.getPath().endsWith(".cquery")) //$NON-NLS-1$
throw e;
}
}
MonitorUtils.worked(monitor, 5);
if (newTpLocation != null)
SetPreference
.set("targetPlatformPath", ExpandingProperties.expand(RMContext.getGlobalPropertyAdditions(), newTpLocation.toPortableString(), 0));//$NON-NLS-1$
if (cquery != null) {
ResolutionContext ctx = (mspec == null) ? new ResolutionContext(cquery) : new ResolutionContext(mspec, cquery);
IResolver resolver = new MainResolver(ctx);
resolver.getContext().setContinueOnError(true);
bom = resolver.resolve(MonitorUtils.subMonitor(monitor, 40));
} else {
input = byteBld.getInputStream();
bom = pf.getBillOfMaterialsParser(true).parse(urlToParse.toString(), input);
MonitorUtils.worked(monitor, 40);
}
wizard.setBOM(bom);
MonitorUtils.worked(monitor, 10);
} catch (Throwable e) {
throw new InvocationTargetException(e);
} finally {
IOUtils.close(input);
monitor.done();
}
}
});
setErrorMessage(null);
} catch (InterruptedException e) {
} catch (Exception e) {
displayException(BuckminsterException.wrap(e));
}
}
void setBomOrMSpecFile(final String bomFile) {
URL oldBomOrMSPecURL = bomOrMSpecURL;
bomOrMSpecURL = null;
if (bomFile == null) {
setErrorMessage(null);
loadButton.setEnabled(false);
return;
}
URL url;
try {
url = URLUtils.normalizeToURL(bomFile);
url = FileLocator.toFileURL(url);
} catch (IOException e) {
setErrorMessage(Messages.invalid_url_or_filename);
loadButton.setEnabled(false);
return;
}
File file = FileUtils.getFile(url);
if (file == null) {
// URL is remote. Let's assume it's OK for now
//
String path = url.getPath();
if (path == null || path.length() == 0 || path.endsWith("/")) //$NON-NLS-1$
{
setErrorMessage(Messages.url_path_is_not_valid);
loadButton.setEnabled(false);
} else {
bomOrMSpecURL = url;
loadButton.setEnabled(true);
setErrorMessage(null);
}
} else {
loadButton.setEnabled(false);
if (file.isFile() && file.canRead()) {
bomOrMSpecURL = url;
if (oldBomOrMSPecURL == null || !oldBomOrMSPecURL.toExternalForm().equals(bomOrMSpecURL.toExternalForm()))
loadBomOrMSpec();
} else
setErrorMessage(Messages.file_does_not_exist);
}
}
}