blob: 42a346c36c69c6a8b9a1b1350139702ebbb6aff7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 Oracle. 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:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.ui.internal.wizards.gen;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jpt.db.Column;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.Table;
import org.eclipse.jpt.gen.internal2.Association;
import org.eclipse.jpt.gen.internal2.ORMGenCustomizer;
import org.eclipse.jpt.ui.internal.util.SWTUtil;
import org.eclipse.jpt.ui.internal.util.TableLayoutComposite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class JoinColumnsPage extends NewAssociationWizardPage {
private Label joinColumnsDescLabel1;
/*the table containing the association columns between table1 and table2
* , or table1 and join table if many to many*/
private TableViewer joinColumnsTable1;
private ArrayList<SimpleJoin> tableDataModel1 = new ArrayList<SimpleJoin>();
private Composite tablesGroup1;
private Label joinColumnsDescLabel2;
/*the table containing the association columns between join table and table2
* if many to many*/
private TableViewer joinColumnsTable2;
private ArrayList<SimpleJoin> tableDataModel2 = new ArrayList<SimpleJoin>();
private Composite tablesGroup2;
static final String[] JOINCOLUMNS_TABLE_COLUMN_PROPERTIES = { "referrerColumn", "referencedColumn" };
private static final int JOINCOLUMN1_COLUMN_INDEX = 0;
private static final int JOINCOLUMN2_COLUMN_INDEX = 1;
protected JoinColumnsPage(ORMGenCustomizer customizer ) {
super(customizer, "JoinColumnsPage");
setTitle( JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_title);
setDescription(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_desc);
}
public void createControl(Composite parent) {
initializeDialogUnits(parent);
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
composite.setLayout(layout);
tablesGroup1 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
tablesGroup1.setLayoutData(new GridData());
tablesGroup1.setLayout(new GridLayout(2, false));
createJoinColumnsTableControl1(tablesGroup1);
//createMtmJoinColumnsTable2(composite);
setControl(composite);
this.setPageComplete( false);
((WizardDialog)getContainer()).addPageChangedListener(new IPageChangedListener(){
public void pageChanged(PageChangedEvent event) {
if( event.getSelectedPage() == JoinColumnsPage.this ){
((Composite)JoinColumnsPage.this.getControl()).getParent().layout() ;
}
}
});
}
private void createMtmJoinColumnsTable2(Composite composite) {
tablesGroup2 = new Composite(composite, SWT.SHADOW_ETCHED_IN);
tablesGroup2.setLayoutData(new GridData());
tablesGroup2.setLayout(new GridLayout(2, false));
createJoinColumnsTableControl2(tablesGroup2);
}
/**
* Update wizard page UI with new table names
*/
public void updateWithNewTables() {
String cardinality = this.getCardinality() ;
if( Association.MANY_TO_MANY.equals( cardinality ) ){
updateWithMtmTables();
}else{
updateWithOtmTables();
}
}
/**
* Update Wizard UI with a single TableViewer with columns from the two associated database tables
*/
public void updateWithOtmTables() {
TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
String table1Name = this.getReferrerTableName() ;
String table2Name = this.getReferencedTableName() ;
if( table1Name ==null || table2Name == null )
return;
columns[0].setText( table1Name );
columns[1].setText( table2Name );
//Hide the Join column table 2
if( tablesGroup2 !=null )
tablesGroup2.setVisible(false);
tableDataModel1.clear();
joinColumnsTable1.refresh();
String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, table2Name);
joinColumnsDescLabel1.setText(msg);
joinColumnsDescLabel1.setToolTipText( msg );
tablesGroup1.layout();
String[] referrerColumnValues = getTableColumns(table1Name);
String[] referencedColumnValues = getTableColumns(table2Name);
updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues);
((Composite)this.getControl()).layout() ;
}
/**
* Update Wizard UI with a two TableViewers with the first with columns from table1 to the MTM join table
* and the second one with columns from the MTM join table to table2
*/
public void updateWithMtmTables() {
TableColumn[] columns = joinColumnsTable1.getTable().getColumns();
String table1Name = this.getReferrerTableName() ;
String table2Name = this.getReferencedTableName() ;
String joinTableName = this.getJoinTableName() ;
if( table1Name==null || table2Name==null || joinTableName==null ){
return;
}
if( tablesGroup2 == null ){
createMtmJoinColumnsTable2( tablesGroup1.getParent());
}
columns[0].setText( table1Name==null?"":table1Name );
columns[1].setText( table2Name==null?"":joinTableName );
//Update join column TableViewer 1
tableDataModel1.clear();
joinColumnsTable1.refresh();
String msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, table1Name, joinTableName);
joinColumnsDescLabel1.setText(msg);
joinColumnsDescLabel1.setToolTipText( msg );
String[] referrerColumnValues = getTableColumns(table1Name);
String[] referencedColumnValues = getTableColumns(joinTableName);
updateCellEditors(joinColumnsTable1, referrerColumnValues, referencedColumnValues );
//Update join column TableViewer 2
columns = joinColumnsTable2.getTable().getColumns();
columns[0].setText( joinTableName==null?"":joinTableName );
columns[1].setText( table2Name==null?"":table2Name );
tablesGroup1.layout();
tableDataModel2.clear();
joinColumnsTable2.refresh();
msg = String.format(JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label, joinTableName, table2Name);
joinColumnsDescLabel2.setText(msg);
joinColumnsDescLabel2.setToolTipText( msg );
referrerColumnValues = getTableColumns(joinTableName);
referencedColumnValues = getTableColumns(table2Name);
updateCellEditors(joinColumnsTable2, referrerColumnValues, referencedColumnValues );
tablesGroup2.layout();
//Show the Join column TableViewer 2
tablesGroup2.setVisible(true);
((Composite)this.getControl()).layout(new Control[]{this.tablesGroup1, this.tablesGroup2});
}
private void createAddRemoveButtonComposite(Composite tablesGroup, final TableViewer joinColumnsTable, final ArrayList<SimpleJoin> tableDataModel) {
//Add and Remove JoinColumns buttons
Composite buttonComposite = new Composite(tablesGroup, SWT.NULL);
GridLayout buttonLayout = new GridLayout(1, false);
buttonComposite.setLayout(buttonLayout);
GridData data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.verticalAlignment = GridData.BEGINNING;
buttonComposite.setLayoutData(data);
Button addButton = new Button(buttonComposite, SWT.PUSH);
addButton.setText( JptUiEntityGenMessages.add );
GridData gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
addButton.setLayoutData(gridData);
addButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
@SuppressWarnings("unchecked")
public void widgetSelected(SelectionEvent e) {
SimpleJoin join = getDefaultNewJoin(joinColumnsTable);
tableDataModel.add(join);
joinColumnsTable.refresh();
//Update Wizard model
TreeMap<String, String> joins = null;
if( joinColumnsTable == joinColumnsTable1 ){
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
}else{
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
}
joins.put( join.foreignKey, join.primaryKey);
updatePageComplete();
}
});
Button removeButton = new Button(buttonComposite, SWT.PUSH);
removeButton.setText( JptUiEntityGenMessages.remove );
gridData = new GridData();
gridData.horizontalAlignment = GridData.FILL;
removeButton.setLayoutData(gridData);
removeButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {}
@SuppressWarnings("unchecked")
public void widgetSelected(SelectionEvent e) {
StructuredSelection selection = (StructuredSelection)joinColumnsTable.getSelection();
if( selection.isEmpty())
return;
SimpleJoin join = (SimpleJoin)selection.getFirstElement();
//Update TableViewer model
tableDataModel.remove( join );
//Update Wizard model
TreeMap<String, String> joins = null;
if( joinColumnsTable == joinColumnsTable1 ){
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
}else{
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
}
joins.remove(join.foreignKey);
joinColumnsTable.refresh();
}
});
addButton.setFocus();
}
protected SimpleJoin getDefaultNewJoin(TableViewer joinColumnsTable) {
String table1Name = "";
String table2Name = "";
if( joinColumnsTable == this.joinColumnsTable1 ){
if( this.getJoinTableName() == null) {
table1Name = this.getReferrerTableName();
table2Name = this.getReferencedTableName() ;
}else{
table1Name = this.getReferrerTableName();
table2Name = this.getJoinTableName() ;
}
}else{
table1Name = this.getJoinTableName();
table2Name = this.getReferencedTableName() ;
}
String[] table1ColumnValues = getTableColumns(table1Name);
String[] table2ColumnValues = getTableColumns(table2Name);
return new SimpleJoin(table1ColumnValues[0], table2ColumnValues[0]);
}
public boolean canFlipToNextPage() {
return isPageComplete();
}
public void updatePageComplete() {
boolean ret = tableDataModel1.size()> 0 ;
setPageComplete( ret );
}
private Label createLabel(Composite container, int span, String text) {
Label label = new Label(container, SWT.NONE);
label.setText(text);
GridData gd = new GridData();
gd.horizontalSpan = span;
label.setLayoutData(gd);
return label;
}
private void createJoinColumnsTableControl1(Composite tablesGroup) {
joinColumnsDescLabel1 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
joinColumnsTable1 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel1);
createAddRemoveButtonComposite(tablesGroup, joinColumnsTable1, tableDataModel1);
}
private void createJoinColumnsTableControl2(Composite tablesGroup) {
joinColumnsDescLabel2 = createLabel(tablesGroup, 2, JptUiEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label );
joinColumnsTable2 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel2);
createAddRemoveButtonComposite(tablesGroup, joinColumnsTable2, tableDataModel2);
}
private TableViewer createJoinColumnsTableControl(Composite parent, ArrayList<SimpleJoin> tableDataModel ){
TableLayoutComposite layout= new TableLayoutComposite(parent, SWT.NONE);
addColumnLayoutData(layout);
final org.eclipse.swt.widgets.Table table = new org.eclipse.swt.widgets.Table(layout, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER );
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn referrerColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN1_COLUMN_INDEX);
referrerColumn.setText("%table1");
referrerColumn.setResizable(true);
TableColumn referencedColumn = new TableColumn(table, SWT.NONE, JOINCOLUMN2_COLUMN_INDEX);
referencedColumn.setText("%table2");
referencedColumn.setResizable(true);
GridData gd= new GridData(GridData.FILL_BOTH);
gd.heightHint= SWTUtil.getTableHeightHint(table, 3);
gd.widthHint = 300;
layout.setLayoutData(gd);
TableViewer newJoinColumnsTable = new TableViewer(table);
newJoinColumnsTable.setUseHashlookup(true);
newJoinColumnsTable.setLabelProvider(this.buildTableTableLabelProvider());
newJoinColumnsTable.setContentProvider(this.buildTableTableContentProvider());
newJoinColumnsTable.setSorter(new ViewerSorter() {
public int compare(Viewer viewer, Object e1, Object e2) {
return ((SimpleJoin) e1).foreignKey.compareTo(((SimpleJoin) e2).foreignKey);
}
});
newJoinColumnsTable.addPostSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
//handleTablesListSelectionChanged(event);
}
});
populateTableDataModel();
newJoinColumnsTable.setInput( tableDataModel );
return newJoinColumnsTable;
}
@SuppressWarnings("unchecked")
public void populateTableDataModel(){
HashMap<String, Object> dataModel = (HashMap<String, Object> )getWizardDataModel();
TreeMap<String, String> joinColumns = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1);
if( joinColumns!= null ){
for( String referrerColumn : joinColumns.keySet() ){
tableDataModel1.add(new SimpleJoin(referrerColumn, joinColumns.get(referrerColumn) ));
}
}
TreeMap<String, String> joinColumns2 = (TreeMap<String, String>)dataModel.get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2);
if( joinColumns2!= null ){
for( String referrerColumn : joinColumns2.keySet() ){
tableDataModel2.add(new SimpleJoin(referrerColumn, joinColumns2.get(referrerColumn) ));
}
}
}
private IContentProvider buildTableTableContentProvider() {
return new JoinColumnsContentProvider();
}
private IBaseLabelProvider buildTableTableLabelProvider() {
return new JoinColumnsTableLabelProvider();
}
private void addColumnLayoutData(TableLayoutComposite layout) {
layout.addColumnData(new ColumnWeightData(50, true));
layout.addColumnData(new ColumnWeightData(50, true));
}
private void updateCellEditors(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues ){
joinColumnsTable.setColumnProperties(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES);
ComboBoxCellEditor[] editors = new ComboBoxCellEditor[JOINCOLUMNS_TABLE_COLUMN_PROPERTIES.length];
editors[JOINCOLUMN1_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referrerColumnValues, SWT.SINGLE);
editors[JOINCOLUMN2_COLUMN_INDEX]= new ComboBoxCellEditor(joinColumnsTable.getTable(), referencedColumnValues, SWT.SINGLE);
joinColumnsTable.setCellEditors(editors);
joinColumnsTable.setCellModifier(this.buildTableTableCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues ));
}
public String[] getTableColumns(String tableName){
Schema schema = (Schema)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_SCHEMA);
Table table = schema.getTableNamed(tableName);
Iterator<Column> columns = table.columns() ;
List<String> list = new ArrayList<String>();
while( columns.hasNext() ){
list.add(columns.next().getName());
}
String[] ret = new String[list.size()];
list.toArray(ret);
return ret;
}
private ICellModifier buildTableTableCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
return new JoinColumnsCellModifier(joinColumnsTable, referrerColumnValues, referencedColumnValues);
}
/**
* A ContentProvider translates the SimpleJoin list into a Collection for display
*
*/
private class JoinColumnsContentProvider implements IStructuredContentProvider {
JoinColumnsContentProvider() {
super();
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
public void dispose() {}
public Object[] getElements(Object inputElement) {
return ((Collection<?>) inputElement).toArray();
}
}
/**
* Simple value object used as model backing the JFace table
*
*/
private class SimpleJoin {
public SimpleJoin(String foreignKey, String primaryKey) {
this.foreignKey = foreignKey;
this.primaryKey = primaryKey;
}
public String foreignKey;
public String primaryKey;
public String toString(){
return "["+ this.foreignKey + " = " + this.primaryKey + "]";
}
}
/**
* A CellModifier to update the join columns in the wizard data model
*/
private class JoinColumnsCellModifier implements ICellModifier {
private TableViewer joinColumnsTable;
private String[] referrerColumnValues;
private String[] referencedColumnValues;
JoinColumnsCellModifier(TableViewer joinColumnsTable, String[] referrerColumnValues, String[] referencedColumnValues) {
super();
this.joinColumnsTable = joinColumnsTable;
this.referrerColumnValues = referrerColumnValues;
this.referencedColumnValues = referencedColumnValues;
}
public boolean canModify(Object element, String property) {
return true;
}
@SuppressWarnings("unchecked")
public Object getValue(Object element, String property) {
// SimpleJoin join = (SimpleJoin) element;
// if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
// return join.primaryKey;
// }
// return join.foreignKey;
// returnt the index of the value in the ComboxCellEditor
ArrayList<SimpleJoin> tableDataModel = (ArrayList<SimpleJoin>) joinColumnsTable.getInput();
for(int i=0; i< tableDataModel.size(); i ++ ){
if( tableDataModel.get(i) == element )
return new Integer(i);
}
return new Integer(0);
}
/**
* element is the selected TableItem
* value is the selected item index in the comboCellEditor
*/
@SuppressWarnings("unchecked")
public void modify(Object element, String property, Object value) {
if ( ! (element instanceof TableItem)) {
return;
}
Integer index = (Integer)value;
TableItem item = (TableItem)element;
boolean unchanged = false;
SimpleJoin join = (SimpleJoin) item.getData();
if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN1_COLUMN_INDEX])) {
unchanged = join.foreignKey.equals( referrerColumnValues[ index.intValue() ] );
if (! unchanged) {
//update the wizard datamodel
TreeMap<String, String> joins = null;
if( joinColumnsTable == joinColumnsTable1 ){
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
}else{
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
}
joins.remove(join.foreignKey);
joins.put(referrerColumnValues[ index.intValue() ], join.primaryKey);
//Update the TableViewer model
join.foreignKey = referrerColumnValues[ index.intValue()];
joinColumnsTable.refresh();
}
return;
}
if (property.equals(JOINCOLUMNS_TABLE_COLUMN_PROPERTIES[JOINCOLUMN2_COLUMN_INDEX])) {
unchanged = join.primaryKey.equals( referencedColumnValues[ index.intValue()] ) ;
if (! unchanged) {
//Update the TableViewer model
join.primaryKey = referencedColumnValues[ index.intValue()] ;
//Update wizard data model
TreeMap<String, String> joins = null;
if( joinColumnsTable == joinColumnsTable1 ){
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1 );
}else{
joins = (TreeMap<String, String>)getWizardDataModel().get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2 );
}
joins.put(join.foreignKey, join.primaryKey);
joinColumnsTable.refresh();
}
}
}
}
/**
* A table label provider to return the join column names for display
*
*/
private final class JoinColumnsTableLabelProvider extends LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
if( !(element instanceof SimpleJoin) )
return null;
switch (columnIndex) {
case 0:
return ((SimpleJoin)element).foreignKey;
case 1:
return ((SimpleJoin)element).primaryKey;
default:
Assert.isTrue(false);
return null;
}
}
public String getText(Object element) {
return getColumnText(element, 0); // needed to make the sorter work
}
}
}