/*! * 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.concept.editor.rls; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.pentaho.pms.schema.security.SecurityOwner; import org.pentaho.pms.ui.concept.editor.Constants; import org.pentaho.pms.ui.concept.editor.rls.IRowLevelSecurityModel.IRlsModelListener; import org.pentaho.pms.ui.concept.editor.rls.IRowLevelSecurityModel.RlsModelEvent; /** * A specialized table for holding localized string values. Automatically persists changes to the model as they occur. * @author mlowery */ public class RlsRoleBasedConstraintTableWidget extends Composite { // ~ Static fields/initializers ====================================================================================== private static final Log logger = LogFactory.getLog(RlsRoleBasedConstraintTableWidget.class); // ~ Instance fields ================================================================================================= private Table table; private TableViewer tableViewer; private String[] columnNames = new String[] { "", "Role", "Constraint Formula" }; private IRowLevelSecurityModel rlsModel; // ~ Constructors ==================================================================================================== public RlsRoleBasedConstraintTableWidget(final Composite parent, final int style, final IRowLevelSecurityModel rlsModel) { super(parent, style); this.rlsModel = rlsModel; createContents(); } // ~ Methods ========================================================================================================= protected Map<SecurityOwner, String> cloneRoleBasedConstraintMap(Map<SecurityOwner, String> map) { Map<SecurityOwner, String> copy = new HashMap<SecurityOwner, String>(); for (Map.Entry<SecurityOwner, String> entry : map.entrySet()) { SecurityOwner clonedOwner = (SecurityOwner) entry.getKey().clone(); copy.put(clonedOwner, entry.getValue()); } return copy; } private List getColumnNames() { return Arrays.asList(columnNames); } private void createContents() { setLayout(new FormLayout()); // Create the table createTable(this); // Create and setup the TableViewer createTableViewer(); tableViewer.setContentProvider(new RlsRoleBasedConstraintTableContentProvider()); tableViewer.setLabelProvider(new RlsRoleBasedConstraintTableLabelProvider()); // TODO change this! tableViewer.setInput("hello"); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); table.setEnabled(enabled); } /** * Create the Table */ private void createTable(Composite parent) { int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION; table = new Table(parent, style); FormData fdTable = new FormData(); fdTable.top = new FormAttachment(0, 0); fdTable.left = new FormAttachment(0, 0); fdTable.right = new FormAttachment(100, 0); fdTable.bottom = new FormAttachment(100, 0); table.setLayoutData(fdTable); table.setLinesVisible(true); table.setHeaderVisible(true); TableColumn column = new TableColumn(table, SWT.CENTER, 0); column.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { tableViewer.setSorter(new RlsRoleBasedConstraintTableSorter(0)); } }); column.setText(columnNames[0]); column.setWidth(30); column = new TableColumn(table, SWT.LEFT, 1); column.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { tableViewer.setSorter(new RlsRoleBasedConstraintTableSorter(1)); } }); column.setText(columnNames[1]); column.setWidth(100); column = new TableColumn(table, SWT.LEFT, 2); column.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { tableViewer.setSorter(new RlsRoleBasedConstraintTableSorter(2)); } }); column.setText(columnNames[2]); column.setWidth(300); } /** * Create the TableViewer */ private void createTableViewer() { tableViewer = new TableViewer(table); tableViewer.setUseHashlookup(true); tableViewer.setColumnProperties(columnNames); // Set the default sorter for the viewer tableViewer.setSorter(new RlsRoleBasedConstraintTableSorter(0)); rlsModel.addRlsModelListener(new IRlsModelListener() { public void rlsModelModified(RlsModelEvent e) { tableViewer.refresh(); } }); } class RlsRoleBasedConstraintTableSorter extends ViewerSorter { private int column; public RlsRoleBasedConstraintTableSorter(int column) { this.column = column; } @Override public int compare(Viewer viewer, Object e1, Object e2) { ConstraintEntry entry1 = (ConstraintEntry) e1; ConstraintEntry entry2 = (ConstraintEntry) e2; switch (column) { case 0: return compareOwnerType(entry1, entry2); case 1: return compareOwnerName(entry1.getOwnerName(), entry2.getOwnerName()); default: return compareFormula(entry1.getFormula(), entry2.getFormula()); } } private int compareOwnerType(ConstraintEntry entry1, ConstraintEntry entry2) { // roles before users then name within roles if (entry1.getOwnerType() == entry2.getOwnerType()) { return entry1.getOwnerName().compareTo(entry2.getOwnerName()); } else if (SecurityOwner.OWNER_TYPE_ROLE == entry1.getOwnerType()) { return -1; } else { return 1; } } private int compareFormula(String formula, String formula2) { return formula.compareTo(formula2); } private int compareOwnerName(String string, String string2) { return string.compareTo(string2); } } class RlsRoleBasedConstraintTableContentProvider implements IStructuredContentProvider { public void inputChanged(Viewer v, Object oldInput, Object newInput) { } public void dispose() { } public Object[] getElements(final Object parent) { ConstraintEntry[] entries = new ConstraintEntry[rlsModel.getOwners().size()]; int i = 0; for (SecurityOwner owner : rlsModel.getOwners()) { entries[i] = new ConstraintEntry(owner, rlsModel.getFormula(owner)); i++; } return entries; } } public static class ConstraintEntry { private SecurityOwner owner; private String formula; public ConstraintEntry(final SecurityOwner owner, final String formula) { this.owner = owner; this.formula = formula; } public int getOwnerType() { return owner.getOwnerType(); } public void setOwnerType(int type) { owner.setOwnerType(type); } public String getOwnerName() { return owner.getOwnerName(); } public SecurityOwner getOwner() { return owner; } public void setOwnerName(String name) { owner.setOwnerName(name); } public String getFormula() { return formula; } public void setFormula(String formula) { this.formula = formula; } public boolean equals(Object obj) { if (obj instanceof ConstraintEntry == false) { return false; } if (this == obj) { return true; } ConstraintEntry rhs = (ConstraintEntry) obj; return new EqualsBuilder().append(owner, rhs.owner).append(formula, rhs.formula).isEquals(); } public int hashCode() { return new HashCodeBuilder(29, 163).append(owner).append(formula).toHashCode(); } public String toString() { return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(owner).append(formula).toString(); } } private class RlsRoleBasedConstraintTableLabelProvider extends LabelProvider implements ITableLabelProvider { public String getColumnText(final Object element, final int columnIndex) { String result = ""; ConstraintEntry entry = (ConstraintEntry) element; switch (columnIndex) { case 0: break; case 1: result = entry.getOwnerName(); break; case 2: result = entry.getFormula(); break; default: break; } return result; } public Image getColumnImage(final Object element, final int columnIndex) { if (columnIndex == 0) { ConstraintEntry entry = (ConstraintEntry) element; if (entry.getOwnerType() == SecurityOwner.OWNER_TYPE_ROLE) { return Constants.getImageRegistry(Display.getCurrent()).get("role-icon"); } else { return Constants.getImageRegistry(Display.getCurrent()).get("user-icon"); } } else { return null; } } } public void refresh() { tableViewer.refresh(); } // poor way of providing access to selection changed events public TableViewer getTableViewer() { return tableViewer; } }