This project has retired. For details please refer to its Attic page.
AclEditorFrame xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.workbench;
20  
21  import java.awt.BorderLayout;
22  import java.awt.Color;
23  import java.awt.Cursor;
24  import java.awt.Dimension;
25  import java.awt.FlowLayout;
26  import java.awt.Font;
27  import java.awt.GridBagConstraints;
28  import java.awt.GridBagLayout;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import java.awt.event.FocusAdapter;
32  import java.awt.event.FocusEvent;
33  import java.awt.event.KeyAdapter;
34  import java.awt.event.KeyEvent;
35  import java.util.ArrayList;
36  import java.util.Collections;
37  import java.util.List;
38  
39  import javax.swing.BorderFactory;
40  import javax.swing.Box;
41  import javax.swing.BoxLayout;
42  import javax.swing.ButtonGroup;
43  import javax.swing.ImageIcon;
44  import javax.swing.JButton;
45  import javax.swing.JComboBox;
46  import javax.swing.JFrame;
47  import javax.swing.JLabel;
48  import javax.swing.JPanel;
49  import javax.swing.JRadioButton;
50  import javax.swing.JScrollPane;
51  import javax.swing.JSeparator;
52  import javax.swing.JSplitPane;
53  import javax.swing.SwingConstants;
54  import javax.swing.UIManager;
55  import javax.swing.text.JTextComponent;
56  
57  import org.apache.chemistry.opencmis.client.api.CmisObject;
58  import org.apache.chemistry.opencmis.commons.SessionParameter;
59  import org.apache.chemistry.opencmis.commons.data.Ace;
60  import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition;
61  import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
62  import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
63  import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
64  import org.apache.chemistry.opencmis.workbench.model.ClientModel;
65  
66  public class AclEditorFrame extends JFrame {
67  
68      private static final long serialVersionUID = 1L;
69  
70      private static final String WINDOW_TITLE = "ACL Editor";
71      private static final ImageIcon ICON_ADD = ClientHelper.getIcon("add.png");
72  
73      private final ClientModel model;
74      private final CmisObject object;
75  
76      private final AceList addAceList;
77      private final AceList removeAceList;
78  
79      private JRadioButton propagationRepositoryButton;
80      private JRadioButton propagationObjectOnlyButton;
81      private JRadioButton propagationPropagteButton;
82  
83      public AclEditorFrame(final ClientModel model, final CmisObject object) {
84          super();
85  
86          this.model = model;
87          this.object = object;
88  
89          Object[] principals;
90          try {
91              // get users
92              List<String> princiaplList = new ArrayList<String>();
93  
94              princiaplList.add("");
95              princiaplList.add("cmis:user");
96  
97              String user = model.getClientSession().getSessionParameters().get(SessionParameter.USER);
98              if (user != null && user.length() > 0) {
99                  princiaplList.add(user);
100             }
101 
102             String anonymous = model.getRepositoryInfo().getPrincipalIdAnonymous();
103             if (anonymous != null && anonymous.length() > 0) {
104                 princiaplList.add(anonymous);
105             }
106 
107             String anyone = model.getRepositoryInfo().getPrincipalIdAnyone();
108             if (anyone != null && anyone.length() > 0) {
109                 princiaplList.add(anyone);
110             }
111 
112             if (object.getAcl() != null && object.getAcl().getAces() != null) {
113                 List<String> aclPrinciaplList = new ArrayList<String>();
114 
115                 for (Ace ace : object.getAcl().getAces()) {
116                     String pid = ace.getPrincipalId();
117                     if (!princiaplList.contains(pid) && !aclPrinciaplList.contains(pid)) {
118                         aclPrinciaplList.add(pid);
119                     }
120                 }
121 
122                 Collections.sort(aclPrinciaplList);
123 
124                 princiaplList.addAll(aclPrinciaplList);
125             }
126 
127             principals = princiaplList.toArray();
128         } catch (Exception ex) {
129             principals = new Object[] { "", "cmis:user" };
130         }
131 
132         Object[] permissions;
133         try {
134             // get permissions
135             List<String> permissionsList = new ArrayList<String>();
136             permissionsList.add("");
137 
138             for (PermissionDefinition pd : model.getRepositoryInfo().getAclCapabilities().getPermissions()) {
139                 permissionsList.add(pd.getId());
140             }
141 
142             permissions = permissionsList.toArray();
143         } catch (Exception ex) {
144             permissions = new Object[] { "", "cmis:read", "cmis:write", "cmis:all" };
145         }
146 
147         addAceList = new AceList(principals, permissions);
148         removeAceList = new AceList(principals, permissions);
149 
150         createGUI();
151     }
152 
153     private void createGUI() {
154         setTitle(WINDOW_TITLE);
155         setPreferredSize(new Dimension(800, 600));
156         setMinimumSize(new Dimension(300, 120));
157 
158         setLayout(new BorderLayout());
159 
160         final JPanel panel = new JPanel();
161         panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
162 
163         final Font labelFont = UIManager.getFont("Label.font");
164         final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);
165 
166         final JPanel topPanel = new JPanel();
167         topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
168         topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
169         final JLabel nameLabel = new JLabel(object.getName());
170         nameLabel.setFont(boldFont);
171         topPanel.add(nameLabel);
172         topPanel.add(new JLabel(object.getId()));
173         add(topPanel, BorderLayout.PAGE_START);
174 
175         // ACE panels
176         final JPanel addAcePanel = createAceListPanel("Add ACEs", addAceList);
177         final JPanel removeAcePanel = createAceListPanel("Remove ACEs", removeAceList);
178 
179         JPanel centerPanel = new JPanel(new BorderLayout());
180 
181         final JSplitPane aceSplitPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(addAcePanel),
182                 new JScrollPane(removeAcePanel));
183 
184         centerPanel.add(aceSplitPanel, BorderLayout.CENTER);
185 
186         // propagation buttons
187         propagationRepositoryButton = new JRadioButton("repository determined", true);
188         propagationObjectOnlyButton = new JRadioButton("object only", false);
189         propagationPropagteButton = new JRadioButton("propagate", false);
190 
191         try {
192             if (model.getRepositoryInfo().getAclCapabilities().getAclPropagation() == AclPropagation.OBJECTONLY) {
193                 propagationPropagteButton.setEnabled(false);
194             }
195         } catch (Exception e) {
196             // ignore
197         }
198 
199         ButtonGroup propagtionGroup = new ButtonGroup();
200         propagtionGroup.add(propagationRepositoryButton);
201         propagtionGroup.add(propagationObjectOnlyButton);
202         propagtionGroup.add(propagationPropagteButton);
203 
204         JPanel propagtionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
205         propagtionPanel.add(new JLabel("ACL Propagation:"));
206         propagtionPanel.add(propagationRepositoryButton);
207         propagtionPanel.add(propagationObjectOnlyButton);
208         propagtionPanel.add(propagationPropagteButton);
209 
210         centerPanel.add(propagtionPanel, BorderLayout.PAGE_END);
211 
212         add(centerPanel, BorderLayout.CENTER);
213 
214         // update button
215         JButton updateButton = new JButton("Update");
216         updateButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
217         updateButton.setDefaultCapable(true);
218         updateButton.addActionListener(new ActionListener() {
219             public void actionPerformed(ActionEvent event) {
220                 if (doApply()) {
221                     dispose();
222                 }
223             }
224         });
225 
226         add(updateButton, BorderLayout.PAGE_END);
227 
228         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
229         pack();
230         setLocationRelativeTo(null);
231         setVisible(true);
232 
233         aceSplitPanel.setDividerLocation(0.5f);
234     }
235 
236     private JPanel createAceListPanel(final String title, final AceList list) {
237         final Font labelFont = UIManager.getFont("Label.font");
238         final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f);
239 
240         final JPanel result = new JPanel();
241         result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));
242 
243         final JPanel topPanel = new JPanel();
244         topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
245         topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
246 
247         final JLabel titleLabel = new JLabel(title);
248         titleLabel.setFont(boldFont);
249         topPanel.add(titleLabel, BorderLayout.LINE_START);
250 
251         topPanel.add(Box.createHorizontalGlue());
252 
253         final JButton addButton = new JButton(ICON_ADD);
254         addButton.addActionListener(new ActionListener() {
255             public void actionPerformed(ActionEvent event) {
256                 list.addNewAce();
257             }
258         });
259 
260         topPanel.add(addButton, BorderLayout.LINE_END);
261 
262         result.add(topPanel);
263 
264         result.add(list);
265 
266         return result;
267     }
268 
269     /**
270      * Applies the ACEs.
271      */
272     private boolean doApply() {
273         try {
274             setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
275 
276             List<Ace> adds = addAceList.getAces();
277             List<Ace> removes = removeAceList.getAces();
278 
279             if (adds != null || removes != null) {
280                 AclPropagation aclPropagation = AclPropagation.REPOSITORYDETERMINED;
281                 if (propagationObjectOnlyButton.isSelected()) {
282                     aclPropagation = AclPropagation.OBJECTONLY;
283                 }
284 
285                 if (propagationPropagteButton.isSelected()) {
286                     aclPropagation = AclPropagation.PROPAGATE;
287                 }
288 
289                 object.applyAcl(adds, removes, aclPropagation);
290                 model.reloadObject();
291             }
292 
293             return true;
294         } catch (Exception ex) {
295             ClientHelper.showError(this, ex);
296             return false;
297         } finally {
298             setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
299         }
300     }
301 
302     /**
303      * ACE list panel.
304      */
305     private static class AceList extends JPanel {
306 
307         private static final long serialVersionUID = 1L;
308 
309         private final List<AceInputPanel> panels;
310         private final Object[] principals;
311         private final Object[] permissions;
312 
313         public AceList(final Object[] principals, final Object[] permissions) {
314             super();
315 
316             panels = new ArrayList<AceInputPanel>();
317             this.principals = principals;
318             this.permissions = permissions;
319 
320             setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
321         }
322 
323         public synchronized void addNewAce() {
324             AceInputPanel acePanel = new AceInputPanel(this, principals, permissions, panels.size());
325             panels.add(acePanel);
326 
327             add(acePanel);
328         }
329 
330         public synchronized void removeAce(int position) {
331             panels.remove(position);
332             for (int i = position; i < panels.size(); i++) {
333                 panels.get(i).updatePosition(i);
334             }
335 
336             removeAll();
337             for (AceInputPanel p : panels) {
338                 add(p);
339             }
340 
341             revalidate();
342         }
343 
344         public synchronized List<Ace> getAces() {
345             List<Ace> result = new ArrayList<Ace>();
346 
347             for (AceInputPanel p : panels) {
348                 result.add(p.getAce());
349             }
350 
351             return result.isEmpty() ? null : result;
352         }
353     }
354 
355     /**
356      * ACE input panel.
357      */
358     public static class AceInputPanel extends JPanel {
359 
360         private static final long serialVersionUID = 1L;
361 
362         private static final Color BACKGROUND1 = UIManager.getColor("Table:\"Table.cellRenderer\".background");
363         private static final Color BACKGROUND2 = UIManager.getColor("Table.alternateRowColor");
364         private static final Color LINE = new Color(0xB8, 0xB8, 0xB8);
365 
366         private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png");
367 
368         private final Object[] permissions;
369 
370         private int position;
371         private final JComboBox principalBox;
372         private final JPanel permissionsPanel;
373         private final List<JComboBox> permissionBoxes;
374 
375         public AceInputPanel(final AceList list, final Object[] principals, final Object[] permissions, int position) {
376             super();
377 
378             this.permissions = permissions;
379 
380             updatePosition(position);
381 
382             setLayout(new GridBagLayout());
383             setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, LINE),
384                     BorderFactory.createEmptyBorder(10, 5, 10, 5)));
385 
386             GridBagConstraints c = new GridBagConstraints();
387             c.gridheight = 1;
388             c.gridwidth = 1;
389 
390             // col 1
391             c.gridx = 0;
392             c.weightx = 1;
393             c.fill = GridBagConstraints.HORIZONTAL;
394             c.anchor = GridBagConstraints.LINE_START;
395 
396             c.gridy = 0;
397             add(new JLabel("Principal:"), c);
398 
399             c.gridy = 1;
400             add(new JSeparator(SwingConstants.HORIZONTAL), c);
401 
402             c.gridy = 2;
403             add(new JLabel("Permissions:"), c);
404 
405             // col 2
406             c.gridx = 1;
407             c.weightx = 1;
408             c.fill = GridBagConstraints.HORIZONTAL;
409             c.anchor = GridBagConstraints.LINE_START;
410 
411             principalBox = new JComboBox(principals);
412             principalBox.setEditable(true);
413             principalBox.setPrototypeDisplayValue("1234567890123456789012345");
414 
415             c.gridy = 0;
416             add(principalBox, c);
417 
418             c.gridy = 1;
419             add(new JSeparator(SwingConstants.HORIZONTAL), c);
420 
421             permissionsPanel = new JPanel();
422             permissionsPanel.setLayout(new BoxLayout(permissionsPanel, BoxLayout.Y_AXIS));
423             permissionsPanel.setOpaque(false);
424 
425             permissionBoxes = new ArrayList<JComboBox>();
426 
427             updatePermissionsPanel(false);
428 
429             c.gridy = 2;
430             add(permissionsPanel, c);
431 
432             // col 3
433             c.gridx = 2;
434             c.weightx = 1;
435             c.fill = GridBagConstraints.NONE;
436             c.anchor = GridBagConstraints.LINE_END;
437 
438             c.gridy = 0;
439             JButton removeButton = new JButton(ICON_REMOVE);
440             removeButton.addActionListener(new ActionListener() {
441                 public void actionPerformed(ActionEvent event) {
442                     list.removeAce(getPosition());
443                 }
444             });
445 
446             add(removeButton, c);
447         }
448 
449         private JComboBox createPermissionBox() {
450             JComboBox result = new JComboBox(permissions);
451             result.setEditable(true);
452             result.setPrototypeDisplayValue("1234567890123456789012345");
453 
454             JTextComponent editor = (JTextComponent) result.getEditor().getEditorComponent();
455             editor.addFocusListener(new FocusAdapter() {
456                 @Override
457                 public void focusLost(FocusEvent event) {
458                     updatePermissionsPanel(true);
459                 }
460             });
461 
462             editor.addKeyListener(new KeyAdapter() {
463                 public void keyPressed(KeyEvent e) {
464                     if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB) {
465                         updatePermissionsPanel(true);
466                     }
467                 }
468             });
469 
470             return result;
471         }
472 
473         private void updatePermissionsPanel(boolean focus) {
474             boolean changed = false;
475 
476             if (!permissionBoxes.isEmpty()) {
477                 int i = 0;
478                 while (i < permissionBoxes.size() - 1) {
479                     if (permissionBoxes.get(i).getSelectedItem().toString().trim().length() == 0) {
480                         permissionBoxes.remove(i);
481                         changed = true;
482                     } else {
483                         i++;
484                     }
485                 }
486 
487                 if (permissionBoxes.get(permissionBoxes.size() - 1).getSelectedItem().toString().trim().length() > 0) {
488                     permissionBoxes.add(createPermissionBox());
489                     changed = true;
490                 }
491             } else {
492                 permissionBoxes.add(createPermissionBox());
493                 changed = true;
494             }
495 
496             if (changed) {
497                 permissionsPanel.removeAll();
498 
499                 for (JComboBox box : permissionBoxes) {
500                     permissionsPanel.add(box);
501                 }
502 
503                 revalidate();
504 
505                 if (focus) {
506                     permissionBoxes.get(permissionBoxes.size() - 1).requestFocusInWindow();
507                 }
508             }
509         }
510 
511         public void updatePosition(int position) {
512             this.position = position;
513             setBackground(position % 2 == 0 ? BACKGROUND1 : BACKGROUND2);
514         }
515 
516         public int getPosition() {
517             return position;
518         }
519 
520         @Override
521         public Dimension getMaximumSize() {
522             return new Dimension(Short.MAX_VALUE, getPreferredSize().height);
523         }
524 
525         public Ace getAce() {
526             List<String> permissions = new ArrayList<String>();
527 
528             for (JComboBox box : permissionBoxes) {
529                 String permission = box.getSelectedItem().toString().trim();
530                 if (permission.length() > 0) {
531                     permissions.add(permission);
532                 }
533             }
534 
535             return new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(principalBox.getSelectedItem()
536                     .toString()), permissions);
537         }
538     }
539 }