/*******************************************************************************
* 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.editor.cspec;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.buckminster.core.common.model.ExpandingProperties;
import org.eclipse.buckminster.core.cspec.builder.ActionArtifactBuilder;
import org.eclipse.buckminster.core.cspec.builder.ActionBuilder;
import org.eclipse.buckminster.core.cspec.builder.ArtifactBuilder;
import org.eclipse.buckminster.core.cspec.builder.CSpecBuilder;
import org.eclipse.buckminster.core.cspec.builder.PrerequisiteBuilder;
import org.eclipse.buckminster.core.cspec.builder.PrerequisitesBuilder;
import org.eclipse.buckminster.core.cspec.model.PrerequisiteAlreadyDefinedException;
import org.eclipse.buckminster.core.cspec.model.UpToDatePolicy;
import org.eclipse.buckminster.core.helpers.TextUtils;
import org.eclipse.buckminster.osgi.filter.FilterFactory;
import org.eclipse.buckminster.ui.Messages;
import org.eclipse.buckminster.ui.UiUtils;
import org.eclipse.buckminster.ui.editor.EditorUtils;
import org.eclipse.buckminster.ui.general.editor.ValidatorException;
import org.eclipse.buckminster.ui.general.editor.simple.SimpleTableEditor;
import org.eclipse.buckminster.ui.general.editor.structured.FieldModifyEvent;
import org.eclipse.buckminster.ui.general.editor.structured.IFieldModifyListener;
import org.eclipse.buckminster.ui.general.editor.structured.TwoPagesTableEditor;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.osgi.framework.InvalidSyntaxException;
/**
* @author Karel Brezina
*
*/
public class ActionsTable extends AttributesTable<ActionBuilder> {
private Map<ActionBuilder, List<ActionArtifactBuilder>> actionArtifacts;
private Text actorNameText;
private Button alwaysCheck;
private Button assignConsoleSupportCheck;
private Text actionFilter;
private Combo upToDatePolicy;
private Text fileCountText;
private Text additionalFileCountText;
private Text prodAliasText;
private Text prodBaseText;
private List<Property> actorProperties = new ArrayList<Property>();
private SimpleTableEditor<Property> actorPropertiesEditor;
private Button pathsButton;
private List<PathWrapper> productPaths = new ArrayList<PathWrapper>();
private SimpleTableEditor<PathWrapper> productPathsEditor;
private Button artifactsButton;
private List<ArtifactBuilder> productArtifacts = new ArrayList<ArtifactBuilder>();
private TwoPagesTableEditor<ArtifactBuilder> productArtifactsEditor;
private List<Property> properties = new ArrayList<Property>();
private SimpleTableEditor<Property> propertiesEditor;
private Text prereqNameText;
private Text prereqRebasePathText;
private List<PrerequisiteBuilder> prerequisites = new ArrayList<PrerequisiteBuilder>();
private SimpleTableEditor<PrerequisiteBuilder> prerequisitesEditor;
public ActionsTable(CSpecEditor editor, List<ActionBuilder> data, Map<ActionBuilder, List<ActionArtifactBuilder>> actionArtifacts,
CSpecBuilder cspec, boolean readOnly) {
super(editor, data, cspec, readOnly);
this.actionArtifacts = actionArtifacts;
}
@Override
public void enableFields(boolean enabled) {
super.enableFields(enabled);
actorNameText.setEnabled(enabled);
alwaysCheck.setEnabled(enabled);
assignConsoleSupportCheck.setEnabled(enabled);
actionFilter.setEnabled(enabled);
upToDatePolicy.setEnabled(enabled);
refreshFileCountFields();
prodAliasText.setEnabled(enabled);
prodBaseText.setEnabled(enabled);
actorPropertiesEditor.setEnabled(enabled);
pathsButton.setEnabled(enabled);
productPathsEditor.setEnabled(enabled && pathsButton.getSelection());
artifactsButton.setEnabled(enabled);
productArtifactsEditor.setEnabled(enabled && artifactsButton.getSelection());
propertiesEditor.setEnabled(enabled);
prereqNameText.setEnabled(enabled);
prereqRebasePathText.setEnabled(enabled);
prerequisitesEditor.setEnabled(enabled);
}
@Override
public void fillStack(Composite stackComposite) {
addStackMapping(Messages.general, createGeneralStackLayer(stackComposite));
addStackMapping(Messages.properties, createPropertiesStackLayer(stackComposite));
addStackMapping(Messages.products, createProductsStackLayer(stackComposite));
addStackMapping(Messages.documentation, createDocumentationStackLayer(stackComposite));
}
@Override
protected ActionBuilder createNewRow() {
return getCSpecBuilder().createActionBuilder();
}
@Override
protected void refreshRow(ActionBuilder builder) {
super.refreshRow(builder);
actorNameText.setText(TextUtils.notNullString(builder.getActorName()));
alwaysCheck.setSelection(builder.isAlways());
assignConsoleSupportCheck.setSelection(builder.isAssignConsoleSupport());
actionFilter.setText(TextUtils.notNullString(builder.getFilter()));
upToDatePolicy.select(builder.getUpToDatePolicy().ordinal());
switch (builder.getUpToDatePolicy()) {
case COUNT:
fileCountText.setText(String.valueOf(builder.getProductFileCount()));
additionalFileCountText.setText(""); //$NON-NLS-1$
break;
case MAPPER:
fileCountText.setText(""); //$NON-NLS-1$
additionalFileCountText.setText(String.valueOf(builder.getProductFileCount()));
break;
default:
fileCountText.setText(""); //$NON-NLS-1$
additionalFileCountText.setText(""); //$NON-NLS-1$
}
refreshFileCountFields();
prodAliasText.setText(TextUtils.notNullString(builder.getProductAlias()));
IPath prodBasePath = builder.getProductBase();
prodBaseText.setText(TextUtils.notNullString(prodBasePath == null ? null : prodBasePath.toOSString()));
CSpecEditorUtils.copyAndSortItems(builder.getActorProperties(), actorProperties);
actorPropertiesEditor.refresh();
CSpecEditorUtils.copyAndSortItems(builder.getProductPaths(), productPaths);
productPathsEditor.refresh();
CSpecEditorUtils.copyAndSortItems(actionArtifacts.get(builder), productArtifacts, CSpecEditorUtils.getAttributeComparator());
createProductArtifactsCopy();
productArtifactsEditor.refresh();
chooseProductPathsButton(productPaths.size() > 0 || productArtifacts.size() == 0);
CSpecEditorUtils.copyAndSortItems(builder.getProperties(), properties);
propertiesEditor.refresh();
PrerequisitesBuilder prereqBuilder = builder.getPrerequisitesBuilder();
prereqNameText.setText(TextUtils.notNullString(prereqBuilder.getName()));
IPath rebasePath = prereqBuilder.getPrerequisiteRebase();
prereqRebasePathText.setText(TextUtils.notNullString(rebasePath == null ? null : rebasePath.toOSString()));
CSpecEditorUtils.copyAndSortItems(prereqBuilder.getPrerequisites(), prerequisites, CSpecEditorUtils.getPrerequisiteComparator());
prerequisitesEditor.refresh();
}
@Override
protected void setRowValues(ActionBuilder builder) throws ValidatorException {
super.setRowValues(builder);
builder.setActorName(UiUtils.trimmedValue(actorNameText));
builder.setAlways(alwaysCheck.getSelection());
builder.setAssignConsoleSupport(assignConsoleSupportCheck.getSelection());
String filterStr = UiUtils.trimmedValue(actionFilter);
if (filterStr != null) {
try {
builder.setFilter(FilterFactory.newInstance(filterStr));
} catch (InvalidSyntaxException e) {
throw new ValidatorException(e.getMessage());
}
} else
builder.setFilter(null);
builder.setUpToDatePolicy(UpToDatePolicy.values()[upToDatePolicy.getSelectionIndex()]);
Text validFileCountField = null;
switch (builder.getUpToDatePolicy()) {
case COUNT:
validFileCountField = fileCountText;
break;
case MAPPER:
validFileCountField = additionalFileCountText;
break;
}
String fileCount = UiUtils.trimmedValue(validFileCountField);
if (fileCount != null)
try {
builder.setProductFileCount(Integer.valueOf(fileCount).intValue());
} catch (NumberFormatException e) {
throw new ValidatorException(Messages.invalid_number + ": " + fileCount); //$NON-NLS-1$
}
builder.setProductAlias(UiUtils.trimmedValue(prodAliasText));
String prodBasePathString = UiUtils.trimmedValue(prodBaseText);
IPath prodBasePath = null;
if (prodBasePathString != null) {
prodBasePath = Path.fromOSString(prodBasePathString);
}
builder.setProductBase(prodBasePath);
ExpandingProperties<String> props = builder.getActorProperties();
if (props != null) {
props.clear();
}
for (Property property : actorProperties) {
builder.addActorProperty(property.getKey(), property.getValue(), true);
}
Set<IPath> paths = builder.getProductPaths();
if (paths != null) {
paths.clear();
}
// save only if selected
if (pathsButton.getSelection()) {
for (PathWrapper path : productPaths) {
IPath p = path.getPath();
if (p == null)
continue;
builder.addProductPath(p);
}
}
actionArtifacts.remove(builder);
// save only if selected
if (artifactsButton.getSelection()) {
if (productArtifacts.size() > 0) {
List<ActionArtifactBuilder> list = new ArrayList<ActionArtifactBuilder>();
for (ArtifactBuilder artifactBuilder : productArtifacts) {
((ActionArtifactBuilder) artifactBuilder).setActionName(builder.getName());
list.add((ActionArtifactBuilder) artifactBuilder);
}
actionArtifacts.put(builder, list);
}
}
props = builder.getProperties();
if (props != null) {
props.clear();
}
for (Property property : properties) {
builder.addProperty(property.getKey(), property.getValue(), true);
}
PrerequisitesBuilder prereqBuilder = builder.getPrerequisitesBuilder();
prereqBuilder.setName(UiUtils.trimmedValue(prereqNameText));
String rebasePathString = UiUtils.trimmedValue(prereqRebasePathText);
IPath rebasePath = null;
if (rebasePathString != null) {
rebasePath = Path.fromOSString(rebasePathString);
}
prereqBuilder.setPrerequisiteRebase(rebasePath);
List<PrerequisiteBuilder> prereqs = prereqBuilder.getPrerequisites();
if (prereqs != null) {
prereqs.clear();
}
for (PrerequisiteBuilder prerequisite : prerequisites) {
// Original "prerequisite" is created with a different
// PrerequisitesBuilder (an empty one)
// Need to created again and copy attributes
PrerequisiteBuilder newPrerequisite = prereqBuilder.createPrerequisiteBuilder();
newPrerequisite.initFrom(prerequisite.createPrerequisite());
try {
prereqBuilder.addPrerequisite(newPrerequisite);
} catch (PrerequisiteAlreadyDefinedException e) {
throw new ValidatorException(e.getMessage());
}
}
}
void showProductArtifact(ArtifactBuilder builder) {
// find according to name
ArtifactBuilder foundBuilder = null;
for (ArtifactBuilder item : productArtifacts) {
if (item.getName().equals(builder.getName())) {
foundBuilder = item;
break;
}
}
if (foundBuilder != null) {
productArtifactsEditor.setFocus();
productArtifactsEditor.show(foundBuilder);
}
}
private void chooseProductPathsButton(boolean choose) {
pathsButton.setSelection(choose);
artifactsButton.setSelection(!choose);
if (pathsButton.getEnabled())
enableProductPathsEditor(choose);
}
@SuppressWarnings("unchecked")
private Control createGeneralStackLayer(Composite stackComposite) {
Composite geComposite = new Composite(stackComposite, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = layout.marginWidth = 0;
geComposite.setLayout(layout);
EditorUtils.createHeaderLabel(geComposite, Messages.general, 2);
UiUtils.createGridLabel(geComposite, Messages.name_with_colon, 1, 0, SWT.NONE);
setNameText(UiUtils.createGridText(geComposite, 1, 0, isReadOnly(), SWT.NONE));
UiUtils.createGridLabel(geComposite, Messages.public_with_colon, 1, 0, SWT.NONE);
setPublicCheck(UiUtils.createCheckButton(geComposite, null, isReadOnly(), null));
UiUtils.createGridLabel(geComposite, Messages.actor_name_with_colon, 1, 0, SWT.NONE);
actorNameText = UiUtils.createGridText(geComposite, 1, 0, isReadOnly(), SWT.NONE);
actorNameText.addModifyListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.always_with_colon, 1, 0, SWT.NONE);
alwaysCheck = UiUtils.createCheckButton(geComposite, null, isReadOnly(), null);
alwaysCheck.addSelectionListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.assign_console_support_with_colon, 1, 0, SWT.NONE);
assignConsoleSupportCheck = UiUtils.createCheckButton(geComposite, null, isReadOnly(), null);
assignConsoleSupportCheck.addSelectionListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.filter_with_colon, 1, 0, SWT.NONE);
actionFilter = UiUtils.createGridText(geComposite, 1, 0, isReadOnly(), SWT.NONE);
actionFilter.addModifyListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.uptodate_policy, 1, 0, SWT.NONE);
upToDatePolicy = UiUtils.createGridEnumCombo(geComposite, 1, 0, UpToDatePolicy.values(), isReadOnly(), null, FIELD_LISTENER, SWT.DROP_DOWN
| SWT.READ_ONLY);
addFieldModifyListener(new IFieldModifyListener() {
@Override
public void modifyField(FieldModifyEvent e) {
if (e.getOriginalEvent() instanceof ModifyEvent && ((ModifyEvent) e.getOriginalEvent()).getSource() == upToDatePolicy)
refreshFileCountFields();
}
});
fileCountText = UiUtils.createLabeledText(geComposite, Messages.file_count, isReadOnly(), SWT.NONE);
fileCountText.addModifyListener(FIELD_LISTENER);
additionalFileCountText = UiUtils.createLabeledText(geComposite, Messages.additional_file_count, isReadOnly(), SWT.NONE);
additionalFileCountText.addModifyListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.prerequisites_alias_with_colon, 1, 0, SWT.NONE);
prereqNameText = UiUtils.createGridText(geComposite, 1, 0, isReadOnly(), SWT.NONE);
prereqNameText.addModifyListener(FIELD_LISTENER);
UiUtils.createGridLabel(geComposite, Messages.prerequisites_rebase_path_with_colon, 1, 0, SWT.NONE);
prereqRebasePathText = UiUtils.createGridText(geComposite, 1, 0, isReadOnly(), SWT.NONE);
prereqRebasePathText.addModifyListener(FIELD_LISTENER);
UiUtils.createEmptyLabel(geComposite);
UiUtils.createEmptyLabel(geComposite);
Label label = UiUtils.createGridLabel(geComposite, Messages.prerequisites_with_colon, 1, 0, SWT.NONE);
GridData gridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
gridData.horizontalSpan = 2;
label.setLayoutData(gridData);
// Uses an empty GroupBuilder (createNewRow())
// "PrerequisiteBuilder"s will be created with this empty GroupBuilder
// Need to create "PrerequisiteBuilder"s again while saving them
PrerequisitesTable preTable = new PrerequisitesTable(getCSpecEditor(), this, prerequisites, createNewRow().getPrerequisitesBuilder(),
isReadOnly());
preTable.addTableModifyListener(FIELD_LISTENER);
prerequisitesEditor = new SimpleTableEditor<PrerequisiteBuilder>(geComposite, preTable, null, Messages.action_prerequisite_with_dash, null,
null, SWT.NONE);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 2;
prerequisitesEditor.setLayoutData(gridData);
geComposite.setData("focusControl", getNameText()); //$NON-NLS-1$
return geComposite;
}
private void createProductArtifactsCopy() {
for (int i = 0; i < productArtifacts.size(); i++) {
ActionArtifactBuilder builder = (ActionArtifactBuilder) productArtifacts.get(i);
ActionArtifactBuilder newBuilder = getCSpecBuilder().createActionArtifactBuilder();
newBuilder.initFrom(builder.createAttribute());
productArtifacts.set(i, newBuilder);
}
}
@SuppressWarnings("unchecked")
private Control createProductsStackLayer(Composite stackComposite) {
Composite composite = new Composite(stackComposite, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = layout.marginWidth = 0;
composite.setLayout(layout);
EditorUtils.createHeaderLabel(composite, Messages.products, 2);
UiUtils.createGridLabel(composite, Messages.product_alias_with_colon, 1, 0, SWT.NONE);
prodAliasText = UiUtils.createGridText(composite, 1, 0, isReadOnly(), SWT.NONE);
prodAliasText.addModifyListener(FIELD_LISTENER);
UiUtils.createGridLabel(composite, Messages.product_base_path_with_colon, 1, 0, SWT.NONE);
prodBaseText = UiUtils.createGridText(composite, 1, 0, isReadOnly(), SWT.NONE);
prodBaseText.addModifyListener(FIELD_LISTENER);
UiUtils.createEmptyLabel(composite);
UiUtils.createEmptyLabel(composite);
pathsButton = new Button(composite, SWT.RADIO);
pathsButton.setText(Messages.product_paths_with_colon);
GridData gridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
gridData.horizontalSpan = 2;
pathsButton.setLayoutData(gridData);
pathsButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
enableProductPathsEditor(true);
}
});
PathsTable table = new PathsTable(productPaths, isReadOnly());
table.addTableModifyListener(FIELD_LISTENER);
productPathsEditor = new SimpleTableEditor<PathWrapper>(composite, table, null, Messages.action_product_path_with_dash, null, null, SWT.NONE);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 2;
productPathsEditor.setLayoutData(gridData);
UiUtils.createEmptyLabel(composite);
UiUtils.createEmptyLabel(composite);
artifactsButton = new Button(composite, SWT.RADIO);
artifactsButton.setText(Messages.product_artifacts);
gridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
gridData.horizontalSpan = 2;
artifactsButton.setLayoutData(gridData);
artifactsButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
enableProductPathsEditor(false);
}
});
ArtifactsTable artifactsTable = new ArtifactsTable(getCSpecEditor(), productArtifacts, getCSpecBuilder(), isReadOnly()) {
@Override
protected ArtifactBuilder createNewRow() {
return getCSpecBuilder().createActionArtifactBuilder();
}
};
artifactsTable.addTableModifyListener(FIELD_LISTENER);
productArtifactsEditor = new TwoPagesTableEditor<ArtifactBuilder>(composite, artifactsTable, false, null,
Messages.action_product_artifact_with_dash, null, null, SWT.NONE);
gridData = new GridData(GridData.FILL_BOTH);
gridData.horizontalSpan = 2;
productArtifactsEditor.setLayoutData(gridData);
composite.setData("focusControl", prodAliasText); //$NON-NLS-1$
return composite;
}
@SuppressWarnings("unchecked")
private Control createPropertiesStackLayer(Composite stackComposite) {
Composite composite = new Composite(stackComposite, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = layout.marginWidth = 0;
composite.setLayout(layout);
EditorUtils.createHeaderLabel(composite, Messages.general_properties, 1);
PropertiesTable table = new PropertiesTable(properties, isReadOnly());
table.addTableModifyListener(FIELD_LISTENER);
propertiesEditor = new SimpleTableEditor<Property>(composite, table, null, Messages.action_properties_with_dash, null, null, SWT.NONE);
UiUtils.createEmptyLabel(composite);
EditorUtils.createHeaderLabel(composite, Messages.actor_properties, 1);
table = new PropertiesTable(actorProperties, isReadOnly());
table.addTableModifyListener(FIELD_LISTENER);
actorPropertiesEditor = new SimpleTableEditor<Property>(composite, table, null, Messages.action_actor_properties_with_dash, null, null,
SWT.NONE);
return composite;
}
private void enableProductPathsEditor(boolean enable) {
productPathsEditor.setEnabled(enable);
productArtifactsEditor.setEnabled(!enable);
}
private void refreshFileCountFields() {
boolean fileCountEnabled = false;
boolean additionalFileCountEnabled = false;
if (upToDatePolicy.isEnabled()) {
switch (UpToDatePolicy.values()[upToDatePolicy.getSelectionIndex()]) {
case COUNT:
fileCountEnabled = true;
break;
case MAPPER:
additionalFileCountEnabled = true;
break;
}
}
fileCountText.setEnabled(fileCountEnabled);
additionalFileCountText.setEnabled(additionalFileCountEnabled);
}
}