blob: 430da8da236e3a0518746d62402d964c223ecc4d [file] [log] [blame]
/*
* Copyright (c) 2022 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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.cdo.lm.ui.actions;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.lm.Drop;
import org.eclipse.emf.cdo.lm.DropType;
import org.eclipse.emf.cdo.lm.FloatingBaseline;
import org.eclipse.emf.cdo.lm.Stream;
import org.eclipse.emf.cdo.lm.client.ISystemDescriptor;
import org.eclipse.emf.cdo.lm.client.ISystemManager;
import org.eclipse.emf.cdo.lm.modules.ModuleDefinition;
import org.eclipse.emf.cdo.lm.provider.LMEditPlugin;
import org.eclipse.emf.cdo.lm.ui.widgets.TimeStampComposite;
import org.eclipse.net4j.util.ui.UIUtil;
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.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPage;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author Eike Stepper
*/
public class NewDropAction extends LMAction<Stream>
{
private static final long INVALID_DATE = CDOBranchPoint.INVALID_DATE;
private final DropType dropType;
private ISystemDescriptor systemDescriptor;
private long startTimeStamp;
private long timeStamp;
private String timeStampError;
private Text versionText;
private Job versionExtractionJob;
private AtomicLong versionExtractionTimeStamp = new AtomicLong(INVALID_DATE);
private String labelString;
private Text labelText;
public NewDropAction(IWorkbenchPage page, Stream stream, DropType dropType)
{
super(page, //
"New " + dropType.getName() + INTERACTIVE, //
"Add a new " + dropType.getName().toLowerCase() + " to stream '" + stream.getName() + "'", //
ExtendedImageRegistry.INSTANCE.getImageDescriptor(LMEditPlugin.INSTANCE.getImage(dropType.isRelease() ? "full/obj16/Release" : "full/obj16/Drop")), //
"Add a new " + dropType.getName().toLowerCase() + " to stream '" + stream.getName() + "'.", //
dropType.isRelease() ? "icons/NewRelease.png" : "icons/NewDrop.png", //
stream);
this.dropType = dropType;
}
@Override
protected void preRun() throws Exception
{
Stream stream = getContext();
systemDescriptor = ISystemManager.INSTANCE.getDescriptor(stream.getSystem());
startTimeStamp = stream.getStartTimeStamp();
if (dropType.isRelease())
{
Drop lastRelease = stream.getLastRelease();
if (lastRelease != null)
{
startTimeStamp = lastRelease.getBranchPoint().getTimeStamp() + 1;
}
}
super.preRun();
}
@Override
protected void fillDialogArea(LMDialog dialog, Composite parent)
{
Stream stream = getContext();
{
Label label = new Label(parent, SWT.NONE);
label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).create());
label.setText("Time stamp:");
TimeStampComposite timeStampComposite = new TimeStampComposite(parent, SWT.NONE, startTimeStamp, CDOBranchPoint.UNSPECIFIED_DATE, stream);
timeStampComposite.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).create());
timeStampComposite.addModifyListener((control, timeStamp, error) -> {
NewDropAction.this.timeStamp = timeStamp;
timeStampError = error;
validateDialog();
scheduleVersionExtraction(stream);
});
timeStampComposite.setTimeStamp(java.lang.System.currentTimeMillis());
}
{
Label label = new Label(parent, SWT.NONE);
label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).create());
label.setText("Version:");
versionText = new Text(parent, SWT.BORDER | SWT.READ_ONLY);
versionText.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).create());
}
{
Label label = new Label(parent, SWT.NONE);
label.setLayoutData(GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).create());
label.setText("Label:");
labelText = new Text(parent, SWT.BORDER | SWT.SINGLE);
labelText.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).create());
labelText.addModifyListener(e -> {
labelString = labelText.getText();
validateDialog();
});
labelText.setFocus();
labelText.selectAll();
}
}
@Override
protected String doValidate(LMDialog dialog)
{
if (timeStamp == INVALID_DATE)
{
return timeStampError == null ? "A time stamp must be entered" : timeStampError;
}
if (labelString == null || labelString.isEmpty())
{
return "A label must be entered.";
}
return super.doValidate(dialog);
}
@Override
protected void doRun(Stream stream, IProgressMonitor monitor) throws Exception
{
systemDescriptor.createDrop(stream, dropType, timeStamp, labelString, monitor);
}
private void scheduleVersionExtraction(FloatingBaseline baseline)
{
synchronized (versionExtractionTimeStamp)
{
versionExtractionTimeStamp.set(timeStamp);
if (timeStamp == INVALID_DATE)
{
if (versionExtractionJob != null)
{
versionExtractionJob.cancel();
versionExtractionJob = null;
}
setVersionString("", false);
}
else
{
if (versionExtractionJob == null)
{
versionExtractionJob = new Job("Extract Version")
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
while (!monitor.isCanceled())
{
long timeStampToUse;
synchronized (versionExtractionTimeStamp)
{
timeStampToUse = versionExtractionTimeStamp.getAndSet(INVALID_DATE);
}
if (timeStampToUse == INVALID_DATE)
{
break;
}
extractVersion(timeStampToUse);
}
return Status.OK_STATUS;
}
private void extractVersion(long timeStamp)
{
ModuleDefinition moduleDefinition = //
systemDescriptor.extractModuleDefinition(baseline, timeStamp);
Version moduleVersion = moduleDefinition.getVersion();
int major = (int)moduleVersion.getSegment(0);
int minor = (int)moduleVersion.getSegment(1);
int micro = (int)moduleVersion.getSegment(2);
setVersionString(major + "." + minor + "." + micro, true);
}
};
versionExtractionJob.schedule();
}
}
}
}
private void setVersionString(String versionString, boolean fromJob)
{
UIUtil.asyncExec(getDisplay(), () -> {
if (!versionText.isDisposed())
{
if (fromJob)
{
synchronized (versionExtractionTimeStamp)
{
if (versionExtractionJob == null)
{
return;
}
}
}
versionText.setText(versionString);
labelText.setText(versionString);
labelText.selectAll();
}
});
}
}