/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.pms.ui.dialog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
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.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.pentaho.pms.messages.Messages;
import org.pentaho.pms.schema.PhysicalColumn;
import org.pentaho.pms.schema.PhysicalTable;
import org.pentaho.pms.schema.SchemaMeta;
import org.pentaho.pms.schema.concept.ConceptUtilityInterface;
import org.pentaho.pms.ui.concept.editor.PhysicalTableModel;
import org.pentaho.pms.ui.concept.editor.PropertyNavigationWidget;
import org.pentaho.pms.ui.concept.editor.PropertyWidgetManager2;
import org.pentaho.pms.util.ObjectAlreadyExistsException;
import org.pentaho.pms.util.Settings;
public class PhysicalTableDialog extends AbstractTableDialog {
private static final Log logger = LogFactory.getLog(PhysicalTableDialog.class);
HashMap<Object, Object> modificationsMap = new HashMap<Object, Object>();
public PhysicalTableDialog(Shell parent, PhysicalColumn origPhysicalColumn, SchemaMeta schemaMeta) {
super(parent);
PhysicalTable originalPhysicalTable = origPhysicalColumn.getTable();
PhysicalTable newPhysicalTable = (PhysicalTable) originalPhysicalTable.clone();
PhysicalTableModel tableModel = new PhysicalTableModel(newPhysicalTable);
initModificationsMap(originalPhysicalTable, newPhysicalTable);
init(tableModel, schemaMeta, origPhysicalColumn);
}
public PhysicalTableDialog(Shell parent, PhysicalTable origPhysicalTable, SchemaMeta schemaMeta) {
super(parent);
PhysicalTable newPhysicalTable = (PhysicalTable) origPhysicalTable.clone();
PhysicalTableModel tableModel = new PhysicalTableModel(newPhysicalTable);
initModificationsMap(origPhysicalTable, newPhysicalTable);
init(tableModel, schemaMeta, origPhysicalTable);
}
private void initModificationsMap(PhysicalTable origPhysicalTable, PhysicalTable workingPhysicalTable) {
modificationsMap.put(workingPhysicalTable, origPhysicalTable);
List workingPhysicalColumns = workingPhysicalTable.getPhysicalColumns().getList();
for (Iterator workingIter = workingPhysicalColumns.iterator(); workingIter.hasNext();) {
PhysicalColumn workingPhysicalColumn = (PhysicalColumn) workingIter.next();
List origPhysicalColumns = origPhysicalTable.getPhysicalColumns().getList();
for (Iterator origIter = origPhysicalColumns.iterator(); origIter.hasNext();) {
PhysicalColumn origPhysicalColumn = (PhysicalColumn) origIter.next();
if (origPhysicalColumn.equals(workingPhysicalColumn)) {
modificationsMap.put(workingPhysicalColumn, origPhysicalColumn);
break;
}
}
}
}
protected void configureShell(final Shell shell) {
super.configureShell(shell);
shell.setText(Messages.getString("PhysicalTableDialog.USER_TABLE_PROPERTIES"));
}
protected void addColumnPressed() {
// Ask for the ID
String startId = Settings.getPhysicalColumnIDPrefix();
if (Settings.isAnIdUppercase()) {
startId = startId.toUpperCase();
}
InputDialog dialog = new InputDialog(getShell(), Messages.getString("PhysicalTableDialog.USER_TITLE_NEW_COLUMN"),
Messages.getString("PhysicalTableDialog.USER_NEW_COLUMN_NAME"), startId, null);
dialog.open();
String id = dialog.getValue();
if (null != id) {
try {
tableModel.addColumn(id, activeLocale);
} catch (ObjectAlreadyExistsException e) {
MessageDialog.openError(getShell(), "Column Add Error", "A column with id '" + id + "' already exists.");
}
}
}
protected void okPressed() {
boolean hasErrors = popupValidationErrorDialogIfNecessary();
if (!hasErrors) {
try {
if (lastSelection != null) {
String id = conceptIdText.getText();
if (id.trim().length() == 0) {
MessageDialog.openError(getShell(), Messages.getString("General.USER_TITLE_ERROR"), Messages.getString(
"PhysicalTableDialog.USER_ERROR_INVALID_ID", conceptIdText.getText()));
tableColumnTree.setSelection(new StructuredSelection(lastSelection));
conceptIdText.forceFocus();
conceptIdText.selectAll();
} else {
lastSelection.setId(conceptIdText.getText());
updateOriginalPhysicalTable();
super.okPressed();
}
} else {
updateOriginalPhysicalTable();
super.okPressed();
}
} catch (ObjectAlreadyExistsException e) {
if (logger.isErrorEnabled()) {
logger.error("an exception occurred", e);
}
MessageDialog.openError(getShell(), Messages.getString("General.USER_TITLE_ERROR"), Messages.getString(
"PhysicalTableDialog.USER_ERROR_PHYSICAL_TABLE_ID_EXISTS", conceptIdText.getText()));
}
}
}
public void selectionChanged(SelectionChangedEvent e) {
if (lastSelection != null && lastSelection.equals(((StructuredSelection) e.getSelection()).getFirstElement())) {
return;
}
boolean hasErrors = popupValidationErrorDialogIfNecessary();
if (!hasErrors) {
if (lastSelection != null) {
try {
String id = conceptIdText.getText();
if (id.trim().length() == 0) {
// gmoran, PMD-227: Without this check we get into an infinite loop since we reset the selection after
// throwing the error message...
if (!lastSelection.equals(((StructuredSelection) e.getSelection()).getFirstElement())) {
MessageDialog.openError(getShell(), Messages.getString("General.USER_TITLE_ERROR"), Messages.getString(
"PhysicalTableDialog.USER_ERROR_INVALID_ID", conceptIdText.getText()));
tableColumnTree.setSelection(new StructuredSelection(lastSelection));
conceptIdText.forceFocus();
conceptIdText.selectAll();
}
} else {
lastSelection.setId(conceptIdText.getText());
super.selectionChanged(e);
}
} catch (ObjectAlreadyExistsException e1) {
if (logger.isErrorEnabled()) {
logger.error("an exception occurred", e1);
}
MessageDialog.openError(getShell(), Messages.getString("General.USER_TITLE_ERROR"), Messages.getString(
"PhysicalTableDialog.USER_ERROR_PHYSICAL_TABLE_ID_EXISTS", conceptIdText.getText()));
}
} else {
super.selectionChanged(e);
}
} else {
// set selection back where it was
if (!lastSelection.equals(((StructuredSelection) e.getSelection()).getFirstElement())) {
tableColumnTree.setSelection(new StructuredSelection(lastSelection));
}
}
}
private void updateOriginalPhysicalTable() {
// Find the original physical table.
PhysicalTable origTable = null;
for (Iterator iterator = modificationsMap.values().iterator(); iterator.hasNext() && (origTable == null);) {
Object target = iterator.next();
if (target instanceof PhysicalTable) {
origTable = (PhysicalTable) target;
}
}
// Remove any columns from the original physical table that were removed from the working copy.
ArrayList<Map.Entry> entriesToRemove = new ArrayList<Map.Entry>();
Set<Map.Entry<Object, Object>> entrySet = modificationsMap.entrySet();
for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) {
boolean found = false;
Map.Entry entry = (Map.Entry) iterator.next();
if (entry.getKey() instanceof PhysicalColumn) {
ConceptUtilityInterface[] workingColumns = tableModel.getColumns();
for (int i = 0; (i < workingColumns.length) && !found; i++) {
found = (workingColumns[i] == entry.getKey());
}
if (!found) {
PhysicalColumn column = origTable.findPhysicalColumn(((PhysicalColumn) entry.getValue()).getId());
int index = origTable.indexOfPhysicalColumn(column);
origTable.removePhysicalColumn(index);
entriesToRemove.add(entry);
}
}
}
entrySet.removeAll(entriesToRemove);
// Update the remaining columns in the physical table with the working info.
for (Iterator iterator = modificationsMap.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
ConceptUtilityInterface origConcept = (ConceptUtilityInterface) entry.getValue();
ConceptUtilityInterface workingConcept = (ConceptUtilityInterface) entry.getKey();
try {
origConcept.setId(workingConcept.getId());
} catch (ObjectAlreadyExistsException e) {
// This should not happen as this exception would already have been caught earlier...
}
origConcept.getConcept().clearChildProperties();
origConcept.getConcept().getChildPropertyInterfaces().putAll(
workingConcept.getConcept().getChildPropertyInterfaces());
}
// Add any columns from the working table that don't exist in the original table.
ConceptUtilityInterface[] workingColumns = tableModel.getColumns();
for (int i = 0; i < workingColumns.length; i++) {
boolean found = false;
for (Iterator iterator = modificationsMap.keySet().iterator(); iterator.hasNext() && !found;) {
found = (workingColumns[i] == iterator.next());
}
if (!found) {
try {
origTable.addPhysicalColumn((PhysicalColumn) workingColumns[i]);
} catch (ObjectAlreadyExistsException e) {
// This should not happen as this exception would already have been caught earlier...
}
}
}
}
protected Composite createConceptEditor() {
Composite conceptEditor = new Composite(cardComposite, SWT.NONE);
conceptEditor.setLayout(new FillLayout());
Group group = new Group(conceptEditor, SWT.SHADOW_OUT);
group.setText("Properties");
group.setLayout(new GridLayout());
SashForm s0 = new SashForm(group, SWT.HORIZONTAL);
s0.SASH_WIDTH = 10;
Composite leftComposite = new Composite(s0, SWT.NONE);
leftComposite.setLayout(new GridLayout());
Label wlId = new Label(leftComposite, SWT.RIGHT);
wlId.setText(Messages.getString("PhysicalTableDialog.USER_NAME_ID")); //$NON-NLS-1$
conceptIdText = new Text(leftComposite, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
conceptIdText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
propertyNavigationWidget = new PropertyNavigationWidget(leftComposite, SWT.NONE);
propertyNavigationWidget.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite rightComposite = new Composite(s0, SWT.NONE);
rightComposite.setLayout(new GridLayout());
new Label(rightComposite, SWT.RIGHT);
Combo fillerCombo = new Combo(rightComposite, SWT.NONE);
fillerCombo.setVisible(false);
propertyWidgetManager = new PropertyWidgetManager2(rightComposite, SWT.NONE, propertyEditorContext, schemaMeta
.getSecurityReference());
propertyWidgetManager.setLayoutData(new GridData(GridData.FILL_BOTH));
GridData gridData = new GridData(GridData.FILL_BOTH);
gridData.heightHint = 20;
s0.setLayoutData(gridData);
s0.setWeights(new int[] { 1, 2 });
return conceptEditor;
}
}