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.slc.client.ui.dist.wizards;
17  
18  import java.net.URI;
19  
20  import javax.jcr.Node;
21  import javax.jcr.NodeIterator;
22  import javax.jcr.Property;
23  import javax.jcr.Repository;
24  import javax.jcr.RepositoryFactory;
25  import javax.jcr.Session;
26  import javax.jcr.SimpleCredentials;
27  import javax.jcr.nodetype.NodeType;
28  
29  import org.argeo.cms.ArgeoNames;
30  import org.argeo.cms.ArgeoTypes;
31  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
32  import org.argeo.jcr.JcrUtils;
33  import org.argeo.node.NodeUtils;
34  import org.argeo.node.security.Keyring;
35  import org.argeo.slc.SlcException;
36  import org.argeo.slc.repo.RepoConstants;
37  import org.eclipse.jface.dialogs.MessageDialog;
38  import org.eclipse.jface.resource.JFaceResources;
39  import org.eclipse.jface.wizard.Wizard;
40  import org.eclipse.jface.wizard.WizardPage;
41  import org.eclipse.swt.SWT;
42  import org.eclipse.swt.events.SelectionAdapter;
43  import org.eclipse.swt.events.SelectionEvent;
44  import org.eclipse.swt.events.SelectionListener;
45  import org.eclipse.swt.layout.GridData;
46  import org.eclipse.swt.layout.GridLayout;
47  import org.eclipse.swt.widgets.Button;
48  import org.eclipse.swt.widgets.Composite;
49  import org.eclipse.swt.widgets.Label;
50  import org.eclipse.swt.widgets.Text;
51  
52  /**
53   * 
54   * Registers a new remote repository in the current Node.
55   * 
56   */
57  public class RegisterRepoWizard extends Wizard {
58  
59  	// Business objects
60  	private Keyring keyring;
61  	private RepositoryFactory repositoryFactory;
62  	private Repository nodeRepository;
63  
64  	// Pages
65  	private DefineModelPage page;
66  
67  	// Widgets of model page
68  	private Text name;
69  	private Text uri;
70  	private Text username;
71  	private Text password;
72  	private Button saveInKeyring;
73  
74  	// Default values
75  	private final static String DEFAULT_NAME = "Argeo Public Repository";
76  	private final static String DEFAULT_URI = "https://forge.argeo.org/jcr/java";
77  	private final static String DEFAULT_USER_NAME = "anonymous";
78  	private final static boolean DEFAULT_ANONYMOUS = true;
79  
80  	public RegisterRepoWizard(Keyring keyring, RepositoryFactory repositoryFactory, Repository nodeRepository) {
81  		super();
82  		this.keyring = keyring;
83  		this.repositoryFactory = repositoryFactory;
84  		this.nodeRepository = nodeRepository;
85  	}
86  
87  	@Override
88  	public void addPages() {
89  		try {
90  			page = new DefineModelPage();
91  			addPage(page);
92  			setWindowTitle("Register a new remote repository");
93  		} catch (Exception e) {
94  			throw new SlcException("Cannot add page to wizard ", e);
95  		}
96  	}
97  
98  	@Override
99  	public boolean performFinish() {
100 		if (!canFinish())
101 			return false;
102 
103 		Session nodeSession = null;
104 		try {
105 			nodeSession = nodeRepository.login();
106 			String reposPath = NodeUtils.getUserHome(nodeSession).getPath() + RepoConstants.REPOSITORIES_BASE_PATH;
107 
108 			Node repos = nodeSession.getNode(reposPath);
109 			String repoNodeName = JcrUtils.replaceInvalidChars(name.getText());
110 			if (repos.hasNode(repoNodeName))
111 				throw new SlcException("There is already a remote repository named " + repoNodeName);
112 
113 			// check if the same URI has already been registered
114 			NodeIterator ni = repos.getNodes();
115 			while (ni.hasNext()) {
116 				Node node = ni.nextNode();
117 				if (node.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY) && node.hasProperty(ArgeoNames.ARGEO_URI)
118 						&& node.getProperty(ArgeoNames.ARGEO_URI).getString().equals(uri.getText()))
119 					throw new SlcException("This URI " + uri.getText() + " is already registered, "
120 							+ "for the time being, only one instance of a single "
121 							+ "repository at a time is implemented.");
122 			}
123 
124 			Node repoNode = repos.addNode(repoNodeName, ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
125 			repoNode.setProperty(ArgeoNames.ARGEO_URI, uri.getText());
126 			repoNode.setProperty(ArgeoNames.ARGEO_USER_ID, username.getText());
127 			repoNode.addMixin(NodeType.MIX_TITLE);
128 			repoNode.setProperty(Property.JCR_TITLE, name.getText());
129 			nodeSession.save();
130 			if (saveInKeyring.getSelection()) {
131 				String pwdPath = repoNode.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD;
132 				keyring.set(pwdPath, password.getText().toCharArray());
133 				nodeSession.save();
134 			}
135 			MessageDialog.openInformation(getShell(), "Repository Added",
136 					"Remote repository " + uri.getText() + "' added");
137 		} catch (Exception e) {
138 			ErrorFeedback.show("Cannot add remote repository", e);
139 		} finally {
140 			JcrUtils.logoutQuietly(nodeSession);
141 		}
142 		return true;
143 	}
144 
145 	private class DefineModelPage extends WizardPage {
146 		private static final long serialVersionUID = 874386824101995060L;
147 
148 		public DefineModelPage() {
149 			super("Main");
150 			setTitle("Fill information to register a repository");
151 		}
152 
153 		public void createControl(Composite parent) {
154 
155 			// main layout
156 			Composite composite = new Composite(parent, SWT.NONE);
157 			composite.setLayout(new GridLayout(2, false));
158 			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
159 
160 			// Create various fields
161 			// setMessage("Login to remote repository", IMessageProvider.NONE);
162 			name = createLT(composite, "Name", DEFAULT_NAME);
163 			uri = createLT(composite, "URI", DEFAULT_URI);
164 
165 			final Button anonymousLogin = createLC(composite, "Log as anonymous", true);
166 			anonymousLogin.addSelectionListener(new SelectionListener() {
167 				private static final long serialVersionUID = 4874716406036981039L;
168 
169 				public void widgetSelected(SelectionEvent e) {
170 					if (anonymousLogin.getSelection()) {
171 						username.setText(DEFAULT_USER_NAME);
172 						password.setText("");
173 						username.setEnabled(false);
174 						password.setEnabled(false);
175 					} else {
176 						username.setText("");
177 						password.setText("");
178 						username.setEnabled(true);
179 						password.setEnabled(true);
180 					}
181 				}
182 
183 				public void widgetDefaultSelected(SelectionEvent e) {
184 				}
185 			});
186 
187 			username = createLT(composite, "User", DEFAULT_USER_NAME);
188 			password = createLP(composite, "Password");
189 			saveInKeyring = createLC(composite, "Remember password", false);
190 
191 			if (DEFAULT_ANONYMOUS) {
192 				username.setEnabled(false);
193 				password.setEnabled(false);
194 			}
195 
196 			Button test = createButton(composite, "Test");
197 			GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false, 2, 1);
198 			gd.widthHint = 140;
199 			test.setLayoutData(gd);
200 
201 			test.addSelectionListener(new SelectionAdapter() {
202 				private static final long serialVersionUID = -4034851916548656293L;
203 
204 				public void widgetSelected(SelectionEvent arg0) {
205 					testConnection();
206 				}
207 			});
208 
209 			// Compulsory
210 			setControl(composite);
211 		}
212 
213 		/** Creates label and text. */
214 		protected Text createLT(Composite parent, String label, String initial) {
215 			new Label(parent, SWT.RIGHT).setText(label);
216 			Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
217 			text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
218 			text.setText(initial);
219 			return text;
220 		}
221 
222 		/** Creates label and check. */
223 		protected Button createLC(Composite parent, String label, Boolean initial) {
224 			new Label(parent, SWT.RIGHT).setText(label);
225 			Button check = new Button(parent, SWT.CHECK);
226 			check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
227 			check.setSelection(initial);
228 			return check;
229 		}
230 
231 		/** Creates a button with a label. */
232 		protected Button createButton(Composite parent, String label) {
233 			Button button = new Button(parent, SWT.PUSH);
234 			button.setText(label);
235 			button.setFont(JFaceResources.getDialogFont());
236 			setButtonLayoutData(button);
237 			return button;
238 		}
239 
240 		/** Creates label and password field */
241 		protected Text createLP(Composite parent, String label) {
242 			new Label(parent, SWT.NONE).setText(label);
243 			Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
244 			text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
245 			return text;
246 		}
247 
248 	}
249 
250 	void testConnection() {
251 		Session session = null;
252 		try {
253 			if (uri.getText().startsWith("http")) {// http, https
254 				URI checkedUri = new URI(uri.getText());
255 				String checkedUriStr = checkedUri.toString();
256 				Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory, checkedUriStr);
257 				if (username.getText().trim().equals("")) {// anonymous
258 					session = repository.login(RepoConstants.DEFAULT_DEFAULT_WORKSPACE);
259 				} else {
260 					char[] pwd = password.getTextChars();
261 					SimpleCredentials sc = new SimpleCredentials(username.getText(), pwd);
262 					session = repository.login(sc, RepoConstants.DEFAULT_DEFAULT_WORKSPACE);
263 				}
264 			} else {// alias
265 				Repository repository = NodeUtils.getRepositoryByAlias(repositoryFactory, uri.getText());
266 				session = repository.login();
267 			}
268 			MessageDialog.openInformation(getShell(), "Success", "Connection to '" + uri.getText() + "' successful");
269 		} catch (Exception e) {
270 			ErrorFeedback.show("Connection test failed for " + uri.getText(), e);
271 		} finally {
272 			JcrUtils.logoutQuietly(session);
273 		}
274 	}
275 }