Java tutorial
/******************************************************************************* * Copyright (c) 2007, 2013 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.jpa.ui.internal.wizards.gen; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; 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.common.ui.internal.WorkbenchTools; import org.eclipse.jpt.common.ui.internal.swt.widgets.TableTools; import org.eclipse.jpt.common.ui.internal.widgets.TableLayoutComposite; import org.eclipse.jpt.jpa.db.Column; import org.eclipse.jpt.jpa.db.Schema; import org.eclipse.jpt.jpa.db.Table; import org.eclipse.jpt.jpa.gen.internal.Association; import org.eclipse.jpt.jpa.gen.internal.ORMGenCustomizer; import org.eclipse.jpt.jpa.ui.internal.JpaHelpContextIds; import org.eclipse.jpt.jpa.ui.wizards.gen.JptJpaUiWizardsEntityGenMessages; 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(JptJpaUiWizardsEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_title); setDescription(JptJpaUiWizardsEntityGenMessages.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); WorkbenchTools.setHelp(composite, JpaHelpContextIds.GENERATE_ENTITIES_WIZARD_JOIN_COLUMNS); 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 */ @Override 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(JptJpaUiWizardsEntityGenMessages.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(JptJpaUiWizardsEntityGenMessages.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(JptJpaUiWizardsEntityGenMessages.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(JptJpaUiWizardsEntityGenMessages.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(JptJpaUiWizardsEntityGenMessages.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 = ""; TreeMap<String, String> existingJoins = null; if (joinColumnsTable == this.joinColumnsTable1) { existingJoins = (TreeMap<String, String>) getWizardDataModel() .get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS1); if (this.getJoinTableName() == null) { table1Name = this.getReferrerTableName(); table2Name = this.getReferencedTableName(); } else { table1Name = this.getReferrerTableName(); table2Name = this.getJoinTableName(); } } else { existingJoins = (TreeMap<String, String>) getWizardDataModel() .get(NewAssociationWizard.ASSOCIATION_JOIN_COLUMNS2); table1Name = this.getJoinTableName(); table2Name = this.getReferencedTableName(); } //find next available column String[] table1ColumnValues = getTableColumns(table1Name); String nextCol1 = ""; for (String s : table1ColumnValues) { if (!existingJoins.keySet().contains(s)) { nextCol1 = s; break; } } String[] table2ColumnValues = getTableColumns(table2Name); String nextCol2 = ""; for (String s : table2ColumnValues) { if (!existingJoins.values().contains(s)) { nextCol2 = s; break; } } return new SimpleJoin(nextCol1, nextCol2); } @Override 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, JptJpaUiWizardsEntityGenMessages.GenerateEntitiesWizard_newAssoc_colsPage_label); joinColumnsTable1 = createJoinColumnsTableControl(tablesGroup, this.tableDataModel1); createAddRemoveButtonComposite(tablesGroup, joinColumnsTable1, tableDataModel1); } private void createJoinColumnsTableControl2(Composite tablesGroup) { joinColumnsDescLabel2 = createLabel(tablesGroup, 2, JptJpaUiWizardsEntityGenMessages.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 = TableTools.calculateHeightHint(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() { @Override 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 = 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); List<String> list = new ArrayList<String>(); for (Column column : table.getColumns()) { list.add(column.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; @Override 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; } } @Override public String getText(Object element) { return getColumnText(element, 0); // needed to make the sorter work } } }