| /******************************************************************************* |
| * Copyright (c) 2012 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.eclipselink.ui.internal.wizards; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jem.util.emf.workbench.ProjectUtilities; |
| import org.eclipse.jface.viewers.ComboViewer; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| 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.window.Window; |
| import org.eclipse.jpt.common.core.JptResourceType; |
| import org.eclipse.jpt.jpa.core.JpaProject; |
| import org.eclipse.jpt.jpa.core.MappingKeys; |
| import org.eclipse.jpt.jpa.core.resource.xml.JpaXmlResource; |
| import org.eclipse.jpt.jpa.eclipselink.ui.internal.EclipseLinkUiMessages; |
| import org.eclipse.jpt.jpa.eclipselink.ui.internal.dialogs.AddVirtualAttributeDialog; |
| import org.eclipse.jpt.jpa.eclipselink.ui.internal.entity.data.model.DynamicEntityField; |
| import org.eclipse.jpt.jpa.ui.details.MappingUiDefinition; |
| import org.eclipse.jpt.jpa.ui.internal.wizards.entity.data.model.IEntityDataModelProperties; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ControlAdapter; |
| import org.eclipse.swt.events.ControlEvent; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| 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.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties; |
| import org.eclipse.wst.common.frameworks.datamodel.IDataModel; |
| |
| public class DynamicEntityFieldTableSection extends Composite { |
| |
| private IDataModel model; |
| private Table mTableWidget = null; |
| private TableViewer mTableViewer = null; |
| private final int NAME_COLUMN = 0; |
| private final int MAPPING_TYPE_COLUMN = 1; |
| private final int ATTRIBUTE_TYPE_COLUMN = 2; |
| private Button addButton; |
| private Button editButton; |
| private Button removeButton; |
| private String propertyName; |
| |
| /** |
| * @param parent the main composite - DynamicEntityFieldsWizardPage |
| * @param model the data model representation |
| * @param propertyName data property name |
| */ |
| public DynamicEntityFieldTableSection(Composite parent, IDataModel model, String propertyName) { |
| super(parent, SWT.NONE); |
| this.model = model; |
| this.propertyName = propertyName; |
| |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginHeight = 4; |
| layout.marginWidth = 0; |
| this.setLayout(layout); |
| this.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| |
| // table widget |
| mTableWidget = new Table(this, SWT.FULL_SELECTION | SWT.BORDER); |
| mTableWidget.setHeaderVisible(true); |
| mTableWidget.setLinesVisible(true); |
| GridData data = new GridData(GridData.FILL_BOTH); |
| data.verticalSpan = 2; |
| mTableWidget.setLayoutData(data); |
| |
| TableColumn nameColumn = new TableColumn(mTableWidget, SWT.NONE); |
| nameColumn.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_nameColumnLabel); |
| |
| TableColumn mappingTypeColumn = new TableColumn(mTableWidget, SWT.NONE); |
| mappingTypeColumn.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_mappingTypeColumnLabel); |
| |
| TableColumn attrTypeColumn = new TableColumn(mTableWidget, SWT.NONE); |
| attrTypeColumn.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_attributeTypeColumnLabel); |
| |
| mTableViewer = new TableViewer(mTableWidget); |
| mTableViewer.setContentProvider(new EntityRowContentProvider()); |
| mTableViewer.setLabelProvider(new EntityRowLabelProvider()); |
| mTableViewer.addDoubleClickListener(new IDoubleClickListener() { |
| public void doubleClick(DoubleClickEvent event) { |
| handleEditButtonSelected(); |
| updatePrimaryKeyFieldProperty(); |
| } |
| }); |
| |
| // add, edit and remove buttons |
| final Composite buttonComposition = new Composite(this, SWT.NULL); |
| layout = new GridLayout(); |
| layout.marginHeight = 0; |
| buttonComposition.setLayout(layout); |
| buttonComposition.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING)); |
| |
| addButton = new Button(buttonComposition, SWT.PUSH); |
| addButton.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_addButtonLabel); |
| addButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); |
| addButton.addSelectionListener(new SelectionListener() { |
| public void widgetSelected(SelectionEvent event) { |
| handleAddButtonSelected(); |
| updatePrimaryKeyFieldProperty(); |
| } |
| public void widgetDefaultSelected(SelectionEvent event) { |
| //Do nothing |
| } |
| }); |
| |
| editButton = new Button(buttonComposition, SWT.PUSH); |
| editButton.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_editButtonLabel); |
| editButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); |
| editButton.addSelectionListener(new SelectionListener() { |
| public void widgetSelected(SelectionEvent event) { |
| handleEditButtonSelected(); |
| updatePrimaryKeyFieldProperty(); |
| } |
| public void widgetDefaultSelected(SelectionEvent event) { |
| //Do nothing |
| } |
| }); |
| editButton.setEnabled(false); |
| |
| removeButton = new Button(buttonComposition, SWT.PUSH); |
| removeButton.setText(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_removeButtonLabel); |
| removeButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); |
| removeButton.addSelectionListener(new SelectionListener() { |
| public void widgetSelected(SelectionEvent event) { |
| handleRemoveButtonSelected(); |
| updatePrimaryKeyFieldProperty(); |
| } |
| public void widgetDefaultSelected(SelectionEvent event) { |
| //Do nothing |
| } |
| }); |
| removeButton.setEnabled(false); |
| |
| mTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| ISelection selection = event.getSelection(); |
| if (editButton != null) { |
| boolean enabled = ((IStructuredSelection) selection).size() == 1; |
| editButton.setEnabled(enabled); |
| } |
| removeButton.setEnabled(!selection.isEmpty()); |
| } |
| }); |
| |
| this.addControlListener(new ColumnControlListener(buttonComposition)); |
| } |
| |
| |
| /** |
| * This method process the Add... button pressed event. |
| * It opens dialog to add a new dynamic entity field |
| */ |
| private void handleAddButtonSelected() { |
| AddFieldDialog dialog = new AddFieldDialog(getShell(), this.getJpaProject()); |
| int result = dialog.open(); |
| if (result == Window.CANCEL) { |
| return; |
| } |
| DynamicEntityField entityField = dialog.getEntityField(); |
| addEntityField(entityField); |
| } |
| |
| /** |
| * Add the given dynamic entity field to the table |
| * |
| * @param DynamicEntityField |
| * @return the DynamicEntityField which is to be added to the table |
| */ |
| private void addEntityField(DynamicEntityField field) { |
| if (field == null) |
| return; |
| List<DynamicEntityField> valueList = (ArrayList<DynamicEntityField>) mTableViewer.getInput(); |
| if (valueList == null) |
| valueList = new ArrayList<DynamicEntityField>(); |
| valueList.add(field); |
| setInput(valueList); |
| } |
| |
| /** |
| * This method process the Edit... button pressed event. |
| * It opens dialog to edit a chosen dynamic entity field |
| */ |
| private void handleEditButtonSelected() { |
| ISelection s = mTableViewer.getSelection(); |
| if (!(s instanceof IStructuredSelection)) |
| return; |
| IStructuredSelection selection = (IStructuredSelection) s; |
| if (selection.size() != 1) |
| return; |
| |
| Object selectedObj = selection.getFirstElement(); |
| DynamicEntityField fieldForEdit = (DynamicEntityField) selectedObj; |
| int index = mTableWidget.getSelectionIndex(); |
| |
| EditFieldDialog dialog = new EditFieldDialog(getShell(), this.getJpaProject(), fieldForEdit); |
| dialog.open(); |
| DynamicEntityField entityField = dialog.getEntityField(); |
| if (entityField != null) { |
| editEntityField(index, entityField); |
| } |
| } |
| |
| /** |
| * Edit a chosen dynamic entity field from the table |
| * @param index the index of the dynamic entity field in the table |
| * @param field the edited dynamic entity field |
| */ |
| private void editEntityField(int index, DynamicEntityField field) { |
| if (field == null) |
| return; |
| List<DynamicEntityField> valueList = (ArrayList<DynamicEntityField>) mTableViewer.getInput(); |
| if (valueList == null) { |
| valueList = new ArrayList<DynamicEntityField>(); |
| } |
| if (index == -1) { |
| valueList.add(field); |
| } else { |
| valueList.set(index, field); |
| } |
| setInput(valueList); |
| } |
| |
| /** |
| * This method process the Remove button pressed event. |
| */ |
| private void handleRemoveButtonSelected() { |
| ISelection selection = mTableViewer.getSelection(); |
| if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) |
| return; |
| List<DynamicEntityField> selectedObject = ((IStructuredSelection) selection).toList(); |
| removeEntityField(selectedObject); |
| } |
| |
| /** |
| * Removes the selected dynamic entity field(s) from the table |
| * @param fields list of dynamic entity fields which should be removed |
| */ |
| private void removeEntityField(Collection<DynamicEntityField> fields) { |
| List<DynamicEntityField> valueList = (ArrayList<DynamicEntityField>) mTableViewer.getInput(); |
| valueList.removeAll(fields); |
| setInput(valueList); |
| } |
| |
| /** |
| * Set the input of the table |
| * @param input the list of dynamic entity fields which have to be presented in the table |
| */ |
| private void setInput(List<DynamicEntityField> input) { |
| mTableViewer.setInput(input); |
| // Create a new list to trigger property change |
| ArrayList<DynamicEntityField> newInput = new ArrayList<DynamicEntityField>(); |
| newInput.addAll(input); |
| model.setProperty(propertyName, newInput); |
| } |
| |
| /** |
| * @return the TableViewer of the table |
| */ |
| public TableViewer getTableViewer() { |
| return mTableViewer; |
| } |
| |
| /** |
| * Update PK fields property when any field(s) added to, edited in, or removed from the field table viewer |
| */ |
| private void updatePrimaryKeyFieldProperty() { |
| List<DynamicEntityField> pkFields = new ArrayList<DynamicEntityField>(); |
| TableItem[] children = mTableViewer.getTable().getItems(); |
| for (int i = 0; i < children.length; i++) { |
| TableItem item = children[i]; |
| DynamicEntityField field = (DynamicEntityField)item.getData(); |
| if (field.getMappingType().getKey().equals(MappingKeys.ID_ATTRIBUTE_MAPPING_KEY)) { |
| field.setKey(true); |
| pkFields.add(field); |
| } |
| } |
| DynamicEntityFieldTableSection.this.model.setProperty(IEntityDataModelProperties.PK_FIELDS, pkFields); |
| } |
| |
| // ********** Control listener for field columns ************** |
| |
| private final class ColumnControlListener extends ControlAdapter { |
| private final Composite buttonComposition; |
| |
| private ColumnControlListener(Composite buttonComposition) { |
| this.buttonComposition = buttonComposition; |
| } |
| |
| @Override |
| public void controlResized(ControlEvent e) { |
| Table table = mTableViewer.getTable(); |
| Rectangle area = table.getParent().getClientArea(); |
| Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| TableColumn[] columns = table.getColumns(); |
| Point buttonArea = buttonComposition.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| int width = area.width - 3 * table.getBorderWidth(); |
| if (preferredSize.y > area.height + table.getHeaderHeight()) { |
| // Subtract the scrollbar width from the total column width |
| // if a vertical scrollbar will be required |
| Point vBarSize = table.getVerticalBar().getSize(); |
| width -= vBarSize.x; |
| } |
| Point oldSize = table.getSize(); |
| int consumeWidth = 0; |
| for (int i = 0; i < columns.length; i++) { |
| if (oldSize.x > area.width) { |
| // table is getting smaller so make the columns |
| // smaller first and then resize the table to |
| // match the client area width |
| consumeWidth = setColumntWidth(width, columns, consumeWidth, i); |
| table.setSize(area.width - buttonArea.x, area.height); |
| } else { |
| // table is getting bigger so make the table |
| // bigger first and then make the columns wider |
| // to match the client area width |
| consumeWidth = setColumntWidth(width, columns, consumeWidth, i); |
| table.setSize(area.width - buttonArea.x, area.height); |
| } |
| } |
| } |
| |
| private int setColumntWidth(int width, TableColumn[] columns, int consumeWidth, int i) { |
| columns[i].setWidth(width / (columns.length + 1)); |
| consumeWidth += columns[i].getWidth(); |
| return consumeWidth; |
| } |
| } |
| |
| // ********** Providers for the dynamic entity field table viewer ************** |
| |
| /** |
| * The content provider for the table items |
| */ |
| protected class EntityRowContentProvider implements IStructuredContentProvider { |
| public boolean isDeleted(Object element) { |
| return false; |
| } |
| public Object[] getElements(Object element) { |
| if (element instanceof List) { |
| return ((List) element).toArray(); |
| } |
| return new Object[0]; |
| } |
| public void inputChanged(Viewer aViewer, Object oldInput, Object newInput) { |
| //Default nothing |
| } |
| public void dispose() { |
| //Default nothing |
| } |
| } |
| |
| /** |
| * The label provider for the table items |
| */ |
| protected class EntityRowLabelProvider extends LabelProvider implements ITableLabelProvider { |
| public Image getColumnImage(Object element, int columnIndex) { |
| return null; |
| } |
| |
| public String getColumnText(Object element, int columnIndex) { |
| DynamicEntityField entity = (DynamicEntityField) element; |
| if (columnIndex == NAME_COLUMN) { |
| return entity.getName(); |
| } |
| if (columnIndex == MAPPING_TYPE_COLUMN) { |
| return entity.getMappingType().getLabel(); |
| } |
| if (columnIndex == ATTRIBUTE_TYPE_COLUMN) { |
| return entity.getFqnTypeName(); |
| } |
| return ""; |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| return null; |
| } |
| |
| @Override |
| public String getText(Object element) { |
| String[] array = (String[]) element; |
| if (array.length > 0) { |
| return array[0]; |
| } else { |
| return super.getText(element); |
| } |
| } |
| } |
| |
| // ********* Add dynamic entity field dialog ****************** |
| |
| /** |
| * The dialog which collect the information (name, mapping type, and attribute type) for a new dynamic entity field |
| */ |
| private class AddFieldDialog extends AddVirtualAttributeDialog { |
| |
| protected DynamicEntityField entityField; |
| |
| protected final JpaProject jpaProject; |
| |
| /** |
| * Constructs AddFieldDialog |
| * @param shell |
| * @param jpaProject the selected jpaProject |
| */ |
| public AddFieldDialog(Shell shell, JpaProject jpaProject) { |
| super(shell, null); |
| this.jpaProject = jpaProject; |
| setTitle(EclipseLinkUiMessages.DynamicEntityFieldsWizardPage_addDynamicEntityFieldDialog_title); |
| } |
| |
| /* Create the area of dialog |
| * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) |
| */ |
| @Override |
| public Control createDialogArea(Composite parent) { |
| Composite composite = (Composite) super.createDialogArea(parent); |
| return composite; |
| } |
| |
| /* Processes OK button pressed event. |
| * @see org.eclipse.jface.dialogs.Dialog#okPressed() |
| */ |
| @Override |
| protected void okPressed() { |
| /** |
| * @see org.eclipse.jpt.jpa.eclipselink.ui.internal.entity.data.model.DynamicEntityField |
| */ |
| DynamicEntityField field = new DynamicEntityField(); |
| field.setMappingType(this.getMappingUiDefinition(this.mappingCombo)); |
| field.setFqnTypeName(this.attributeTypeText.getText()); |
| field.setName(this.nameText.getText()); |
| entityField = field; |
| |
| setReturnCode(OK); |
| close(); |
| } |
| |
| private MappingUiDefinition<?,?> getMappingUiDefinition(ComboViewer mappingType) { |
| StructuredSelection selection = (StructuredSelection) mappingType.getSelection(); |
| return (selection.isEmpty()) ? null : (MappingUiDefinition<?,?>) selection.getFirstElement(); |
| } |
| |
| /** |
| * @return the dynamic entity field representation with the information collected from the dialog |
| */ |
| public DynamicEntityField getEntityField() { |
| return this.entityField; |
| } |
| |
| // ********** override super class methods ************ |
| |
| @Override |
| protected JpaProject getJpaProject() { |
| return this.jpaProject; |
| } |
| |
| @Override |
| protected JptResourceType getJptResourceType() { |
| String xmlName = model.getStringProperty(IEntityDataModelProperties.XML_NAME); |
| return this.getOrmXmlResource(xmlName).getResourceType(); |
| } |
| |
| protected JpaXmlResource getOrmXmlResource(String xmlName) { |
| return this.jpaProject == null ? null : this.jpaProject.getMappingFileXmlResource(new Path(xmlName)); |
| } |
| } |
| |
| // ********* Edit dynamic entity field dialog ****************** |
| |
| private class EditFieldDialog extends AddFieldDialog { |
| |
| public EditFieldDialog(Shell shell, JpaProject jpaProject, DynamicEntityField field) { |
| super(shell, jpaProject); |
| this.entityField = field; |
| } |
| |
| /* Create the area of the dialog |
| */ |
| @Override |
| public Control createDialogArea(Composite parent) { |
| Composite composite = (Composite) super.createDialogArea(parent); |
| |
| this.nameText.setText(this.entityField.getName()); |
| this.mappingCombo.setSelection(new StructuredSelection(this.entityField.getMappingType())); |
| this.attributeTypeText.setText(this.entityField.getFqnTypeName()); |
| |
| return composite; |
| } |
| } |
| |
| //************* misc ************** |
| |
| protected JpaProject getJpaProject() { |
| return (JpaProject) getIProject().getAdapter(JpaProject.class); |
| } |
| |
| protected IProject getIProject() { |
| String projectName = model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME); |
| return ProjectUtilities.getProject(projectName); |
| } |
| } |