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.e4.jcr.handlers;
17  
18  import java.net.URI;
19  import java.util.Hashtable;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.jcr.Node;
24  import javax.jcr.Repository;
25  import javax.jcr.RepositoryFactory;
26  import javax.jcr.Session;
27  import javax.jcr.SimpleCredentials;
28  
29  import org.argeo.api.NodeConstants;
30  import org.argeo.api.NodeUtils;
31  import org.argeo.api.security.Keyring;
32  import org.argeo.cms.ArgeoNames;
33  import org.argeo.cms.ArgeoTypes;
34  import org.argeo.cms.e4.jcr.JcrBrowserView;
35  import org.argeo.eclipse.ui.EclipseUiException;
36  import org.argeo.eclipse.ui.dialogs.ErrorFeedback;
37  import org.argeo.jcr.JcrUtils;
38  import org.eclipse.e4.core.di.annotations.Execute;
39  import org.eclipse.e4.core.di.annotations.Optional;
40  import org.eclipse.e4.ui.model.application.ui.basic.MPart;
41  import org.eclipse.e4.ui.services.IServiceConstants;
42  import org.eclipse.jface.dialogs.Dialog;
43  import org.eclipse.jface.dialogs.IMessageProvider;
44  import org.eclipse.jface.dialogs.MessageDialog;
45  import org.eclipse.jface.dialogs.TitleAreaDialog;
46  import org.eclipse.swt.SWT;
47  import org.eclipse.swt.events.SelectionAdapter;
48  import org.eclipse.swt.events.SelectionEvent;
49  import org.eclipse.swt.graphics.Point;
50  import org.eclipse.swt.layout.GridData;
51  import org.eclipse.swt.layout.GridLayout;
52  import org.eclipse.swt.widgets.Button;
53  import org.eclipse.swt.widgets.Composite;
54  import org.eclipse.swt.widgets.Control;
55  import org.eclipse.swt.widgets.Display;
56  import org.eclipse.swt.widgets.Label;
57  import org.eclipse.swt.widgets.Shell;
58  import org.eclipse.swt.widgets.Text;
59  
60  /**
61   * Connect to a remote repository and, if successful publish it as an OSGi
62   * service.
63   */
64  public class AddRemoteRepository {
65  
66  	@Inject
67  	private RepositoryFactory repositoryFactory;
68  	@Inject
69  	private Repository nodeRepository;
70  	@Inject
71  	@Optional
72  	private Keyring keyring;
73  
74  	@Execute
75  	public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part) {
76  		JcrBrowserView view = (JcrBrowserView) part.getObject();
77  		RemoteRepositoryLoginDialog dlg = new RemoteRepositoryLoginDialog(Display.getDefault().getActiveShell());
78  		if (dlg.open() == Dialog.OK) {
79  			view.refresh(null);
80  		}
81  	}
82  
83  	// public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
84  	// this.repositoryFactory = repositoryFactory;
85  	// }
86  	//
87  	// public void setKeyring(Keyring keyring) {
88  	// this.keyring = keyring;
89  	// }
90  	//
91  	// public void setNodeRepository(Repository nodeRepository) {
92  	// this.nodeRepository = nodeRepository;
93  	// }
94  
95  	class RemoteRepositoryLoginDialog extends TitleAreaDialog {
96  		private static final long serialVersionUID = 2234006887750103399L;
97  		private Text name;
98  		private Text uri;
99  		private Text username;
100 		private Text password;
101 		private Button saveInKeyring;
102 
103 		public RemoteRepositoryLoginDialog(Shell parentShell) {
104 			super(parentShell);
105 		}
106 
107 		protected Point getInitialSize() {
108 			return new Point(600, 400);
109 		}
110 
111 		protected Control createDialogArea(Composite parent) {
112 			Composite dialogarea = (Composite) super.createDialogArea(parent);
113 			dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
114 			Composite composite = new Composite(dialogarea, SWT.NONE);
115 			composite.setLayout(new GridLayout(2, false));
116 			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
117 			setMessage("Login to remote repository", IMessageProvider.NONE);
118 			name = createLT(composite, "Name", "remoteRepository");
119 			uri = createLT(composite, "URI", "http://localhost:7070/jcr/node");
120 			username = createLT(composite, "User", "");
121 			password = createLP(composite, "Password");
122 
123 			saveInKeyring = createLC(composite, "Remember password", false);
124 			parent.pack();
125 			return composite;
126 		}
127 
128 		@Override
129 		protected void createButtonsForButtonBar(Composite parent) {
130 			super.createButtonsForButtonBar(parent);
131 			Button test = createButton(parent, 2, "Test", false);
132 			test.addSelectionListener(new SelectionAdapter() {
133 				private static final long serialVersionUID = -1829962269440419560L;
134 
135 				public void widgetSelected(SelectionEvent arg0) {
136 					testConnection();
137 				}
138 			});
139 		}
140 
141 		void testConnection() {
142 			Session session = null;
143 			try {
144 				URI checkedUri = new URI(uri.getText());
145 				String checkedUriStr = checkedUri.toString();
146 
147 				Hashtable<String, String> params = new Hashtable<String, String>();
148 				params.put(NodeConstants.LABELED_URI, checkedUriStr);
149 				Repository repository = repositoryFactory.getRepository(params);
150 				if (username.getText().trim().equals("")) {// anonymous
151 					// FIXME make it more generic
152 					session = repository.login("main");
153 				} else {
154 					// FIXME use getTextChars() when upgrading to 3.7
155 					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412
156 					char[] pwd = password.getText().toCharArray();
157 					SimpleCredentials sc = new SimpleCredentials(username.getText(), pwd);
158 					session = repository.login(sc, "main");
159 					MessageDialog.openInformation(getParentShell(), "Success",
160 							"Connection to '" + uri.getText() + "' successful");
161 				}
162 			} catch (Exception e) {
163 				ErrorFeedback.show("Connection test failed for " + uri.getText(), e);
164 			} finally {
165 				JcrUtils.logoutQuietly(session);
166 			}
167 		}
168 
169 		@Override
170 		protected void okPressed() {
171 			Session nodeSession = null;
172 			try {
173 				nodeSession = nodeRepository.login();
174 				Node home = NodeUtils.getUserHome(nodeSession);
175 
176 				Node remote = home.hasNode(ArgeoNames.ARGEO_REMOTE) ? home.getNode(ArgeoNames.ARGEO_REMOTE)
177 						: home.addNode(ArgeoNames.ARGEO_REMOTE);
178 				if (remote.hasNode(name.getText()))
179 					throw new EclipseUiException("There is already a remote repository named " + name.getText());
180 				Node remoteRepository = remote.addNode(name.getText(), ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
181 				remoteRepository.setProperty(ArgeoNames.ARGEO_URI, uri.getText());
182 				remoteRepository.setProperty(ArgeoNames.ARGEO_USER_ID, username.getText());
183 				nodeSession.save();
184 				if (saveInKeyring.getSelection()) {
185 					String pwdPath = remoteRepository.getPath() + '/' + ArgeoNames.ARGEO_PASSWORD;
186 					keyring.set(pwdPath, password.getText().toCharArray());
187 				}
188 				nodeSession.save();
189 				MessageDialog.openInformation(getParentShell(), "Repository Added",
190 						"Remote repository '" + username.getText() + "@" + uri.getText() + "' added");
191 
192 				super.okPressed();
193 			} catch (Exception e) {
194 				ErrorFeedback.show("Cannot add remote repository", e);
195 			} finally {
196 				JcrUtils.logoutQuietly(nodeSession);
197 			}
198 		}
199 
200 		/** Creates label and text. */
201 		protected Text createLT(Composite parent, String label, String initial) {
202 			new Label(parent, SWT.NONE).setText(label);
203 			Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
204 			text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
205 			text.setText(initial);
206 			return text;
207 		}
208 
209 		/** Creates label and check. */
210 		protected Button createLC(Composite parent, String label, Boolean initial) {
211 			new Label(parent, SWT.NONE).setText(label);
212 			Button check = new Button(parent, SWT.CHECK);
213 			check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
214 			check.setSelection(initial);
215 			return check;
216 		}
217 
218 		protected Text createLP(Composite parent, String label) {
219 			new Label(parent, SWT.NONE).setText(label);
220 			Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
221 			text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
222 			return text;
223 		}
224 	}
225 }