View Javadoc
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.cms.ui.workbench.internal.useradmin.commands;
17  
18  import java.util.Dictionary;
19  import java.util.Map;
20  
21  import org.argeo.cms.ArgeoNames;
22  import org.argeo.cms.CmsException;
23  import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
24  import org.argeo.cms.ui.workbench.internal.useradmin.UserAdminWrapper;
25  import org.argeo.eclipse.ui.EclipseUiUtils;
26  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
27  import org.argeo.naming.LdapAttrs;
28  import org.argeo.osgi.useradmin.UserAdminConf;
29  import org.eclipse.core.commands.AbstractHandler;
30  import org.eclipse.core.commands.ExecutionEvent;
31  import org.eclipse.core.commands.ExecutionException;
32  import org.eclipse.jface.wizard.Wizard;
33  import org.eclipse.jface.wizard.WizardDialog;
34  import org.eclipse.jface.wizard.WizardPage;
35  import org.eclipse.swt.SWT;
36  import org.eclipse.swt.events.FocusEvent;
37  import org.eclipse.swt.events.FocusListener;
38  import org.eclipse.swt.layout.GridData;
39  import org.eclipse.swt.layout.GridLayout;
40  import org.eclipse.swt.widgets.Combo;
41  import org.eclipse.swt.widgets.Composite;
42  import org.eclipse.swt.widgets.Label;
43  import org.eclipse.swt.widgets.Text;
44  import org.eclipse.ui.handlers.HandlerUtil;
45  import org.osgi.service.useradmin.Group;
46  import org.osgi.service.useradmin.Role;
47  import org.osgi.service.useradmin.UserAdminEvent;
48  
49  /** Create a new group */
50  public class NewGroup extends AbstractHandler {
51  	public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".newGroup";
52  
53  	/* DEPENDENCY INJECTION */
54  	private UserAdminWrapper userAdminWrapper;
55  
56  	public Object execute(ExecutionEvent event) throws ExecutionException {
57  		NewGroupWizard newGroupWizard = new NewGroupWizard();
58  		newGroupWizard.setWindowTitle("Group creation");
59  		WizardDialog dialog = new WizardDialog(
60  				HandlerUtil.getActiveShell(event), newGroupWizard);
61  		dialog.open();
62  		return null;
63  	}
64  
65  	private class NewGroupWizard extends Wizard {
66  
67  		// Pages
68  		private MainGroupInfoWizardPage mainGroupInfo;
69  
70  		// UI fields
71  		private Text dNameTxt, commonNameTxt, descriptionTxt;
72  		private Combo baseDnCmb;
73  
74  		public NewGroupWizard() {
75  		}
76  
77  		@Override
78  		public void addPages() {
79  			mainGroupInfo = new MainGroupInfoWizardPage();
80  			addPage(mainGroupInfo);
81  		}
82  
83  		@SuppressWarnings({ "rawtypes", "unchecked" })
84  		@Override
85  		public boolean performFinish() {
86  			if (!canFinish())
87  				return false;
88  			String commonName = commonNameTxt.getText();
89  			try {
90  				userAdminWrapper.beginTransactionIfNeeded();
91  				String dn = getDn(commonName);
92  				Group group = (Group) userAdminWrapper.getUserAdmin()
93  						.createRole(dn, Role.GROUP);
94  				Dictionary props = group.getProperties();
95  				String descStr = descriptionTxt.getText();
96  				if (EclipseUiUtils.notEmpty(descStr))
97  					props.put(LdapAttrs.description.name(), descStr);
98  				userAdminWrapper.commitOrNotifyTransactionStateChange();
99  				userAdminWrapper.notifyListeners(new UserAdminEvent(null,
100 						UserAdminEvent.ROLE_CREATED, group));
101 				return true;
102 			} catch (Exception e) {
103 				ErrorFeedback.show("Cannot create new group " + commonName, e);
104 				return false;
105 			}
106 		}
107 
108 		private class MainGroupInfoWizardPage extends WizardPage implements
109 				FocusListener, ArgeoNames {
110 			private static final long serialVersionUID = -3150193365151601807L;
111 
112 			public MainGroupInfoWizardPage() {
113 				super("Main");
114 				setTitle("General information");
115 				setMessage("Please choose a domain, provide a common name "
116 						+ "and a free description");
117 			}
118 
119 			@Override
120 			public void createControl(Composite parent) {
121 				Composite bodyCmp = new Composite(parent, SWT.NONE);
122 				setControl(bodyCmp);
123 				bodyCmp.setLayout(new GridLayout(2, false));
124 
125 				dNameTxt = EclipseUiUtils.createGridLT(bodyCmp,
126 						"Distinguished name");
127 				dNameTxt.setEnabled(false);
128 
129 				baseDnCmb = createGridLC(bodyCmp, "Base DN");
130 				// Initialise before adding the listener to avoid NPE
131 				initialiseDnCmb(baseDnCmb);
132 				baseDnCmb.addFocusListener(this);
133 
134 				commonNameTxt = EclipseUiUtils.createGridLT(bodyCmp,
135 						"Common name");
136 				commonNameTxt.addFocusListener(this);
137 
138 				Label descLbl = new Label(bodyCmp, SWT.LEAD);
139 				descLbl.setText("Description");
140 				descLbl.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false,
141 						false));
142 				descriptionTxt = new Text(bodyCmp, SWT.LEAD | SWT.MULTI
143 						| SWT.WRAP | SWT.BORDER);
144 				descriptionTxt.setLayoutData(EclipseUiUtils.fillAll());
145 				descriptionTxt.addFocusListener(this);
146 
147 				// Initialize buttons
148 				setPageComplete(false);
149 				getContainer().updateButtons();
150 			}
151 
152 			@Override
153 			public void focusLost(FocusEvent event) {
154 				String name = commonNameTxt.getText();
155 				if (EclipseUiUtils.isEmpty(name))
156 					dNameTxt.setText("");
157 				else
158 					dNameTxt.setText(getDn(name));
159 
160 				String message = checkComplete();
161 				if (message != null) {
162 					setMessage(message, WizardPage.ERROR);
163 					setPageComplete(false);
164 				} else {
165 					setMessage("Complete", WizardPage.INFORMATION);
166 					setPageComplete(true);
167 				}
168 				getContainer().updateButtons();
169 			}
170 
171 			@Override
172 			public void focusGained(FocusEvent event) {
173 			}
174 
175 			/** @return the error message or null if complete */
176 			protected String checkComplete() {
177 				String name = commonNameTxt.getText();
178 
179 				if (name.trim().equals(""))
180 					return "Common name must not be empty";
181 				Role role = userAdminWrapper.getUserAdmin()
182 						.getRole(getDn(name));
183 				if (role != null)
184 					return "Group " + name + " already exists";
185 				return null;
186 			}
187 
188 			@Override
189 			public void setVisible(boolean visible) {
190 				super.setVisible(visible);
191 				if (visible)
192 					if (baseDnCmb.getSelectionIndex() == -1)
193 						baseDnCmb.setFocus();
194 					else
195 						commonNameTxt.setFocus();
196 			}
197 		}
198 
199 		private Map<String, String> getDns() {
200 			return userAdminWrapper.getKnownBaseDns(true);
201 		}
202 
203 		private String getDn(String cn) {
204 			Map<String, String> dns = getDns();
205 			String bdn = baseDnCmb.getText();
206 			if (EclipseUiUtils.notEmpty(bdn)) {
207 				Dictionary<String, ?> props = UserAdminConf.uriAsProperties(dns
208 						.get(bdn));
209 				String dn = LdapAttrs.cn.name() + "=" + cn + ","
210 						+ UserAdminConf.groupBase.getValue(props) + "," + bdn;
211 				return dn;
212 			}
213 			return null;
214 		}
215 
216 		private void initialiseDnCmb(Combo combo) {
217 			Map<String, String> dns = userAdminWrapper.getKnownBaseDns(true);
218 			if (dns.isEmpty())
219 				throw new CmsException(
220 						"No writable base dn found. Cannot create group");
221 			combo.setItems(dns.keySet().toArray(new String[0]));
222 			if (dns.size() == 1)
223 				combo.select(0);
224 		}
225 	}
226 
227 	private Combo createGridLC(Composite parent, String label) {
228 		Label lbl = new Label(parent, SWT.LEAD);
229 		lbl.setText(label);
230 		lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
231 		Combo combo = new Combo(parent, SWT.LEAD | SWT.BORDER | SWT.READ_ONLY);
232 		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
233 		return combo;
234 	}
235 
236 	/* DEPENDENCY INJECTION */
237 	public void setUserAdminWrapper(UserAdminWrapper userAdminWrapper) {
238 		this.userAdminWrapper = userAdminWrapper;
239 	}
240 }