001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.gui.access;
019:
020: import java.awt.Color;
021: import java.awt.datatransfer.Transferable;
022: import java.awt.datatransfer.UnsupportedFlavorException;
023: import java.awt.dnd.DnDConstants;
024: import java.awt.dnd.DragGestureEvent;
025: import java.awt.dnd.DragGestureListener;
026: import java.awt.dnd.DragSource;
027: import java.awt.dnd.DragSourceDragEvent;
028: import java.awt.dnd.DragSourceDropEvent;
029: import java.awt.dnd.DragSourceEvent;
030: import java.awt.dnd.DragSourceListener;
031: import java.awt.dnd.DropTarget;
032: import java.awt.dnd.DropTargetDragEvent;
033: import java.awt.dnd.DropTargetDropEvent;
034: import java.awt.dnd.DropTargetEvent;
035: import java.awt.dnd.DropTargetListener;
036: import java.awt.event.ActionEvent;
037: import java.awt.event.ActionListener;
038: import java.io.IOException;
039: import java.util.logging.Level;
040: import java.util.logging.Logger;
041:
042: import javax.swing.DefaultCellEditor;
043: import javax.swing.Icon;
044: import javax.swing.JButton;
045: import javax.swing.JCheckBox;
046: import javax.swing.JLabel;
047: import javax.swing.JTable;
048: import javax.swing.table.TableCellRenderer;
049:
050: import de.finix.contelligent.client.ContelligentClient;
051: import de.finix.contelligent.client.base.ContelligentComponent;
052: import de.finix.contelligent.client.base.Type;
053: import de.finix.contelligent.client.i18n.Resources;
054: import de.finix.contelligent.client.security.ComponentAccess;
055: import de.finix.contelligent.client.security.Principal;
056: import de.finix.contelligent.client.util.ExceptionDialog;
057: import de.finix.contelligent.client.util.SwingWorker;
058: import de.finix.contelligent.client.util.dnd.SingleComponentTransferable;
059: import de.finix.contelligent.client.util.list.NameValueComboBox;
060:
061: public class AccessTable extends JTable implements DropTargetListener,
062: DragSourceListener, DragGestureListener {
063:
064: private static Logger logger = Logger.getLogger(AccessTable.class
065: .getName());
066:
067: private boolean editable;
068:
069: private AccessTableModel accessTableModel;
070:
071: public AccessTable(AccessTableModel accessTableModel) {
072: super (accessTableModel);
073: this .accessTableModel = accessTableModel;
074: setDefaultEditor(ComponentAccess.class, new AccessEditor(this ));
075: setDefaultRenderer(ComponentAccess.class, new AccessRenderer(
076: this ));
077: DropTarget dropTarget = new DropTarget(this , this );
078: DragSource dragSource = new DragSource();
079: dragSource.createDefaultDragGestureRecognizer(this ,
080: DnDConstants.ACTION_MOVE, this );
081: }
082:
083: /**
084: * Utility method used both as cell renderer and editor.
085: */
086: static Icon getTimeIcon(ComponentAccess access) {
087: if (access.getType() == 0) {
088: return Resources.accessOnIcon;
089: } else if (access.getType() == 1) {
090: if (access.isValid()) {
091: return Resources.accessStartOnIcon;
092: } else {
093: return Resources.accessStartOffIcon;
094: }
095: } else if (access.getType() == 2) {
096: if (access.isValid()) {
097: return Resources.accessEndOnIcon;
098: } else {
099: return Resources.accessExpiredIcon;
100: }
101: } else {
102: if (access.isValid()) {
103: return Resources.accessStartEndOnIcon;
104: } else {
105: if (access.getValidFrom() > System.currentTimeMillis()) {
106: return Resources.accessStartEndOffIcon;
107: } else {
108: return Resources.accessExpiredIcon;
109: }
110: }
111: }
112: }
113:
114: class AccessEditor extends DefaultCellEditor {
115: private ComponentAccess entry;
116:
117: private AccessTable accessTable;
118:
119: public AccessEditor(AccessTable accessTable) {
120: super (new JCheckBox()); // Bad Swing design
121: this .accessTable = accessTable;
122: }
123:
124: protected void fireEditingStopped() {
125: super .fireEditingStopped();
126: }
127:
128: public Object getCellEditorValue() {
129: return entry;
130: }
131:
132: public java.awt.Component getTableCellEditorComponent(
133: JTable table, Object value, boolean isSelected,
134: int row, int column) {
135:
136: if (column == 2) {
137: entry = (ComponentAccess) value;
138:
139: NameValueComboBox modeList = ComponentAccess
140: .getDescriptionComboBox(ComponentAccess.MODES);
141:
142: modeList.addActionListener(new ActionListener() {
143: public void actionPerformed(ActionEvent e) {
144: NameValueComboBox ml = (NameValueComboBox) e
145: .getSource();
146: entry.setMode((String) ml
147: .getSelectedItemValue());
148: fireEditingStopped();
149: accessTable.resizeAndRepaint();
150: }
151: });
152: return modeList;
153: } else if (column == 3) {
154: JButton jb = new JButton(AccessTable
155: .getTimeIcon((ComponentAccess) value));
156: jb.setContentAreaFilled(false);
157: jb.addActionListener(new TimeButtonActionListener(
158: (ComponentAccess) value));
159: return jb;
160: } else {
161: return null;
162: }
163: }
164:
165: class TimeButtonActionListener implements ActionListener {
166:
167: ComponentAccess access;
168:
169: public TimeButtonActionListener(ComponentAccess access) {
170: this .access = access;
171: }
172:
173: public void actionPerformed(ActionEvent arg0) {
174: TimeDialog tf = new TimeDialog(access,
175: ContelligentClient.getActiveFrame());
176: tf.setVisible(true);
177: if (tf.getResult()) {
178: fireEditingStopped();
179: accessTableModel.getComponent()
180: .setAclModified(true);
181: } else {
182: fireEditingCanceled();
183: }
184: }
185: }
186:
187: }
188:
189: class AccessRenderer implements TableCellRenderer {
190:
191: AccessTable accessTable;
192:
193: public AccessRenderer(AccessTable accessTable) {
194: this .accessTable = accessTable;
195: }
196:
197: public java.awt.Component getTableCellRendererComponent(
198: JTable table, Object object, boolean isSelected,
199: boolean hasFocus, int row, int column) {
200: JLabel cellRenderer = new JLabel();
201: cellRenderer.setOpaque(true);
202: ComponentAccess entry = (ComponentAccess) object;
203: if (isSelected) {
204: cellRenderer.setBackground(table
205: .getSelectionBackground());
206: cellRenderer.setForeground(table
207: .getSelectionForeground());
208: } else {
209: cellRenderer.setBackground(table.getBackground());
210: if (entry.isInherited()) {
211: cellRenderer.setForeground(Color.gray);
212: } else {
213: cellRenderer.setForeground(Color.black);
214: }
215: }
216: if (column == 0) {
217: cellRenderer.setText(entry.getPrincipalDisplayName());
218: } else if (column == 1) {
219: cellRenderer.setText(entry.getPermissionDisplayName());
220: } else if (column == 2) {
221: cellRenderer.setText(entry.getVisibleModeDisplayName());
222: } else if (column == 3) {
223: JButton jb = new JButton(AccessTable
224: .getTimeIcon((ComponentAccess) object));
225: jb.setContentAreaFilled(false);
226: return jb;
227: }
228: cellRenderer.setFont(table.getFont());
229: return cellRenderer;
230: }
231: }
232:
233: /**
234: * is invoked when you are dragging over the DropSite
235: *
236: */
237: public void dragEnter(DropTargetDragEvent event) {
238: // debug messages for diagnostics
239: event.acceptDrag(DnDConstants.ACTION_MOVE);
240: }
241:
242: /**
243: * is invoked when you are exit the DropSite without dropping
244: *
245: */
246: public void dragExit(DropTargetEvent event) {
247: }
248:
249: /**
250: * is invoked when a drag operation is going on
251: *
252: */
253: public void dragOver(DropTargetDragEvent event) {
254: }
255:
256: /**
257: * a drop has occurred
258: *
259: */
260: public void drop(DropTargetDropEvent event) {
261: // TODO: This seems to be code for the old, old user system. See if we can remove this.
262: if (editable) {
263: try {
264: Transferable transferable = event.getTransferable();
265:
266: // we accept ContelligentComponent and Strings
267: if (transferable
268: .isDataFlavorSupported(SingleComponentTransferable.componentFlavor)) {
269: event.acceptDrop(DnDConstants.ACTION_MOVE);
270: final ContelligentComponent droppedComponent = (ContelligentComponent) transferable
271: .getTransferData(SingleComponentTransferable.componentFlavor);
272: event.getDropTargetContext().dropComplete(true);
273: if (droppedComponent.instanceOf(Type.ROLE)
274: || droppedComponent.instanceOf(Type.USER)) {
275: SwingWorker worker = new SwingWorker(
276: "AccessTable-Thread") {
277: public Object construct() {
278: // ask for the permission
279: PermissionOptionPane permissionOptionPane = new PermissionOptionPane();
280: if (permissionOptionPane
281: .showPermissionDialog(
282: Resources
283: .getLocalString("choose_permission"),
284: Resources
285: .getLocalString("permission_to_grant")) == PermissionOptionPane.OK_OPTION) {
286: logger.log(Level.FINE,
287: "Permissionchooser OK");
288: return permissionOptionPane
289: .getPermission();
290: }
291: return null;
292: }
293:
294: // Runs on the event-dispatching thread.
295: public void finished() {
296: logger.log(Level.FINE, "Permission '"
297: + getValue() + "' added");
298: if (getValue() != null) {
299: String permission = (String) getValue();
300: String principalString = droppedComponent
301: .getPropertyValue(ContelligentComponent.PRINCIPAL_STRING);
302: String principalGroupId = principalString
303: .substring(
304: 0,
305: principalString
306: .indexOf(":"));
307: ;
308: String principalId = principalString
309: .substring(principalString
310: .indexOf(":") + 1);
311: ;
312: // check if permission is already inherited
313: ((AccessTableModel) getModel())
314: .addAclEntry(new ComponentAccess(
315: new Principal(
316: principalGroupId,
317: principalId),
318: permission,
319: ComponentAccess.ALLOW,
320: ComponentAccess.UNSET,
321: -1, -1, -1, -1));
322: }
323: }
324: };
325: worker.start();
326: }
327: } else {
328: event.rejectDrop();
329: }
330: } catch (IOException exception) {
331: ExceptionDialog.show(exception);
332: event.rejectDrop();
333: } catch (UnsupportedFlavorException ufException) {
334: ExceptionDialog.show(ufException);
335: event.rejectDrop();
336: }
337: }
338: }
339:
340: /**
341: * is invoked if the use modifies the current drop gesture
342: *
343: */
344: public void dropActionChanged(DropTargetDragEvent event) {
345: }
346:
347: /**
348: * a drag gesture has been initiated
349: *
350: */
351: public void dragGestureRecognized(DragGestureEvent event) {
352: }
353:
354: /**
355: * this message goes to DragSourceListener, informing it that the dragging
356: * has ended
357: *
358: */
359: public void dragDropEnd(DragSourceDropEvent event) {
360: if (event.getDropSuccess()) {
361: // removeElement((ContelligentComponent)event.getDragSourceContext().getTransferable());
362: }
363: }
364:
365: /**
366: * this message goes to DragSourceListener, informing it that the dragging
367: * has entered the DropSite
368: *
369: */
370: public void dragEnter(DragSourceDragEvent event) {
371: }
372:
373: /**
374: * this message goes to DragSourceListener, informing it that the dragging
375: * has exited the DropSite
376: *
377: */
378: public void dragExit(DragSourceEvent event) {
379: }
380:
381: /**
382: * this message goes to DragSourceListener, informing it that the dragging
383: * is currently ocurring over the DropSite
384: *
385: */
386: public void dragOver(DragSourceDragEvent event) {
387: }
388:
389: /**
390: * is invoked when the user changes the dropAction
391: *
392: */
393: public void dropActionChanged(DragSourceDragEvent event) {
394: }
395:
396: public void setEditable(boolean editable) {
397: this .editable = editable;
398: }
399:
400: public boolean isEditable() {
401: return editable;
402: }
403: }
|