| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.chemistry.opencmis.workbench; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Cursor; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Font; |
| import java.awt.GridBagConstraints; |
| import java.awt.GridBagLayout; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.FocusAdapter; |
| import java.awt.event.FocusEvent; |
| import java.awt.event.KeyAdapter; |
| import java.awt.event.KeyEvent; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import javax.swing.BorderFactory; |
| import javax.swing.Box; |
| import javax.swing.BoxLayout; |
| import javax.swing.ButtonGroup; |
| import javax.swing.ImageIcon; |
| import javax.swing.JButton; |
| import javax.swing.JComboBox; |
| import javax.swing.JFrame; |
| import javax.swing.JLabel; |
| import javax.swing.JPanel; |
| import javax.swing.JRadioButton; |
| import javax.swing.JScrollPane; |
| import javax.swing.JSeparator; |
| import javax.swing.JSplitPane; |
| import javax.swing.SwingConstants; |
| import javax.swing.UIManager; |
| import javax.swing.text.JTextComponent; |
| |
| import org.apache.chemistry.opencmis.client.api.CmisObject; |
| import org.apache.chemistry.opencmis.commons.SessionParameter; |
| import org.apache.chemistry.opencmis.commons.data.Ace; |
| import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition; |
| import org.apache.chemistry.opencmis.commons.enums.AclPropagation; |
| import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl; |
| import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl; |
| import org.apache.chemistry.opencmis.workbench.model.ClientModel; |
| |
| public class AclEditorFrame extends JFrame { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final String WINDOW_TITLE = "ACL Editor"; |
| private static final ImageIcon ICON_ADD = ClientHelper.getIcon("add.png"); |
| |
| private final ClientModel model; |
| private final CmisObject object; |
| |
| private final AceList addAceList; |
| private final AceList removeAceList; |
| |
| private JRadioButton propagationRepositoryButton; |
| private JRadioButton propagationObjectOnlyButton; |
| private JRadioButton propagationPropagteButton; |
| |
| public AclEditorFrame(final ClientModel model, final CmisObject object) { |
| super(); |
| |
| this.model = model; |
| this.object = object; |
| |
| // get users |
| List<String> princiaplList = new ArrayList<String>(); |
| try { |
| princiaplList.add(""); |
| princiaplList.add("cmis:user"); |
| |
| String user = model.getClientSession().getSessionParameters().get(SessionParameter.USER); |
| if (user != null && user.length() > 0) { |
| princiaplList.add(user); |
| } |
| |
| String anonymous = model.getRepositoryInfo().getPrincipalIdAnonymous(); |
| if (anonymous != null && anonymous.length() > 0) { |
| princiaplList.add(anonymous); |
| } |
| |
| String anyone = model.getRepositoryInfo().getPrincipalIdAnyone(); |
| if (anyone != null && anyone.length() > 0) { |
| princiaplList.add(anyone); |
| } |
| |
| if (object.getAcl() != null && object.getAcl().getAces() != null) { |
| List<String> aclPrinciaplList = new ArrayList<String>(); |
| |
| for (Ace ace : object.getAcl().getAces()) { |
| String pid = ace.getPrincipalId(); |
| if (!princiaplList.contains(pid) && !aclPrinciaplList.contains(pid)) { |
| aclPrinciaplList.add(pid); |
| } |
| } |
| |
| Collections.sort(aclPrinciaplList); |
| |
| princiaplList.addAll(aclPrinciaplList); |
| } |
| } catch (Exception ex) { |
| princiaplList = new ArrayList<String>(); |
| princiaplList.add(""); |
| princiaplList.add("cmis:user"); |
| } |
| |
| // get permissions |
| List<String> permissionsList = new ArrayList<String>(); |
| try { |
| permissionsList.add(""); |
| for (PermissionDefinition pd : model.getRepositoryInfo().getAclCapabilities().getPermissions()) { |
| permissionsList.add(pd.getId()); |
| } |
| } catch (Exception ex) { |
| permissionsList = new ArrayList<String>(); |
| permissionsList.add(""); |
| permissionsList.add("cmis:read"); |
| permissionsList.add("cmis:write"); |
| permissionsList.add("cmis:all"); |
| } |
| |
| addAceList = new AceList(princiaplList, permissionsList); |
| removeAceList = new AceList(princiaplList, permissionsList); |
| |
| createGUI(); |
| } |
| |
| private void createGUI() { |
| setTitle(WINDOW_TITLE); |
| setPreferredSize(new Dimension(800, 600)); |
| setMinimumSize(new Dimension(300, 120)); |
| |
| setLayout(new BorderLayout()); |
| |
| final JPanel panel = new JPanel(); |
| panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); |
| |
| final Font labelFont = UIManager.getFont("Label.font"); |
| final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f); |
| |
| final JPanel topPanel = new JPanel(); |
| topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); |
| topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| final JLabel nameLabel = new JLabel(object.getName()); |
| nameLabel.setFont(boldFont); |
| topPanel.add(nameLabel); |
| topPanel.add(new JLabel(object.getId())); |
| add(topPanel, BorderLayout.PAGE_START); |
| |
| // ACE panels |
| final JPanel addAcePanel = createAceListPanel("Add ACEs", addAceList); |
| final JPanel removeAcePanel = createAceListPanel("Remove ACEs", removeAceList); |
| |
| JPanel centerPanel = new JPanel(new BorderLayout()); |
| |
| final JSplitPane aceSplitPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(addAcePanel), |
| new JScrollPane(removeAcePanel)); |
| |
| centerPanel.add(aceSplitPanel, BorderLayout.CENTER); |
| |
| // propagation buttons |
| propagationRepositoryButton = new JRadioButton("repository determined", true); |
| propagationObjectOnlyButton = new JRadioButton("object only", false); |
| propagationPropagteButton = new JRadioButton("propagate", false); |
| |
| try { |
| if (model.getRepositoryInfo().getAclCapabilities().getAclPropagation() == AclPropagation.OBJECTONLY) { |
| propagationPropagteButton.setEnabled(false); |
| } |
| } catch (Exception e) { |
| propagationPropagteButton.setEnabled(true); |
| } |
| |
| ButtonGroup propagtionGroup = new ButtonGroup(); |
| propagtionGroup.add(propagationRepositoryButton); |
| propagtionGroup.add(propagationObjectOnlyButton); |
| propagtionGroup.add(propagationPropagteButton); |
| |
| JPanel propagtionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); |
| propagtionPanel.add(new JLabel("ACL Propagation:")); |
| propagtionPanel.add(propagationRepositoryButton); |
| propagtionPanel.add(propagationObjectOnlyButton); |
| propagtionPanel.add(propagationPropagteButton); |
| |
| centerPanel.add(propagtionPanel, BorderLayout.PAGE_END); |
| |
| add(centerPanel, BorderLayout.CENTER); |
| |
| // update button |
| JButton updateButton = new JButton("Update"); |
| updateButton.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| updateButton.setDefaultCapable(true); |
| updateButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| if (doApply()) { |
| dispose(); |
| } |
| } |
| }); |
| |
| add(updateButton, BorderLayout.PAGE_END); |
| |
| setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); |
| pack(); |
| setLocationRelativeTo(null); |
| setVisible(true); |
| |
| aceSplitPanel.setDividerLocation(0.5f); |
| } |
| |
| private JPanel createAceListPanel(final String title, final AceList list) { |
| final Font labelFont = UIManager.getFont("Label.font"); |
| final Font boldFont = labelFont.deriveFont(Font.BOLD, labelFont.getSize2D() * 1.2f); |
| |
| final JPanel result = new JPanel(); |
| result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS)); |
| |
| final JPanel topPanel = new JPanel(); |
| topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS)); |
| topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); |
| |
| final JLabel titleLabel = new JLabel(title); |
| titleLabel.setFont(boldFont); |
| topPanel.add(titleLabel, BorderLayout.LINE_START); |
| |
| topPanel.add(Box.createHorizontalGlue()); |
| |
| final JButton addButton = new JButton(ICON_ADD); |
| addButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| list.addNewAce(); |
| } |
| }); |
| |
| topPanel.add(addButton, BorderLayout.LINE_END); |
| |
| result.add(topPanel); |
| |
| result.add(list); |
| |
| return result; |
| } |
| |
| /** |
| * Applies the ACEs. |
| */ |
| private boolean doApply() { |
| try { |
| setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
| |
| List<Ace> adds = addAceList.getAces(); |
| List<Ace> removes = removeAceList.getAces(); |
| |
| if (adds != null || removes != null) { |
| AclPropagation aclPropagation = AclPropagation.REPOSITORYDETERMINED; |
| if (propagationObjectOnlyButton.isSelected()) { |
| aclPropagation = AclPropagation.OBJECTONLY; |
| } |
| |
| if (propagationPropagteButton.isSelected()) { |
| aclPropagation = AclPropagation.PROPAGATE; |
| } |
| |
| object.applyAcl(adds, removes, aclPropagation); |
| model.reloadObject(); |
| } |
| |
| return true; |
| } catch (Exception ex) { |
| ClientHelper.showError(this, ex); |
| return false; |
| } finally { |
| setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
| } |
| } |
| |
| /** |
| * ACE list panel. |
| */ |
| private static class AceList extends JPanel { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private final List<AceInputPanel> panels; |
| private final List<String> principals; |
| private final List<String> permissions; |
| |
| public AceList(final List<String> principals, final List<String> permissions) { |
| super(); |
| |
| panels = new ArrayList<AceInputPanel>(); |
| this.principals = principals; |
| this.permissions = permissions; |
| |
| setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
| } |
| |
| public synchronized void addNewAce() { |
| AceInputPanel acePanel = new AceInputPanel(this, principals, permissions, panels.size()); |
| panels.add(acePanel); |
| |
| add(acePanel); |
| } |
| |
| public synchronized void removeAce(int position) { |
| panels.remove(position); |
| for (int i = position; i < panels.size(); i++) { |
| panels.get(i).updatePosition(i); |
| } |
| |
| removeAll(); |
| for (AceInputPanel p : panels) { |
| add(p); |
| } |
| |
| revalidate(); |
| } |
| |
| public synchronized List<Ace> getAces() { |
| List<Ace> result = new ArrayList<Ace>(); |
| |
| for (AceInputPanel p : panels) { |
| result.add(p.getAce()); |
| } |
| |
| return result.isEmpty() ? null : result; |
| } |
| } |
| |
| /** |
| * ACE input panel. |
| */ |
| public static class AceInputPanel extends JPanel { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final Color BACKGROUND1 = UIManager.getColor("Table:\"Table.cellRenderer\".background"); |
| private static final Color BACKGROUND2 = UIManager.getColor("Table.alternateRowColor"); |
| private static final Color LINE = new Color(0xB8, 0xB8, 0xB8); |
| |
| private static final ImageIcon ICON_REMOVE = ClientHelper.getIcon("remove.png"); |
| |
| private final List<String> permissions; |
| |
| private int position; |
| private final JComboBox principalBox; |
| private final JPanel permissionsPanel; |
| private final List<JComboBox> permissionBoxes; |
| |
| public AceInputPanel(final AceList list, final List<String> principals, final List<String> permissions, |
| int position) { |
| super(); |
| |
| this.permissions = permissions; |
| |
| updatePosition(position); |
| |
| setLayout(new GridBagLayout()); |
| setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, LINE), |
| BorderFactory.createEmptyBorder(10, 5, 10, 5))); |
| |
| GridBagConstraints c = new GridBagConstraints(); |
| c.gridheight = 1; |
| c.gridwidth = 1; |
| |
| // col 1 |
| c.gridx = 0; |
| c.weightx = 1; |
| c.fill = GridBagConstraints.HORIZONTAL; |
| c.anchor = GridBagConstraints.LINE_START; |
| |
| c.gridy = 0; |
| add(new JLabel("Principal:"), c); |
| |
| c.gridy = 1; |
| add(new JSeparator(SwingConstants.HORIZONTAL), c); |
| |
| c.gridy = 2; |
| add(new JLabel("Permissions:"), c); |
| |
| // col 2 |
| c.gridx = 1; |
| c.weightx = 1; |
| c.fill = GridBagConstraints.HORIZONTAL; |
| c.anchor = GridBagConstraints.LINE_START; |
| |
| principalBox = new JComboBox(principals.toArray(new String[0])); |
| principalBox.setEditable(true); |
| principalBox.setPrototypeDisplayValue("1234567890123456789012345"); |
| |
| c.gridy = 0; |
| add(principalBox, c); |
| |
| c.gridy = 1; |
| add(new JSeparator(SwingConstants.HORIZONTAL), c); |
| |
| permissionsPanel = new JPanel(); |
| permissionsPanel.setLayout(new BoxLayout(permissionsPanel, BoxLayout.Y_AXIS)); |
| permissionsPanel.setOpaque(false); |
| |
| permissionBoxes = new ArrayList<JComboBox>(); |
| |
| updatePermissionsPanel(false); |
| |
| c.gridy = 2; |
| add(permissionsPanel, c); |
| |
| // col 3 |
| c.gridx = 2; |
| c.weightx = 1; |
| c.fill = GridBagConstraints.NONE; |
| c.anchor = GridBagConstraints.LINE_END; |
| |
| c.gridy = 0; |
| JButton removeButton = new JButton(ICON_REMOVE); |
| removeButton.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| list.removeAce(getPosition()); |
| } |
| }); |
| |
| add(removeButton, c); |
| } |
| |
| private JComboBox createPermissionBox() { |
| JComboBox result = new JComboBox(permissions.toArray(new String[0])); |
| result.setEditable(true); |
| result.setPrototypeDisplayValue("1234567890123456789012345"); |
| |
| JTextComponent editor = (JTextComponent) result.getEditor().getEditorComponent(); |
| editor.addFocusListener(new FocusAdapter() { |
| @Override |
| public void focusLost(FocusEvent event) { |
| updatePermissionsPanel(true); |
| } |
| }); |
| |
| editor.addKeyListener(new KeyAdapter() { |
| public void keyPressed(KeyEvent e) { |
| if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_TAB) { |
| updatePermissionsPanel(true); |
| } |
| } |
| }); |
| |
| return result; |
| } |
| |
| private void updatePermissionsPanel(boolean focus) { |
| boolean changed = false; |
| |
| if (!permissionBoxes.isEmpty()) { |
| int i = 0; |
| while (i < permissionBoxes.size() - 1) { |
| if (permissionBoxes.get(i).getSelectedItem().toString().trim().length() == 0) { |
| permissionBoxes.remove(i); |
| changed = true; |
| } else { |
| i++; |
| } |
| } |
| |
| if (permissionBoxes.get(permissionBoxes.size() - 1).getSelectedItem().toString().trim().length() > 0) { |
| permissionBoxes.add(createPermissionBox()); |
| changed = true; |
| } |
| } else { |
| permissionBoxes.add(createPermissionBox()); |
| changed = true; |
| } |
| |
| if (changed) { |
| permissionsPanel.removeAll(); |
| |
| for (JComboBox box : permissionBoxes) { |
| permissionsPanel.add(box); |
| } |
| |
| revalidate(); |
| |
| if (focus) { |
| permissionBoxes.get(permissionBoxes.size() - 1).requestFocusInWindow(); |
| } |
| } |
| } |
| |
| private void updatePosition(int position) { |
| this.position = position; |
| setBackground(position % 2 == 0 ? BACKGROUND1 : BACKGROUND2); |
| } |
| |
| public int getPosition() { |
| return position; |
| } |
| |
| @Override |
| public Dimension getMaximumSize() { |
| return new Dimension(Short.MAX_VALUE, getPreferredSize().height); |
| } |
| |
| public Ace getAce() { |
| List<String> permissionsList = new ArrayList<String>(); |
| |
| for (JComboBox box : permissionBoxes) { |
| String permission = box.getSelectedItem().toString().trim(); |
| if (permission.length() > 0) { |
| permissionsList.add(permission); |
| } |
| } |
| |
| return new AccessControlEntryImpl(new AccessControlPrincipalDataImpl(principalBox.getSelectedItem() |
| .toString()), permissionsList); |
| } |
| } |
| } |