package org.insightech.er.editor.view.dialog.element.relation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.insightech.er.Activator;
import org.insightech.er.ResourceString;
import org.insightech.er.common.dialog.AbstractDialog;
import org.insightech.er.common.widgets.CompositeFactory;
import org.insightech.er.editor.model.diagram_contents.element.connection.Relation;
import org.insightech.er.editor.model.diagram_contents.element.node.table.ERTable;
import org.insightech.er.editor.model.diagram_contents.element.node.table.column.NormalColumn;
import org.insightech.er.editor.model.diagram_contents.element.node.table.unique_key.ComplexUniqueKey;
import org.insightech.er.editor.view.dialog.element.relation.RelationDialog.ColumnComboInfo;
import org.insightech.er.util.Format;
public class RelationByExistingColumnsDialog extends AbstractDialog {
private static final int COLUMN_WIDTH = 200;
private Combo columnCombo;
private Table comparisonTable;
private ERTable source;
private ColumnComboInfo columnComboInfo;
private List<NormalColumn> candidateForeignKeyColumns;
private List<NormalColumn> referencedColumnList;
private List<NormalColumn> foreignKeyColumnList;
private Map<NormalColumn, List<NormalColumn>> referencedMap;
private boolean referenceForPK;
private ComplexUniqueKey referencedComplexUniqueKey;
private NormalColumn referencedColumn;
private List<TableEditor> tableEditorList;
private Map<TableEditor, List<NormalColumn>> editorReferencedMap;
private Map<Relation, Set<NormalColumn>> foreignKeySetMap;
public RelationByExistingColumnsDialog(Shell parentShell, ERTable source,
List<NormalColumn> candidateForeignKeyColumns,
Map<NormalColumn, List<NormalColumn>> referencedMap,
Map<Relation, Set<NormalColumn>> foreignKeySetMap) {
super(parentShell, 2);
this.source = source;
this.referencedColumnList = new ArrayList<NormalColumn>();
this.foreignKeyColumnList = new ArrayList<NormalColumn>();
this.candidateForeignKeyColumns = candidateForeignKeyColumns;
this.referencedMap = referencedMap;
this.foreignKeySetMap = foreignKeySetMap;
this.tableEditorList = new ArrayList<TableEditor>();
this.editorReferencedMap = new HashMap<TableEditor, List<NormalColumn>>();
}
@Override
protected void initLayout(GridLayout layout) {
super.initLayout(layout);
layout.verticalSpacing = 20;
}
/**
* {@inheritDoc}
*/
@Override
protected void initialize(Composite composite) {
GridData gridData = new GridData();
gridData.horizontalSpan = 2;
Label label = new Label(composite, SWT.NONE);
label.setLayoutData(gridData);
label
.setText(ResourceString
.getResourceString("dialog.message.create.relation.by.existing.columns"));
this.createColumnCombo(composite);
this.createComparisonTable(composite);
}
/**
* This method initializes combo
*
*/
private void createColumnCombo(Composite composite) {
Label label = new Label(composite, SWT.NONE);
label.setText(ResourceString
.getResourceString("label.reference.column"));
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = true;
this.columnCombo = new Combo(composite, SWT.READ_ONLY);
this.columnCombo.setLayoutData(gridData);
this.columnCombo.setVisibleItemCount(20);
}
private void createComparisonTable(Composite composite) {
GridData tableGridData = new GridData();
tableGridData.horizontalSpan = 2;
tableGridData.heightHint = 100;
tableGridData.horizontalAlignment = GridData.FILL;
tableGridData.grabExcessHorizontalSpace = true;
this.comparisonTable = new Table(composite, SWT.SINGLE | SWT.BORDER
| SWT.FULL_SELECTION);
this.comparisonTable.setLayoutData(tableGridData);
this.comparisonTable.setHeaderVisible(true);
this.comparisonTable.setLinesVisible(true);
TableColumn referencedColumn = new TableColumn(this.comparisonTable,
SWT.NONE);
referencedColumn.setWidth(COLUMN_WIDTH);
referencedColumn.setText(ResourceString
.getResourceString("label.reference.column"));
TableColumn foreignKeyColumn = new TableColumn(this.comparisonTable,
SWT.NONE);
foreignKeyColumn.setWidth(COLUMN_WIDTH);
foreignKeyColumn.setText(ResourceString
.getResourceString("label.foreign.key"));
}
/**
* {@inheritDoc}
*/
@Override
protected void setData() {
this.columnComboInfo = RelationDialog.setReferencedColumnComboData(
this.columnCombo, this.source);
this.columnCombo.select(0);
this.createComparisonTableRows();
}
/**
* {@inheritDoc}
*/
@Override
protected void perfomeOK() {
int index = this.columnCombo.getSelectionIndex();
if (index < this.columnComboInfo.complexUniqueKeyStartIndex) {
this.referenceForPK = true;
} else if (index < this.columnComboInfo.columnStartIndex) {
ComplexUniqueKey complexUniqueKey = this.source
.getComplexUniqueKeyList()
.get(
index
- this.columnComboInfo.complexUniqueKeyStartIndex);
this.referencedComplexUniqueKey = complexUniqueKey;
} else {
this.referencedColumn = this.columnComboInfo.candidateColumns
.get(index - this.columnComboInfo.columnStartIndex);
}
for (TableEditor tableEditor : this.tableEditorList) {
NormalColumn foreignKeyColumn = this.getSelectedColumn(tableEditor);
this.foreignKeyColumnList.add(foreignKeyColumn);
}
}
private NormalColumn getSelectedColumn(TableEditor tableEditor) {
Combo foreignKeyCombo = (Combo) tableEditor.getEditor();
int foreignKeyComboIndex = foreignKeyCombo.getSelectionIndex();
int startIndex = 1;
NormalColumn foreignKeyColumn = null;
List<NormalColumn> foreignKeyList = this.editorReferencedMap
.get(tableEditor);
if (foreignKeyList != null) {
if (foreignKeyComboIndex <= foreignKeyList.size()) {
foreignKeyColumn = foreignKeyList.get(foreignKeyComboIndex
- startIndex);
} else {
startIndex += foreignKeyList.size();
}
}
if (foreignKeyColumn == null) {
foreignKeyColumn = this.candidateForeignKeyColumns
.get(foreignKeyComboIndex - startIndex);
}
return foreignKeyColumn;
}
@Override
protected String getErrorMessage() {
Set<NormalColumn> selectedColumns = new HashSet<NormalColumn>();
for (TableEditor tableEditor : this.tableEditorList) {
Combo foreignKeyCombo = (Combo) tableEditor.getEditor();
int index = foreignKeyCombo.getSelectionIndex();
if (index == 0) {
return "error.foreign.key.not.selected";
}
NormalColumn selectedColumn = this.getSelectedColumn(tableEditor);
if (selectedColumns.contains(selectedColumn)) {
return "error.foreign.key.must.be.different";
}
selectedColumns.add(selectedColumn);
}
if (this.existForeignKeySet(selectedColumns)) {
return "error.foreign.key.already.exist";
}
return null;
}
private boolean existForeignKeySet(Set<NormalColumn> columnSet) {
boolean exist = false;
for (Set<NormalColumn> foreignKeySet : this.foreignKeySetMap.values()) {
if (foreignKeySet.size() == columnSet.size()) {
exist = true;
for (NormalColumn normalColumn : columnSet) {
if (!foreignKeySet.contains(normalColumn)) {
exist = false;
continue;
}
}
break;
}
}
return exist;
}
@Override
protected void addListener() {
super.addListener();
this.columnCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
comparisonTable.removeAll();
disposeTableEditor();
createComparisonTableRows();
validate();
}
});
this.comparisonTable.addListener(SWT.MeasureItem, new Listener() {
public void handleEvent(Event event) {
event.height = columnCombo.getSize().y;
;
}
});
}
private void createComparisonTableRows() {
try {
int index = this.columnCombo.getSelectionIndex();
if (index < this.columnComboInfo.complexUniqueKeyStartIndex) {
this.referencedColumnList = this.source.getPrimaryKeys();
} else if (index < this.columnComboInfo.columnStartIndex) {
ComplexUniqueKey complexUniqueKey = this.source
.getComplexUniqueKeyList()
.get(
index
- this.columnComboInfo.complexUniqueKeyStartIndex);
this.referencedColumnList = complexUniqueKey.getColumnList();
} else {
NormalColumn referencedColumn = this.columnComboInfo.candidateColumns
.get(index - this.columnComboInfo.columnStartIndex);
this.referencedColumnList = new ArrayList<NormalColumn>();
this.referencedColumnList.add(referencedColumn);
}
for (NormalColumn referencedColumn : this.referencedColumnList) {
this.column2TableItem(referencedColumn);
}
} catch (Exception e) {
Activator.showExceptionDialog(e);
}
}
private void column2TableItem(NormalColumn referencedColumn) {
TableItem tableItem = new TableItem(this.comparisonTable, SWT.NONE);
tableItem.setText(0, Format.null2blank(referencedColumn
.getLogicalName()));
List<NormalColumn> foreignKeyList = this.referencedMap
.get(referencedColumn.getRootReferencedColumn());
TableEditor tableEditor = new TableEditor(this.comparisonTable);
tableEditor.grabHorizontal = true;
tableEditor.setEditor(this.createForeignKeyCombo(foreignKeyList),
tableItem, 1);
this.tableEditorList.add(tableEditor);
this.editorReferencedMap.put(tableEditor, foreignKeyList);
}
protected Combo createForeignKeyCombo(List<NormalColumn> foreignKeyList) {
Combo foreignKeyCombo = CompositeFactory.createReadOnlyCombo(this,
this.comparisonTable, null);
foreignKeyCombo.add("");
if (foreignKeyList != null) {
for (NormalColumn normalColumn : foreignKeyList) {
foreignKeyCombo.add(Format.toString(normalColumn.getName()));
}
}
for (NormalColumn normalColumn : this.candidateForeignKeyColumns) {
foreignKeyCombo.add(Format.toString(normalColumn.getName()));
}
if (foreignKeyCombo.getItemCount() > 0) {
foreignKeyCombo.select(0);
}
return foreignKeyCombo;
}
@Override
public boolean close() {
this.disposeTableEditor();
return super.close();
}
private void disposeTableEditor() {
for (TableEditor tableEditor : this.tableEditorList) {
tableEditor.getEditor().dispose();
tableEditor.dispose();
}
this.tableEditorList.clear();
this.editorReferencedMap.clear();
}
public List<NormalColumn> getReferencedColumnList() {
return referencedColumnList;
}
public List<NormalColumn> getForeignKeyColumnList() {
return foreignKeyColumnList;
}
public boolean isReferenceForPK() {
return referenceForPK;
}
public ComplexUniqueKey getReferencedComplexUniqueKey() {
return referencedComplexUniqueKey;
}
public NormalColumn getReferencedColumn() {
return this.referencedColumn;
}
@Override
protected String getTitle() {
return "dialog.title.relation";
}
}