/** * */ package org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.nightlabs.base.ui.layout.WeightedTableLayout; import org.nightlabs.base.ui.table.AbstractTableComposite; import org.nightlabs.jfire.base.JFireEjb3Factory; import org.nightlabs.jfire.base.login.ui.Login; import org.nightlabs.jfire.reporting.ReportManagerRemote; import org.nightlabs.jfire.reporting.admin.ui.resource.Messages; import org.nightlabs.jfire.reporting.oda.jfs.IJFSQueryPropertySetMetaData; import org.nightlabs.jfire.reporting.oda.jfs.JFSQueryPropertySet; import org.nightlabs.jfire.reporting.oda.jfs.IJFSQueryPropertySetMetaData.IEntry; /** * A table Composite that shows and is able to manipulate the properties of a {@link JFSQueryPropertySet}. * It manages the properties as elements of type {@link JFSQueryPropertySetTableEntry}. * The table allows the editing of all property values. The property names can be edited as well * given that the property is not references in the meta-data of the current {@link JFSQueryPropertySet}. * The table also provides methods to add and remove elements, * however it only removes properties that don't come from the meta-data. * * @author Alexander Bieber <!-- alex [AT] nightlabs [DOT] de --> */ public class JFSQueryPropertySetTable extends AbstractTableComposite<JFSQueryPropertySetTableEntry> { private static final Logger logger = Logger.getLogger(JFSQueryPropertySetTable.class); /** * Create a new {@link JFSQueryPropertySetTable}. * * @param parent The parent to use. * @param style The style to apply. */ public JFSQueryPropertySetTable(Composite parent, int style) { super(parent, style); } /** * Create a new {@link JFSQueryPropertySetTable}. * * @param parent The parent to use. * @param style The style to apply. * @param initTable Whether to initialize the table (i.e. set label/content-provider etc.). */ public JFSQueryPropertySetTable(Composite parent, int style, boolean initTable) { super(parent, style, initTable); } /* (non-Javadoc) * @see org.nightlabs.base.ui.table.AbstractTableComposite#createTableColumns(org.eclipse.jface.viewers.TableViewer, org.eclipse.swt.widgets.Table) */ @Override protected void createTableColumns(TableViewer tableViewer, Table table) { TableViewerColumn nameColumn = new TableViewerColumn(tableViewer, SWT.LEFT); nameColumn.getColumn().setText(Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.column.name.text")); //$NON-NLS-1$ nameColumn.setLabelProvider(new CellLabelProvider() { @Override public void update(ViewerCell cell) { JFSQueryPropertySetTableEntry entry = (JFSQueryPropertySetTableEntry) cell.getElement(); cell.setText(entry.getName()); } }); TableViewerColumn valueColumn = new TableViewerColumn(tableViewer, SWT.LEFT); valueColumn.getColumn().setText(Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.column.value.text")); //$NON-NLS-1$ valueColumn.setLabelProvider(new CellLabelProvider() { @Override public void update(ViewerCell cell) { JFSQueryPropertySetTableEntry entry = (JFSQueryPropertySetTableEntry) cell.getElement(); if (entry.getValue() != null && !"".equals(entry.getValue())) //$NON-NLS-1$ cell.setText(entry.getValue()); else cell.setText(""); //$NON-NLS-1$ } }); valueColumn.setEditingSupport(createValueEditingSupport()); nameColumn.setEditingSupport(createNameEditingSupport()); table.setLayout(new WeightedTableLayout(new int[] {1, 1})); } /** * Creates the {@link EditingSupport} for the value column. * It manages the value property within the {@link JFSQueryPropertySetTableEntry} * elements of this table. * * @return The {@link EditingSupport} for the value column. */ protected EditingSupport createValueEditingSupport() { return new EditingSupport(getTableViewer()) { private TextCellEditor cellEditor; @Override protected boolean canEdit(Object element) { return element instanceof JFSQueryPropertySetTableEntry; } @Override protected CellEditor getCellEditor(Object element) { if (cellEditor == null) { cellEditor = new TextCellEditor(getTable()); } return cellEditor; } @Override protected Object getValue(Object element) { String value = ((JFSQueryPropertySetTableEntry) element).getValue(); if (value == null) return ""; //$NON-NLS-1$ return value; } @Override protected void setValue(Object element, Object value) { ((JFSQueryPropertySetTableEntry) element).setValue((String) value); getTableViewer().refresh(element, true); } }; } /** * Creates the {@link EditingSupport} for the name column. * It manages the name property within the {@link JFSQueryPropertySetTableEntry} * elements of this table. Only the names of properties that * don't come from the meta-data of the Script referecned by the * {@link JFSQueryPropertySet}. * * @return The {@link EditingSupport} for the value column. */ protected EditingSupport createNameEditingSupport() { return new EditingSupport(getTableViewer()) { private TextCellEditor cellEditor; @Override protected boolean canEdit(Object element) { return (element instanceof JFSQueryPropertySetTableEntry) && !((JFSQueryPropertySetTableEntry) element).isFromMetaData(); } @Override protected CellEditor getCellEditor(Object element) { if (cellEditor == null) { cellEditor = new TextCellEditor(getTable()); } return cellEditor; } @Override protected Object getValue(Object element) { String name = ((JFSQueryPropertySetTableEntry) element).getName(); if (name == null) return ""; //$NON-NLS-1$ return name; } @Override protected void setValue(Object element, Object value) { String name = (String) value; if (name == null || "".equals(name)) { //$NON-NLS-1$ MessageDialog.openInformation( getShell(), Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.emptyProperty.title"), //$NON-NLS-1$ Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.emptyProperty.message1") + //$NON-NLS-1$ Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.emptyProperty.message2")); //$NON-NLS-1$ return; } JFSQueryPropertySetTableEntry entry = (JFSQueryPropertySetTableEntry) element; for (JFSQueryPropertySetTableEntry checkEntry : entries) { if (entry != checkEntry && name.equals(checkEntry.getName())) { MessageDialog.openInformation( getShell(), Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.duplicateProperty.title"), //$NON-NLS-1$ Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.duplicateProperty.message1") + //$NON-NLS-1$ Messages.getString("org.nightlabs.jfire.reporting.admin.ui.oda.jfs.client.ui.property.JFSQueryPropertySetTable.dialog.duplicateProperty.message2")); //$NON-NLS-1$ return; } } entry.setName(name); getTableViewer().refresh(element, true); } }; } /* (non-Javadoc) * @see org.nightlabs.base.ui.table.AbstractTableComposite#setTableProvider(org.eclipse.jface.viewers.TableViewer) */ @Override protected void setTableProvider(TableViewer tableViewer) { tableViewer.setContentProvider(new ArrayContentProvider()); // tableViewer.setSorter(new ViewerSorter() { // @Override // public int category(Object element) { // return ((JFSQueryPropertySetTableEntry) element).isFromMetaData() ? 0 : 1; // } // }); } /** * Query the {@link IJFSQueryPropertySetMetaData} of the Script referenced by the given * {@link JFSQueryPropertySet}. This currently accesses the {@link ReportManager} bean * directly. * * @param queryPropertySet The {@link JFSQueryPropertySet} to get the meta-data for. * @return The {@link IJFSQueryPropertySetMetaData} for the Script referenced by the given {@link JFSQueryPropertySet}. */ protected IJFSQueryPropertySetMetaData getJFSQueryPropertySetMetaData(JFSQueryPropertySet queryPropertySet) { try { ReportManagerRemote rm = JFireEjb3Factory.getRemoteBean(ReportManagerRemote.class, Login.getLogin().getInitialContextProperties()); return rm.getJFSQueryPropertySetMetaData(queryPropertySet.getScriptRegistryItemID()); } catch (Exception e) { throw new RuntimeException(e); } } /** * Initialize this table with the properties of the given queryPropertySet. * * @param queryPropertySet The {@link JFSQueryPropertySet} to initialize the table with. */ public void setJFSQueryPropertySet(JFSQueryPropertySet queryPropertySet) { Set<String> definedProps = new HashSet<String>(queryPropertySet.getProperties().keySet()); IJFSQueryPropertySetMetaData metaData = getJFSQueryPropertySetMetaData(queryPropertySet); List<JFSQueryPropertySetTableEntry> entries = new LinkedList<JFSQueryPropertySetTableEntry>(); // All entries from the meta-data first for (IEntry metaDataEntry : metaData.getEntries()) { if (definedProps.contains(metaDataEntry.getName())) { // value set for a property from the meta-data String value = queryPropertySet.getProperties().get(metaDataEntry.getName()); JFSQueryPropertySetTableEntry entry = new JFSQueryPropertySetTableEntry( true, metaDataEntry.isRequired(), metaDataEntry.getName()); entry.setValue(value); entries.add(entry); definedProps.remove(metaDataEntry.getName()); } else { // value NOT set for a property from the meta-data JFSQueryPropertySetTableEntry entry = new JFSQueryPropertySetTableEntry( true, metaDataEntry.isRequired(), metaDataEntry.getName()); entries.add(entry); } } // then all other defined properties for (String definedPropName : definedProps) { String value = queryPropertySet.getProperties().get(definedPropName); JFSQueryPropertySetTableEntry entry = new JFSQueryPropertySetTableEntry( false, false, definedPropName); entry.setValue(value); entries.add(entry); } setInput(entries); } private List<JFSQueryPropertySetTableEntry> entries = null; @SuppressWarnings("unchecked") @Override public void setInput(Object input) { if (input instanceof List) { entries = (List<JFSQueryPropertySetTableEntry>) input; super.setInput(input); } else { logger.error(this.getClass().getName() + " received an unexpected input type " + input.getClass().getName()); //$NON-NLS-1$ } } /** * Removes the first selected entry from this table. * Note, that this will have no effect if the first * selected element is a property referenced in * the meta-data of the curren {@link JFSQueryPropertySet}. */ public void removeFirstSelectedEntry() { JFSQueryPropertySetTableEntry entry = getFirstSelectedElement(); if (entry == null) return; entries.remove(entry); refresh(true); } /** * Checks if the given name can be used as property name * in the given set of properties. * * @param name The name to check. * @return Whether the given name can be used as property name in the current set. */ private boolean checkNewPropertyName(String name) { for (JFSQueryPropertySetTableEntry entry : entries) { if (name.equals(entry.getName())) return false; } return true; } /** * Adds a new entry to the list of properties of this table * and will select its name column for editing. * @return The newly created {@link JFSQueryPropertySetTableEntry}. */ public JFSQueryPropertySetTableEntry createNewEntry() { String namePrefix = "NewProperty"; //$NON-NLS-1$ int i = 1; while (!checkNewPropertyName(namePrefix + i)) i++; JFSQueryPropertySetTableEntry entry = new JFSQueryPropertySetTableEntry( false, false, namePrefix + i ); entries.add(entry); refresh(true); getTableViewer().editElement(entry, 0); return entry; } /** * Collect the properties from the table as they should be set * to a {@link JFSQueryPropertySet}. * * @return The properties collected from the table. */ public Map<String, String> getProperties() { Map<String, String> result = new HashMap<String, String>(); if (entries != null) { for (JFSQueryPropertySetTableEntry entry : entries) { result.put(entry.getName(), entry.getValue()); } } return result; } }