]> git.argeo.org Git - gpl/argeo-slc.git/blob - plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/FetchWizard.java
enhance UI after first feed backs.
[gpl/argeo-slc.git] / plugins / org.argeo.slc.client.ui.dist / src / main / java / org / argeo / slc / client / ui / dist / wizards / FetchWizard.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.slc.client.ui.dist.wizards;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.jcr.Credentials;
24 import javax.jcr.Node;
25 import javax.jcr.NodeIterator;
26 import javax.jcr.Repository;
27 import javax.jcr.RepositoryException;
28 import javax.jcr.RepositoryFactory;
29 import javax.jcr.Session;
30
31 import org.argeo.ArgeoMonitor;
32 import org.argeo.eclipse.ui.EclipseArgeoMonitor;
33 import org.argeo.jcr.ArgeoNames;
34 import org.argeo.jcr.ArgeoTypes;
35 import org.argeo.jcr.JcrUtils;
36 import org.argeo.jcr.UserJcrUtils;
37 import org.argeo.slc.SlcException;
38 import org.argeo.slc.client.ui.dist.DistPlugin;
39 import org.argeo.slc.client.ui.dist.PrivilegedJob;
40 import org.argeo.slc.client.ui.dist.utils.ArtifactNamesComparator;
41 import org.argeo.slc.client.ui.dist.utils.ViewerUtils;
42 import org.argeo.slc.repo.RepoConstants;
43 import org.argeo.slc.repo.RepoSync;
44 import org.argeo.slc.repo.RepoUtils;
45 import org.argeo.util.security.Keyring;
46 import org.eclipse.core.runtime.IProgressMonitor;
47 import org.eclipse.core.runtime.IStatus;
48 import org.eclipse.core.runtime.Status;
49 import org.eclipse.jface.dialogs.MessageDialog;
50 import org.eclipse.jface.viewers.CheckboxTableViewer;
51 import org.eclipse.jface.viewers.ColumnLabelProvider;
52 import org.eclipse.jface.viewers.IStructuredContentProvider;
53 import org.eclipse.jface.viewers.TableViewerColumn;
54 import org.eclipse.jface.viewers.Viewer;
55 import org.eclipse.jface.wizard.Wizard;
56 import org.eclipse.jface.wizard.WizardPage;
57 import org.eclipse.swt.SWT;
58 import org.eclipse.swt.events.ModifyEvent;
59 import org.eclipse.swt.events.ModifyListener;
60 import org.eclipse.swt.events.SelectionEvent;
61 import org.eclipse.swt.events.SelectionListener;
62 import org.eclipse.swt.layout.GridData;
63 import org.eclipse.swt.layout.GridLayout;
64 import org.eclipse.swt.widgets.Button;
65 import org.eclipse.swt.widgets.Combo;
66 import org.eclipse.swt.widgets.Composite;
67 import org.eclipse.swt.widgets.Label;
68 import org.eclipse.swt.widgets.Table;
69
70 /**
71 * Defines parameters for the fetch process and run it using a {@link RepoSync}
72 * object.
73 */
74 public class FetchWizard extends Wizard {
75
76 // private final static Log log = LogFactory.getLog(FetchWizard.class);
77
78 // Business objects
79 private Keyring keyring;
80 private RepositoryFactory repositoryFactory;
81 private Session currSession;
82 private Node targetRepoNode, sourceRepoNode;
83
84 // This page widget
85 private DefineModelPage page;
86 private CheckboxTableViewer wkspViewer;
87 private Button filesOnlyBtn;
88
89 public FetchWizard(Keyring keyring, RepositoryFactory repositoryFactory,
90 Repository nodeRepository) {
91 super();
92 this.keyring = keyring;
93 this.repositoryFactory = repositoryFactory;
94 try {
95 currSession = nodeRepository.login();
96 } catch (RepositoryException e) {
97 throw new SlcException(
98 "Unexpected error while initializing fetch wizard", e);
99 }
100 }
101
102 @Override
103 public void dispose() {
104 super.dispose();
105 JcrUtils.logoutQuietly(currSession);
106 }
107
108 @Override
109 public void addPages() {
110 try {
111 page = new DefineModelPage();
112 addPage(page);
113 setWindowTitle("Fetch...");
114 } catch (Exception e) {
115 throw new SlcException("Cannot add page to wizard ", e);
116 }
117 }
118
119 @Override
120 public boolean performFinish() {
121 if (!canFinish())
122 return false;
123 try {
124 // Target Repository
125 String targetRepoUri = targetRepoNode.getProperty(
126 ArgeoNames.ARGEO_URI).getString();
127 Repository targetRepo = RepoUtils.getRepository(repositoryFactory,
128 keyring, targetRepoNode);
129 Credentials targetCredentials = RepoUtils.getRepositoryCredentials(
130 keyring, targetRepoNode);
131
132 // Source Repository
133 String sourceRepoUri = sourceRepoNode.getProperty(
134 ArgeoNames.ARGEO_URI).getString();
135 Repository sourceRepo = RepoUtils.getRepository(repositoryFactory,
136 keyring, sourceRepoNode);
137 Credentials sourceCredentials = RepoUtils.getRepositoryCredentials(
138 keyring, sourceRepoNode);
139
140 String msg;
141
142 // no workspace has been chosen, we return
143 if (wkspViewer.getCheckedElements().length == 0) {
144 msg = "No workspace has been chosen, and thus no fetch has been done.";
145 MessageDialog.openWarning(DistPlugin.getDefault()
146 .getWorkbench().getDisplay().getActiveShell(),
147 "Warning", msg);
148 return true;
149 }
150
151 msg = "Your are about to fetch data from repository: \n\t"
152 + sourceRepoUri + "\ninto target repository: \n\t"
153 + targetRepoUri + "\nDo you really want to proceed ?";
154
155 boolean result = MessageDialog.openConfirm(DistPlugin.getDefault()
156 .getWorkbench().getDisplay().getActiveShell(),
157 "Confirm Fetch clear", msg);
158
159 if (result) {
160 RepoSync repoSync = new RepoSync(sourceRepo, sourceCredentials,
161 targetRepo, targetCredentials);
162 repoSync.setTargetRepoUri(targetRepoUri);
163 repoSync.setSourceRepoUri(sourceRepoUri);
164
165 // Specify workspaces to synchronise
166 List<String> wksps = new ArrayList<String>();
167 for (Object obj : wkspViewer.getCheckedElements()) {
168 wksps.add((String) obj);
169 }
170 repoSync.setSourceWkspList(wksps);
171
172 // Set the import files only option
173 repoSync.setFilesOnly(filesOnlyBtn.getSelection());
174
175 FetchJob job = new FetchJob(repoSync);
176 job.setUser(true);
177 job.schedule();
178 }
179
180 } catch (Exception e) {
181 throw new SlcException(
182 "Unexpected error while launching the fetch", e);
183 }
184 return true;
185 }
186
187 private class DefineModelPage extends WizardPage {
188
189 // This page widget
190 private Combo chooseSourceRepoCmb;
191
192 // Business objects
193 private Map<String, Node> sourceReposMap;
194
195 public DefineModelPage() {
196 super("Main");
197 setTitle("Define fetch parameters");
198 }
199
200 public void createControl(Composite parent) {
201
202 // main layout
203 Composite composite = new Composite(parent, SWT.NONE);
204 composite.setLayout(new GridLayout(2, false));
205
206 // Choose source repo
207 new Label(composite, SWT.NONE)
208 .setText("Choose a source repository");
209 chooseSourceRepoCmb = new Combo(composite, SWT.BORDER
210 | SWT.V_SCROLL);
211 chooseSourceRepoCmb.setItems(getSourceRepoUris());
212 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
213 chooseSourceRepoCmb.setLayoutData(gd);
214
215 // Import only files
216 filesOnlyBtn = new Button(composite, SWT.CHECK | SWT.WRAP);
217 filesOnlyBtn
218 .setText("Import only files (faster, a normalized action should be launched once done)");
219 filesOnlyBtn.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
220 false, 2, 1));
221
222 // Workspace table
223 Composite wkspTable = new Composite(composite, SWT.NONE);
224 gd = new GridData();
225 gd.horizontalSpan = 2;
226 gd.grabExcessVerticalSpace = true;
227 gd.verticalAlignment = SWT.FILL;
228 wkspTable.setLayoutData(gd);
229 wkspTable.setLayout(new GridLayout(1, false));
230 addWkspTablePart(wkspTable);
231
232 // Choose source repo
233 final Button selectAllBtn = new Button(composite, SWT.CHECK);
234 selectAllBtn.setText("Select/Unselect all");
235
236 selectAllBtn.addSelectionListener(new SelectionListener() {
237 public void widgetSelected(SelectionEvent e) {
238 wkspViewer.setAllChecked(selectAllBtn.getSelection());
239 }
240
241 public void widgetDefaultSelected(SelectionEvent e) {
242 }
243 });
244
245 chooseSourceRepoCmb.addModifyListener(new ModifyListener() {
246 public void modifyText(ModifyEvent e) {
247 String chosenUri = chooseSourceRepoCmb
248 .getItem(chooseSourceRepoCmb.getSelectionIndex());
249 sourceRepoNode = sourceReposMap.get(chosenUri);
250 wkspViewer.setInput(sourceRepoNode);
251 }
252 });
253
254 // initialize to first avalaible repo
255 if (chooseSourceRepoCmb.getItemCount() > 0)
256 chooseSourceRepoCmb.select(0);
257 // Compulsory
258 setControl(composite);
259 }
260
261 // Helper to populate avalaible source repo list
262 protected String[] getSourceRepoUris() {
263 try {
264 Node repoList = currSession.getNode(UserJcrUtils.getUserHome(
265 currSession).getPath()
266 + RepoConstants.REPOSITORIES_BASE_PATH);
267
268 String targetRepoUri = null;
269 if (targetRepoNode != null) {
270 targetRepoUri = targetRepoNode.getProperty(
271 ArgeoNames.ARGEO_URI).getString();
272 }
273 NodeIterator ni = repoList.getNodes();
274 List<String> sourceRepoNames = new ArrayList<String>();
275 // caches a map of the source repo nodes with their URI as a key
276 // to ease further processing
277 sourceReposMap = new HashMap<String, Node>();
278 while (ni.hasNext()) {
279 Node currNode = ni.nextNode();
280 if (currNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
281 String currUri = currNode.getProperty(
282 ArgeoNames.ARGEO_URI).getString();
283 if (targetRepoUri == null
284 || !targetRepoUri.equals(currUri)) {
285 sourceReposMap.put(currUri, currNode);
286 sourceRepoNames.add(currUri);
287 }
288 }
289 }
290 return sourceRepoNames.toArray(new String[sourceRepoNames
291 .size()]);
292 } catch (RepositoryException e) {
293 throw new SlcException("Error while getting repo aliases", e);
294 }
295 }
296
297 // Create the workspaces table
298 private void addWkspTablePart(Composite parent) {
299
300 Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL
301 | SWT.BORDER | SWT.CHECK);
302 table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
303 table.setLinesVisible(true);
304 table.setHeaderVisible(true);
305 wkspViewer = new CheckboxTableViewer(table);
306
307 // WORKSPACES COLUMN
308 TableViewerColumn column = ViewerUtils.createTableViewerColumn(
309 wkspViewer, "Workspaces", SWT.NONE, 400);
310 column.setLabelProvider(new ColumnLabelProvider());
311
312 wkspViewer.setContentProvider(new IStructuredContentProvider() {
313 // caches current repo
314 private Repository currSourceRepo;
315 private Credentials currSourceCred;
316
317 public void inputChanged(Viewer viewer, Object oldInput,
318 Object newInput) {
319 if (newInput != null && newInput instanceof Node) {
320 // update current used repository
321 currSourceRepo = RepoUtils.getRepository(
322 repositoryFactory, keyring, (Node) newInput);
323 currSourceCred = RepoUtils.getRepositoryCredentials(
324 keyring, (Node) newInput);
325 // reset workspace list
326 wkspViewer.setAllChecked(false);
327 }
328 }
329
330 public void dispose() {
331 }
332
333 public Object[] getElements(Object obj) {
334 Session session = null;
335 try {
336 session = currSourceRepo.login(currSourceCred);
337 List<String> result = new ArrayList<String>();
338 // remove unvalid elements
339 for (String name : session.getWorkspace()
340 .getAccessibleWorkspaceNames())
341 if (name.lastIndexOf('-') > 0)
342 result.add(name);
343 return result.toArray();
344 } catch (RepositoryException e) {
345 throw new SlcException(
346 "Unexpected error while initializing fetch wizard",
347 e);
348 } finally {
349 JcrUtils.logoutQuietly(session);
350 }
351 }
352 });
353 wkspViewer.setComparator(new ArtifactNamesComparator());
354
355 }
356 }
357
358 /**
359 * Define the privileged job that will be run asynchronously to accomplish
360 * the sync
361 */
362 private class FetchJob extends PrivilegedJob {
363 private RepoSync repoSync;
364
365 public FetchJob(RepoSync repoSync) {
366 super("Fetch");
367 this.repoSync = repoSync;
368 }
369
370 @Override
371 protected IStatus doRun(IProgressMonitor progressMonitor) {
372 try {
373 ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor);
374 repoSync.setMonitor(monitor);
375 repoSync.run();
376 } catch (Exception e) {
377 return new Status(IStatus.ERROR, DistPlugin.ID,
378 "Cannot fetch repository", e);
379 }
380 return Status.OK_STATUS;
381 }
382 }
383
384 public void setTargetRepoNode(Node targetRepoNode) {
385 this.targetRepoNode = targetRepoNode;
386 }
387
388 public void setSourceRepoNode(Node sourceRepoNode) {
389 this.sourceRepoNode = sourceRepoNode;
390 }
391 }