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