]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.ui.admin/src/org/argeo/security/ui/admin/internal/parts/GroupMainPage.java
fix wrong hierarchy
[lgpl/argeo-commons.git] / org.argeo.security.ui.admin / src / org / argeo / security / ui / admin / internal / parts / GroupMainPage.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.security.ui.admin.internal.parts;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import javax.jcr.RepositoryException;
22
23 import org.argeo.ArgeoException;
24 import org.argeo.eclipse.ui.EclipseUiUtils;
25 import org.argeo.jcr.ArgeoNames;
26 import org.argeo.security.ui.admin.internal.ColumnDefinition;
27 import org.argeo.security.ui.admin.internal.UserAdminConstants;
28 import org.argeo.security.ui.admin.internal.UserAdminWrapper;
29 import org.argeo.security.ui.admin.internal.UserTableViewer;
30 import org.argeo.security.ui.admin.internal.providers.CommonNameLP;
31 import org.argeo.security.ui.admin.internal.providers.MailLP;
32 import org.argeo.security.ui.admin.internal.providers.RoleIconLP;
33 import org.argeo.security.ui.admin.internal.providers.UserNameLP;
34 import org.argeo.security.ui.admin.internal.providers.UserTableDefaultDClickListener;
35 import org.eclipse.jface.dialogs.MessageDialog;
36 import org.eclipse.jface.viewers.TableViewer;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.jface.viewers.ViewerDropAdapter;
39 import org.eclipse.swt.SWT;
40 import org.eclipse.swt.dnd.DND;
41 import org.eclipse.swt.dnd.DropTargetEvent;
42 import org.eclipse.swt.dnd.TextTransfer;
43 import org.eclipse.swt.dnd.Transfer;
44 import org.eclipse.swt.dnd.TransferData;
45 import org.eclipse.swt.layout.GridData;
46 import org.eclipse.swt.layout.GridLayout;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Label;
49 import org.eclipse.swt.widgets.Shell;
50 import org.eclipse.swt.widgets.Text;
51 import org.eclipse.ui.forms.AbstractFormPart;
52 import org.eclipse.ui.forms.IManagedForm;
53 import org.eclipse.ui.forms.SectionPart;
54 import org.eclipse.ui.forms.editor.FormEditor;
55 import org.eclipse.ui.forms.editor.FormPage;
56 import org.eclipse.ui.forms.widgets.FormToolkit;
57 import org.eclipse.ui.forms.widgets.ScrolledForm;
58 import org.eclipse.ui.forms.widgets.Section;
59 import org.osgi.service.useradmin.Group;
60 import org.osgi.service.useradmin.Role;
61 import org.osgi.service.useradmin.User;
62 import org.osgi.service.useradmin.UserAdmin;
63 import org.osgi.service.useradmin.UserAdminEvent;
64
65 /** Display/edit main properties of a given group */
66 public class GroupMainPage extends FormPage implements ArgeoNames {
67 final static String ID = "GroupEditor.mainPage";
68
69 private final UserEditor editor;
70 private UserAdminWrapper userAdminWrapper;
71
72 // Local configuration
73 private final int PRE_TITLE_INDENT = 10;
74
75 public GroupMainPage(FormEditor editor, UserAdminWrapper userAdminWrapper) {
76 super(editor, ID, "Main");
77 this.editor = (UserEditor) editor;
78 this.userAdminWrapper = userAdminWrapper;
79 }
80
81 protected void createFormContent(final IManagedForm mf) {
82 try {
83 ScrolledForm form = mf.getForm();
84 refreshFormTitle();
85
86 // Body
87 Composite body = form.getBody();
88 GridLayout mainLayout = new GridLayout();
89 body.setLayout(mainLayout);
90 appendOverviewPart(body);
91 appendMembersPart(body);
92 } catch (RepositoryException e) {
93 throw new ArgeoException("Cannot create form content", e);
94 }
95 }
96
97 /** Creates the general section */
98 protected void appendOverviewPart(Composite parent) {
99 FormToolkit tk = getManagedForm().getToolkit();
100 Composite body = addSection(tk, parent, "Main information");
101 GridLayout layout = new GridLayout(2, false);
102 body.setLayout(layout);
103
104 Text distinguishedName = createLT(body, "Group Name",
105 editor.getProperty(UserAdminConstants.KEY_UID));
106 distinguishedName.setEnabled(false);
107
108 final Text commonName = createLT(body, "Common Name",
109 editor.getProperty(UserAdminConstants.KEY_CN));
110 commonName.setEnabled(false);
111
112 // create form part (controller)
113 AbstractFormPart part = new SectionPart((Section) body.getParent()) {
114 public void commit(boolean onSave) {
115 super.commit(onSave);
116 }
117 };
118 getManagedForm().addPart(part);
119 }
120
121 /** Filtered table with members. Has drag & drop ability */
122 protected void appendMembersPart(Composite parent)
123 throws RepositoryException {
124
125 FormToolkit tk = getManagedForm().getToolkit();
126 Section section = tk.createSection(parent, Section.TITLE_BAR);
127 section.setLayoutData(EclipseUiUtils.fillAll());
128 section.setText("Members of group "
129 + editor.getProperty(UserAdminConstants.KEY_CN));
130
131 // Composite body = tk.createComposite(section, SWT.NONE);
132 Composite body = new Composite(section, SWT.NO_FOCUS);
133 section.setClient(body);
134 body.setLayoutData(EclipseUiUtils.fillAll());
135
136 createMemberPart(body);
137
138 // create form part (controller)
139 AbstractFormPart part = new SectionPart(section) {
140 public void commit(boolean onSave) {
141 super.commit(onSave);
142 }
143 };
144
145 getManagedForm().addPart(part);
146 }
147
148 // UI Objects
149 private UserTableViewer userTableViewerCmp;
150 private TableViewer userViewer;
151 private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
152
153 public void createMemberPart(Composite parent) {
154 parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
155 // Define the displayed columns
156 columnDefs.add(new ColumnDefinition(new RoleIconLP(), "", 0, 24));
157 columnDefs.add(new ColumnDefinition(new UserNameLP(),
158 "Distinguished Name", 240));
159 columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name",
160 150));
161 columnDefs.add(new ColumnDefinition(new MailLP(), "Primary Mail", 150));
162
163 // Create and configure the table
164 userTableViewerCmp = new MyUserTableViewer(parent, SWT.MULTI
165 | SWT.H_SCROLL | SWT.V_SCROLL, userAdminWrapper.getUserAdmin());
166
167 userTableViewerCmp.setColumnDefinitions(columnDefs);
168 userTableViewerCmp.populate(true, false);
169 // userTableViewerCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
170 // false, false));
171 userTableViewerCmp.setLayoutData(EclipseUiUtils.fillAll());
172
173 // Links
174 userViewer = userTableViewerCmp.getTableViewer();
175 userViewer.addDoubleClickListener(new UserTableDefaultDClickListener());
176 // Really?
177 userTableViewerCmp.refresh();
178
179 // Drag and drop
180 int operations = DND.DROP_COPY | DND.DROP_MOVE;
181 Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };
182 userViewer.addDropSupport(operations, tt,
183 new GroupDropListener(userViewer, userAdminWrapper,
184 (Group) editor.getDisplayedUser()));
185 }
186
187 private class MyUserTableViewer extends UserTableViewer {
188 private static final long serialVersionUID = 8467999509931900367L;
189
190 public MyUserTableViewer(Composite parent, int style,
191 UserAdmin userAdmin) {
192 super(parent, style, userAdmin, true);
193 }
194
195 @Override
196 protected List<User> listFilteredElements(String filter) {
197 Group group = (Group) editor.getDisplayedUser();
198 Role[] roles = group.getMembers();
199 List<User> users = new ArrayList<User>();
200 for (Role role : roles)
201 // if (role.getType() == Role.GROUP)
202 users.add((User) role);
203 return users;
204 }
205 }
206
207 private void refreshFormTitle() throws RepositoryException {
208 getManagedForm().getForm().setText(
209 editor.getProperty(UserAdminConstants.KEY_CN));
210 }
211
212 /**
213 * Defines this table as being a potential target to add group membership
214 * (roles) to this user
215 */
216 private class GroupDropListener extends ViewerDropAdapter {
217 private static final long serialVersionUID = 2893468717831451621L;
218
219 private final UserAdminWrapper userAdminWrapper;
220 private final Group myGroup;
221
222 public GroupDropListener(Viewer viewer,
223 UserAdminWrapper userAdminWrapper, Group group) {
224 super(viewer);
225 this.userAdminWrapper = userAdminWrapper;
226 this.myGroup = group;
227 }
228
229 @Override
230 public boolean validateDrop(Object target, int operation,
231 TransferData transferType) {
232 // Target is always OK in a list only view
233 // TODO check if not a string
234 boolean validDrop = true;
235 return validDrop;
236 }
237
238 @Override
239 public void drop(DropTargetEvent event) {
240 // TODO Is there an opportunity to perform ceck before?
241
242 String newUserName = (String) event.data;
243 UserAdmin myUserAdmin = userAdminWrapper.getUserAdmin();
244 Role role = myUserAdmin.getRole(newUserName);
245 if (role.getType() == Role.USER) {
246 // TODO check if the user is already member of this group
247 userAdminWrapper.beginTransactionIfNeeded();
248 User user = (User) role;
249 myGroup.addMember(user);
250 userAdminWrapper.notifyListeners(new UserAdminEvent(null,
251 UserAdminEvent.ROLE_CHANGED, myGroup));
252 } else if (role.getType() == Role.GROUP) {
253 Group newGroup = (Group) role;
254
255 Shell shell = getViewer().getControl().getShell();
256 // Sanity checks
257 if (myGroup == newGroup) { // Equality
258 MessageDialog.openError(shell, "Forbidden addition ",
259 "A group cannot be a member of itself.");
260 return;
261 }
262
263 // Cycle
264 String myName = myGroup.getName();
265 List<User> myMemberships = editor.getFlatGroups(myGroup);
266 if (myMemberships.contains(newGroup)) {
267 MessageDialog.openError(shell, "Forbidden addition: cycle",
268 "Cannot add " + newUserName + " to group " + myName
269 + ". This would create a cycle");
270 return;
271 }
272
273 // Already member
274 List<User> newGroupMemberships = editor.getFlatGroups(newGroup);
275 if (newGroupMemberships.contains(myGroup)) {
276 MessageDialog.openError(shell, "Forbidden addition",
277 "Cannot add " + newUserName + " to group " + myName
278 + ", this membership already exists");
279 return;
280 }
281
282 userAdminWrapper.beginTransactionIfNeeded();
283 // TODO implement the dirty state
284 myGroup.addMember(newGroup);
285 userAdminWrapper.notifyListeners(new UserAdminEvent(null,
286 UserAdminEvent.ROLE_CHANGED, myGroup));
287 }
288 super.drop(event);
289 }
290
291 @Override
292 public boolean performDrop(Object data) {
293 userTableViewerCmp.refresh();
294 return true;
295 }
296 }
297
298 // LOCAL HELPERS
299 private Composite addSection(FormToolkit tk, Composite parent, String title) {
300 Section section = tk.createSection(parent, Section.TITLE_BAR);
301 GridData gd = EclipseUiUtils.fillWidth();
302 gd.verticalAlignment = PRE_TITLE_INDENT;
303 section.setLayoutData(gd);
304 section.setText(title);
305 Composite body = tk.createComposite(section, SWT.WRAP);
306 body.setLayoutData(EclipseUiUtils.fillAll());
307 section.setClient(body);
308 return body;
309 }
310
311 /** Creates label and text. */
312 protected Text createLT(Composite body, String label, String value) {
313 FormToolkit toolkit = getManagedForm().getToolkit();
314 Label lbl = toolkit.createLabel(body, label);
315 lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
316 Text text = toolkit.createText(body, value, SWT.BORDER);
317 text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
318 return text;
319 }
320 }