/*
Copyright (C) 2006 EBI
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the itmplied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.biomart.builder.view.gui.diagrams.contexts;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import org.biomart.builder.model.Column;
import org.biomart.builder.model.ComponentStatus;
import org.biomart.builder.model.DataSet;
import org.biomart.builder.model.Key;
import org.biomart.builder.model.Relation;
import org.biomart.builder.model.Schema;
import org.biomart.builder.model.Table;
import org.biomart.builder.model.DataSet.DataSetTable;
import org.biomart.builder.model.DataSet.DataSetTableType;
import org.biomart.builder.view.gui.MartTabSet.MartTab;
import org.biomart.builder.view.gui.diagrams.ExplainTransformationDiagram.RealisedRelation;
import org.biomart.builder.view.gui.diagrams.ExplainTransformationDiagram.SkipTempReal;
import org.biomart.builder.view.gui.diagrams.components.KeyComponent;
import org.biomart.builder.view.gui.diagrams.components.RelationComponent;
import org.biomart.builder.view.gui.diagrams.components.SchemaComponent;
import org.biomart.builder.view.gui.diagrams.components.TableComponent;
import org.biomart.common.resources.Resources;
/**
* This context applies to the general schema view, as seen via a dataset tab.
* It allows dataset-specific things such as masked relations to be set up,
* where those things have to be defined against the source schema rather than
* the dataset's generated schema.
*
* @author Richard Holland <holland@ebi.ac.uk>
* @version $Revision: 1.38 $, $Date: 2008-02-01 10:17:56 $, modified by
* $Author: rh4 $
* @since 0.5
*/
public class ExplainContext extends SchemaContext {
private DataSet dataset;
private DataSetTable datasetTable;
/**
* Creates a new context within a given set of tabs, which applies to a
* specific dataset table. All menu options will apply to this dataset, and
* operations working with these datasets will be delegated to the methods
* specified in the tabset.
*
* @param martTab
* the mart tab that the dataset tab appears within.
* @param dataset
* the dataset the table is in.
* @param datasetTable
* the dataset table we are attached to.
*/
public ExplainContext(final MartTab martTab, final DataSet dataset,
final DataSetTable datasetTable) {
super(martTab);
this.dataset = dataset;
this.datasetTable = datasetTable;
}
/**
* Creates a new context within a given set of tabs, which applies to a
* specific dataset. All menu options will apply to this dataset, and
* operations working with these datasets will be delegated to the methods
* specified in the tabset.
*
* @param martTab
* the mart tab that the dataset tab appears within.
* @param dataset
* the dataset we are attached to.
*/
public ExplainContext(final MartTab martTab, final DataSet dataset) {
this(martTab, dataset, null);
}
public void customiseAppearance(final JComponent component,
final Object object) {
if (object instanceof Relation)
this.customiseRelationAppearance(component, (Relation) object,
RealisedRelation.NO_ITERATION);
// Schema objects.
else if (object instanceof Schema) {
final Schema schema = (Schema) object;
final SchemaComponent schcomp = (SchemaComponent) component;
if (this.isMasked(schema))
schcomp.setBackground(SchemaComponent.MASKED_BACKGROUND);
else
schcomp.setBackground(SchemaComponent.BACKGROUND_COLOUR);
schcomp.setRenameable(false);
schcomp.setSelectable(false);
}
// This section customises table objects.
else if (object instanceof Table) {
final Table table = (Table) object;
final TableComponent tblcomp = (TableComponent) component;
// Fade out UNINCLUDED tables.
if (!(object instanceof DataSetTable)
&& (tblcomp.getDiagram() instanceof SkipTempReal || this
.isMasked(table)))
tblcomp.setBackground(TableComponent.MASKED_COLOUR);
// All others are normal.
else
tblcomp.setBackground(TableComponent.BACKGROUND_COLOUR);
if (this.getDataSetTable() != null)
tblcomp.setRestricted(table.getRestrictTable(this.getDataSet(),
this.getDataSetTable().getName()) != null);
}
// This section customises the appearance of key objects within
// table objects in the diagram.
else if (object instanceof Key) {
final KeyComponent keycomp = (KeyComponent) component;
// All are normal.
keycomp.setForeground(KeyComponent.NORMAL_COLOUR);
// Remove drag-and-drop from the key as it does not apply in
// the window context.
keycomp.setDraggable(false);
}
}
public boolean isMasked(final Object object) {
final String schemaPrefix = this.getMartTab()
.getPartitionViewSelection();
// Schemas.
if (object instanceof Schema) {
final Schema schema = (Schema) object;
// Fade out UNINCLUDED schemas.
final Set includedSchs = new HashSet(
this.getDataSetTable() != null ? this.getDataSetTable()
.getIncludedSchemas() : this.getDataSet()
.getIncludedSchemas());
return !includedSchs.contains(schema);
}
// Relations
else if (object instanceof Relation) {
final Relation relation = (Relation) object;
// Fade out all UNINCLUDED and MASKED relations.
if (this.isMasked(relation.getFirstKey().getTable())
|| this.isMasked(relation.getSecondKey().getTable()))
return true;
}
// This section customises table objects.
else if (object instanceof Table) {
final Table table = (Table) object;
// Fade out UNINCLUDED tables.
final Set includedTabs = new HashSet(
this.getDataSetTable() != null ? this.getDataSetTable()
.getIncludedTables() : this.getDataSet()
.getIncludedTables());
// Otherwise, table is masked if it is not included
// or is not valid for this schema prefix.
return !includedTabs.contains(table)
|| !table.existsForPartition(schemaPrefix);
}
// This section is for columns.
else if (object instanceof Column) {
final Column col = (Column) object;
return !col.existsForPartition(schemaPrefix);
}
return false;
}
/**
* See {@link #customiseAppearance(JComponent, Object)} but this applies to
* a particular relation iteration.
*
* @param component
* See {@link #customiseAppearance(JComponent, Object)}.
* @param relation
* the relation.
* @param iteration
* the iteration of the relation, or
* {@link RealisedRelation#NO_ITERATION} for all iterations.
*/
public void customiseRelationAppearance(final JComponent component,
final Relation relation, final int iteration) {
// Is it restricted?
if (this.getDataSetTable() != null)
((RelationComponent) component)
.setRestricted(relation.isRestrictRelation(this
.getDataSet(), this.getDataSetTable().getName())
&& (iteration == RealisedRelation.NO_ITERATION || relation
.getRestrictRelation(this.getDataSet(),
this.getDataSetTable().getName(),
iteration) != null));
// Is it compounded?
((RelationComponent) component)
.setCompounded((this.getDataSetTable() == null ? relation
.getCompoundRelation(this.getDataSet()) : relation
.getCompoundRelation(this.getDataSet(), this
.getDataSetTable().getName())) != null);
// Is it loopback?
((RelationComponent) component)
.setLoopback((this.getDataSetTable() == null ? relation
.getLoopbackRelation(this.getDataSet()) : relation
.getLoopbackRelation(this.getDataSet(), this
.getDataSetTable().getName())) != null);
// Fade out all UNINCLUDED and MASKED relations.
boolean included = this.getDataSetTable() == null ? this.getDataSet()
.getIncludedRelations().contains(relation) : this
.getDataSetTable().getIncludedRelations().contains(relation);
if (!included
|| (this.getDataSetTable() == null ? relation
.isMaskRelation(this.getDataSet()) : relation
.isMaskRelation(this.getDataSet(), this
.getDataSetTable().getName())))
component.setForeground(RelationComponent.MASKED_COLOUR);
// Highlight SUBCLASS relations.
else if (relation.isSubclassRelation(this.getDataSet()))
component.setForeground(RelationComponent.SUBCLASS_COLOUR);
// Highlight UNROLLED relations.
else if (this.getDataSetTable() != null
&& relation.getUnrolledRelation(this.getDataSet()) != null
&& !this.getDataSetTable().getType().equals(
DataSetTableType.DIMENSION))
component.setForeground(RelationComponent.UNROLLED_COLOUR);
// All others are normal.
else
component.setForeground(RelationComponent.NORMAL_COLOUR);
}
/**
* Obtain the dataset that this context is linked with.
*
* @return our dataset.
*/
protected DataSet getDataSet() {
return this.dataset;
}
/**
* Obtain the dataset that this context is linked with.
*
* @return our dataset.
*/
protected DataSetTable getDataSetTable() {
return this.datasetTable;
}
public void populateContextMenu(final JPopupMenu contextMenu,
final Object object) {
if (object instanceof Relation)
this.populateRelationContextMenu(contextMenu, (Relation) object,
RealisedRelation.NO_ITERATION);
// This menu is attached to all table objects.
else if (object instanceof Table) {
// Add a separator if there's other stuff before us.
if (contextMenu.getComponentCount() > 0)
contextMenu.addSeparator();
// Obtain the table object we should refer to.
final Table table = (Table) object;
// Accept/Reject changes - only appear in explain dataset
// table, and only enabled if dataset table includes this table
// and dataset table has visible modified columns from this
// table.
if (this.getDataSetTable() != null) {
final JMenuItem accept = new JMenuItem(Resources
.get("acceptChangesTitle"));
accept.setMnemonic(Resources.get("acceptChangesMnemonic")
.charAt(0));
accept.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestAcceptAll(
ExplainContext.this.getDataSetTable(),
table);
}
});
accept.setEnabled(this.getDataSetTable()
.hasVisibleModifiedFrom(table));
contextMenu.add(accept);
final JMenuItem reject = new JMenuItem(Resources
.get("rejectChangesTitle"));
reject.setMnemonic(Resources.get("rejectChangesMnemonic")
.charAt(0));
reject.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestRejectAll(
ExplainContext.this.getDataSetTable(),
table);
}
});
reject.setEnabled(this.getDataSetTable()
.hasVisibleModifiedFrom(table));
contextMenu.add(reject);
contextMenu.addSeparator();
}
// The mask option allows the user to mask all
// relations on a table.
final JMenuItem mask = new JMenuItem(Resources
.get("maskTableTitle"));
mask.setMnemonic(Resources.get("maskTableMnemonic").charAt(0));
mask.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestMaskAllRelations(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
contextMenu.add(mask);
// The unmask option allows the user to unmask all
// relations on a table.
final JMenuItem unmask = new JMenuItem(Resources
.get("unmaskTableTitle"));
unmask.setMnemonic(Resources.get("unmaskTableMnemonic").charAt(0));
unmask.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestUnmaskAllRelations(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
contextMenu.add(unmask);
contextMenu.addSeparator();
// If it's a restricted table...
if (this.getDataSetTable() != null
&& ((Table) object).getRestrictTable(this.getDataSet(),
this.getDataSetTable().getName()) != null) {
// Option to modify restriction.
final JMenuItem modify = new JMenuItem(Resources
.get("modifyTableRestrictionTitle"), new ImageIcon(
Resources.getResourceAsURL("filter.gif")));
modify.setMnemonic(Resources.get(
"modifyTableRestrictionMnemonic").charAt(0));
modify.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestRestrictTable(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
contextMenu.add(modify);
if (this.getDataSetTable() == null)
modify.setEnabled(false);
} else {
// Add a table restriction.
final JMenuItem restriction = new JMenuItem(Resources
.get("addTableRestrictionTitle"), new ImageIcon(
Resources.getResourceAsURL("filter.gif")));
restriction.setMnemonic(Resources.get(
"addTableRestrictionMnemonic").charAt(0));
restriction.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestRestrictTable(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
contextMenu.add(restriction);
if (this.getDataSetTable() == null)
restriction.setEnabled(false);
}
// Option to remove restriction.
final JMenuItem remove = new JMenuItem(Resources
.get("removeTableRestrictionTitle"));
remove.setMnemonic(Resources.get("removeTableRestrictionMnemonic")
.charAt(0));
remove.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestUnrestrictTable(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
contextMenu.add(remove);
if (this.getDataSetTable() == null
|| table.getRestrictTable(this.getDataSet(), this
.getDataSetTable().getName()) == null)
remove.setEnabled(false);
// Option to set 'big table' value.
final JCheckBoxMenuItem bigTable = new JCheckBoxMenuItem(Resources
.get("bigTableTitle"));
bigTable.setMnemonic(Resources.get("bigTableMnemonic").charAt(0));
bigTable.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestBigTable(ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table);
}
});
bigTable.setSelected((this.getDataSetTable() == null ? table
.getBigTable(this.getDataSet()) : table.getBigTable(this
.getDataSet(), this.getDataSetTable().getName())) > 0);
contextMenu.add(bigTable);
// The transform start option.
final JCheckBoxMenuItem transformStart = new JCheckBoxMenuItem(
Resources.get("transformStartTitle"));
transformStart.setMnemonic(Resources.get("transformStartMnemonic")
.charAt(0));
transformStart.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestTransformStart(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
table, transformStart.isSelected());
}
});
transformStart.setEnabled(this.getDataSetTable() != null
&& this.getDataSetTable().getType().equals(
DataSetTableType.DIMENSION));
transformStart.setSelected(this.getDataSetTable() != null
&& table.isTransformStart(this.getDataSet(), this
.getDataSetTable().getName()));
contextMenu.add(transformStart);
}
}
/**
* See {@link #populateContextMenu(JPopupMenu, Object)} but this applies to
* a particular relation iteration.
*
* @param contextMenu
* See {@link #populateContextMenu(JPopupMenu, Object)}.
* @param relation
* the relation.
* @param iteration
* the iteration of the relation, or
* {@link RealisedRelation#NO_ITERATION} for all iterations.
*/
public void populateRelationContextMenu(final JPopupMenu contextMenu,
final Relation relation, final int iteration) {
// Add a separator if there's other stuff before us.
if (contextMenu.getComponentCount() > 0)
contextMenu.addSeparator();
// Work out what state the relation is already in.
final boolean alternativeJoined = this.getDataSetTable() != null
&& relation.isAlternativeJoin(this.getDataSet(), this
.getDataSetTable().getName());
final boolean incorrect = relation.getStatus().equals(
ComponentStatus.INFERRED_INCORRECT);
final boolean relationMasked = this.getDataSetTable() == null ? relation
.isMaskRelation(this.getDataSet())
: relation.isMaskRelation(this.getDataSet(), this
.getDataSetTable().getName());
final boolean relationRestricted = this.getDataSetTable() != null
&& relation.isRestrictRelation(this.getDataSet(), this
.getDataSetTable().getName())
&& (iteration == RealisedRelation.NO_ITERATION || relation
.getRestrictRelation(this.getDataSet(), this
.getDataSetTable().getName(), iteration) != null);
final boolean relationSubclassed = relation.isSubclassRelation(this
.getDataSet());
final boolean relationCompounded = (this.getDataSetTable() == null ? relation
.getCompoundRelation(this.getDataSet())
: relation.getCompoundRelation(this.getDataSet(), this
.getDataSetTable().getName())) != null;
final boolean relationUnrolled = this.getDataSetTable() == null ? false
: relation.getUnrolledRelation(this.getDataSet()) != null
&& !this.getDataSetTable().getType().equals(
DataSetTableType.DIMENSION);
final boolean relationForced = this.getDataSetTable() == null ? relation
.isForceRelation(this.getDataSet())
: relation.isForceRelation(this.getDataSet(), this
.getDataSetTable().getName());
final boolean relationIncluded = this.getDataSetTable() == null ? this
.getDataSet().getIncludedRelations().contains(relation) : this
.getDataSetTable().getIncludedRelations().contains(relation);
final boolean relationLoopbacked = (this.getDataSetTable() == null ? relation
.getLoopbackRelation(this.getDataSet())
: relation.getLoopbackRelation(this.getDataSet(), this
.getDataSetTable().getName())) != null;
// The mask/unmask option allows the user to mask/unmask a relation.
final JCheckBoxMenuItem mask = new JCheckBoxMenuItem(Resources
.get("maskRelationTitle"));
mask.setMnemonic(Resources.get("maskRelationMnemonic").charAt(0));
mask.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestMaskRelation(ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation, mask.isSelected());
}
});
contextMenu.add(mask);
if (incorrect || relationUnrolled || !relationMasked
&& !relationIncluded)
mask.setEnabled(false);
if (relationMasked)
mask.setSelected(true);
// The mask/unmask option allows the user to alternative-join a
// relation.
final JCheckBoxMenuItem join = new JCheckBoxMenuItem(Resources
.get("alternativeJoinTitle"));
join.setMnemonic(Resources.get("alternativeJoinMnemonic").charAt(0));
join.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this
.getMartTab()
.getDataSetTabSet()
.requestAlternativeJoin(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation,
ExplainContext.this.getDataSetTable().getType()
.equals(DataSetTableType.DIMENSION) ? join
.isSelected()
: !join.isSelected());
}
});
contextMenu.add(join);
if (this.getDataSetTable() == null || incorrect || relationUnrolled
|| relationMasked || !relationIncluded)
join.setEnabled(false);
join.setSelected(this.getDataSetTable() != null
&& (this.getDataSetTable().getType().equals(
DataSetTableType.DIMENSION) ? alternativeJoined
: !alternativeJoined));
// The loopback option allows the user to loopback include a relation
// that would otherwise only be included once.
final JCheckBoxMenuItem loopback = new JCheckBoxMenuItem(Resources
.get("loopbackRelationTitle"));
loopback.setMnemonic(Resources.get("loopbackRelationMnemonic")
.charAt(0));
loopback.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this
.getMartTab()
.getDataSetTabSet()
.requestLoopbackRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(), relation);
}
});
contextMenu.add(loopback);
if (incorrect || relationUnrolled || relationMasked
|| !relation.isOneToMany() && !relationLoopbacked)
loopback.setEnabled(false);
loopback.setSelected(relationLoopbacked);
// The force option allows the user to forcibly include a relation
// that would otherwise remain unincluded.
final JCheckBoxMenuItem force = new JCheckBoxMenuItem(Resources
.get("forceIncludeRelationTitle"));
force.setMnemonic(Resources.get("forceIncludeRelationMnemonic").charAt(
0));
force.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestForceRelation(ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation, force.isSelected());
}
});
contextMenu.add(force);
if (incorrect || relationUnrolled || relationMasked || relationIncluded
&& !relationForced)
force.setEnabled(false);
if (relationForced)
force.setSelected(true);
// The compound option allows the user to compound a relation.
final JCheckBoxMenuItem compound = new JCheckBoxMenuItem(Resources
.get("compoundRelationTitle"));
compound.setMnemonic(Resources.get("compoundRelationMnemonic")
.charAt(0));
compound.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this
.getMartTab()
.getDataSetTabSet()
.requestCompoundRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(), relation);
compound
.setSelected((ExplainContext.this.getDataSetTable() == null ? relation
.getCompoundRelation(ExplainContext.this
.getDataSet())
: relation.getCompoundRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable()
.getName())) != null);
}
});
contextMenu.add(compound);
if (incorrect || relationUnrolled || relationMasked
|| this.getDataSet().isPartitionTable())
compound.setEnabled(false);
if (relationCompounded)
compound.setSelected(true);
// The subclass/unsubclass option allows subclassing, but is
// only selectable when the relation is unmasked and not
// incorrect or already flagged as being in any conflicting state.
final JCheckBoxMenuItem subclass = new JCheckBoxMenuItem(Resources
.get("subclassRelationTitle"));
subclass.setMnemonic(Resources.get("subclassRelationMnemonic")
.charAt(0));
subclass.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestSubclassRelation(
ExplainContext.this.getDataSet(), relation,
subclass.isSelected());
}
});
contextMenu.add(subclass);
if (incorrect || relationUnrolled || relationMasked
|| relation.isOneToOne() || this.getDataSetTable() != null)
subclass.setEnabled(false);
if (relationSubclassed)
subclass.setSelected(true);
contextMenu.addSeparator();
// If it's a restricted relation...
if (relationRestricted) {
// Option to modify restriction.
final JMenuItem modify = new JMenuItem(Resources
.get("modifyRelationRestrictionTitle"), new ImageIcon(
Resources.getResourceAsURL("filter.gif")));
modify.setMnemonic(Resources.get(
"modifyRelationRestrictionMnemonic").charAt(0));
modify.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestRestrictRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation, iteration);
}
});
contextMenu.add(modify);
if (incorrect || relationUnrolled || relationMasked
|| this.getDataSetTable() == null)
modify.setEnabled(false);
} else {
// Add a relation restriction.
final JMenuItem restriction = new JMenuItem(Resources
.get("addRelationRestrictionTitle"), new ImageIcon(
Resources.getResourceAsURL("filter.gif")));
restriction.setMnemonic(Resources.get(
"addRelationRestrictionMnemonic").charAt(0));
restriction.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestRestrictRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation, iteration);
}
});
if (incorrect || relationUnrolled || relationMasked
|| this.getDataSetTable() == null)
restriction.setEnabled(false);
contextMenu.add(restriction);
}
// Option to remove restriction.
final JMenuItem remove = new JMenuItem(Resources
.get("removeRelationRestrictionTitle"));
remove.setMnemonic(Resources.get("removeRelationRestrictionMnemonic")
.charAt(0));
remove.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent evt) {
ExplainContext.this.getMartTab().getDataSetTabSet()
.requestUnrestrictRelation(
ExplainContext.this.getDataSet(),
ExplainContext.this.getDataSetTable(),
relation, iteration);
}
});
contextMenu.add(remove);
if (!relationRestricted)
remove.setEnabled(false);
}
}