1 package org
.argeo
.slc
.client
.ui
.dist
.wizards
;
3 import java
.util
.ArrayList
;
4 import java
.util
.HashMap
;
8 import javax
.jcr
.Credentials
;
10 import javax
.jcr
.NodeIterator
;
11 import javax
.jcr
.Repository
;
12 import javax
.jcr
.RepositoryException
;
13 import javax
.jcr
.RepositoryFactory
;
14 import javax
.jcr
.Session
;
16 import org
.argeo
.api
.NodeUtils
;
17 import org
.argeo
.api
.security
.Keyring
;
18 import org
.argeo
.cms
.ArgeoNames
;
19 import org
.argeo
.cms
.ArgeoTypes
;
20 import org
.argeo
.cms
.ui
.workbench
.util
.PrivilegedJob
;
21 import org
.argeo
.eclipse
.ui
.EclipseJcrMonitor
;
22 import org
.argeo
.jcr
.JcrMonitor
;
23 import org
.argeo
.jcr
.JcrUtils
;
24 import org
.argeo
.slc
.SlcException
;
25 import org
.argeo
.slc
.client
.ui
.dist
.DistPlugin
;
26 import org
.argeo
.slc
.client
.ui
.dist
.utils
.ViewerUtils
;
27 import org
.argeo
.slc
.repo
.RepoConstants
;
28 import org
.argeo
.slc
.repo
.RepoSync
;
29 import org
.argeo
.slc
.repo
.RepoUtils
;
30 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
31 import org
.eclipse
.core
.runtime
.IStatus
;
32 import org
.eclipse
.core
.runtime
.Status
;
33 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
34 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
35 import org
.eclipse
.jface
.viewers
.CheckboxTableViewer
;
36 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
37 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
38 import org
.eclipse
.jface
.viewers
.IStructuredContentProvider
;
39 import org
.eclipse
.jface
.viewers
.TableViewer
;
40 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
41 import org
.eclipse
.jface
.viewers
.Viewer
;
42 import org
.eclipse
.jface
.viewers
.ViewerComparator
;
43 import org
.eclipse
.jface
.wizard
.IWizardPage
;
44 import org
.eclipse
.jface
.wizard
.Wizard
;
45 import org
.eclipse
.jface
.wizard
.WizardPage
;
46 import org
.eclipse
.swt
.SWT
;
47 import org
.eclipse
.swt
.events
.ModifyEvent
;
48 import org
.eclipse
.swt
.events
.ModifyListener
;
49 import org
.eclipse
.swt
.events
.SelectionAdapter
;
50 import org
.eclipse
.swt
.events
.SelectionEvent
;
51 import org
.eclipse
.swt
.layout
.GridData
;
52 import org
.eclipse
.swt
.layout
.GridLayout
;
53 import org
.eclipse
.swt
.widgets
.Button
;
54 import org
.eclipse
.swt
.widgets
.Combo
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Label
;
57 import org
.eclipse
.swt
.widgets
.Table
;
58 import org
.eclipse
.swt
.widgets
.Text
;
61 * Defines parameters for the fetch process and run it using a {@link RepoSync}
64 public class FetchWizard
extends Wizard
{
65 // private final static Log log = LogFactory.getLog(FetchWizard.class);
68 private Keyring keyring
;
69 private RepositoryFactory repositoryFactory
;
70 private Session currSession
;
71 private Node targetRepoNode
, sourceRepoNode
;
73 private List
<WkspObject
> selectedWorkspaces
= new ArrayList
<WkspObject
>();
76 private ChooseWkspPage chooseWkspPage
;
77 private RecapPage recapPage
;
79 // Cache the advanced pages
80 private Map
<WkspObject
, AdvancedFetchPage
> advancedPages
= new HashMap
<FetchWizard
.WkspObject
, FetchWizard
.AdvancedFetchPage
>();
82 // Controls with parameters
83 private Button filesOnlyBtn
;
84 private Button advancedBtn
;
85 private CheckboxTableViewer wkspViewer
;
87 public FetchWizard(Keyring keyring
, RepositoryFactory repositoryFactory
,
88 Repository nodeRepository
) {
90 this.keyring
= keyring
;
91 this.repositoryFactory
= repositoryFactory
;
93 currSession
= nodeRepository
.login();
94 } catch (RepositoryException e
) {
95 throw new SlcException(
96 "Unexpected error while initializing fetch wizard", e
);
101 public void dispose() {
102 JcrUtils
.logoutQuietly(currSession
);
107 public void addPages() {
109 chooseWkspPage
= new ChooseWkspPage();
110 addPage(chooseWkspPage
);
111 recapPage
= new RecapPage();
113 setWindowTitle("Define Fetch Procedure");
114 } catch (Exception e
) {
115 throw new SlcException("Cannot add page to wizard ", e
);
120 public boolean performFinish() {
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
);
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
);
140 String msg
= "Your are about to fetch data from repository: \n\t"
141 + sourceRepoUri
+ "\ninto target repository: \n\t"
142 + targetRepoUri
+ "\nDo you really want to proceed ?";
144 boolean result
= MessageDialog
.openConfirm(DistPlugin
.getDefault()
145 .getWorkbench().getDisplay().getActiveShell(),
146 "Confirm Fetch Launch", msg
);
149 RepoSync repoSync
= new RepoSync(sourceRepo
, sourceCredentials
,
150 targetRepo
, targetCredentials
);
151 repoSync
.setTargetRepoUri(targetRepoUri
);
152 repoSync
.setSourceRepoUri(sourceRepoUri
);
154 // Specify workspaces to synchronise
155 Map
<String
, String
> wksps
= new HashMap
<String
, String
>();
156 for (Object obj
: wkspViewer
.getCheckedElements()) {
157 WkspObject stn
= (WkspObject
) obj
;
158 wksps
.put(stn
.srcName
, stn
.targetName
);
160 repoSync
.setWkspMap(wksps
);
162 // Set the import files only option
163 repoSync
.setFilesOnly(filesOnlyBtn
.getSelection());
164 FetchJob job
= new FetchJob(repoSync
);
168 } catch (Exception e
) {
169 throw new SlcException(
170 "Unexpected error while launching the fetch", e
);
175 // ///////////////////////////////
178 private class ChooseWkspPage
extends WizardPage
{
179 private static final long serialVersionUID
= 211336700788047638L;
181 private Map
<String
, Node
> sourceReposMap
;
182 private Combo chooseSourceRepoCmb
;
184 public ChooseWkspPage() {
186 setTitle("Choose workspaces to fetch");
187 setDescription("Check 'advanced fetch' box to "
188 + "rename workspaces and fine tune the process");
190 // Initialise with registered Repositories
191 sourceReposMap
= getSourceRepoUris();
194 public void createControl(Composite parent
) {
195 Composite composite
= new Composite(parent
, SWT
.NO_FOCUS
);
196 composite
.setLayout(new GridLayout(2, false));
198 // Choose source repository combo
199 new Label(composite
, SWT
.NONE
)
200 .setText("Choose a source repository");
201 chooseSourceRepoCmb
= new Combo(composite
, SWT
.BORDER
203 chooseSourceRepoCmb
.setItems(sourceReposMap
.keySet().toArray(
204 new String
[sourceReposMap
.size()]));
205 GridData gd
= new GridData(GridData
.FILL_HORIZONTAL
);
206 chooseSourceRepoCmb
.setLayoutData(gd
);
209 final Button selectAllBtn
= new Button(composite
, SWT
.CHECK
);
210 selectAllBtn
.setText("Select/Unselect all");
212 advancedBtn
= new Button(composite
, SWT
.CHECK
);
213 advancedBtn
.setText("Advanced fetch");
214 advancedBtn
.setToolTipText("Check this for further "
215 + "parameterization of the fetch process");
218 Table table
= new Table(composite
, SWT
.H_SCROLL
| SWT
.V_SCROLL
219 | SWT
.BORDER
| SWT
.CHECK
);
220 gd
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
221 gd
.horizontalSpan
= 2;
222 table
.setLayoutData(gd
);
223 configureWkspTable(table
);
226 filesOnlyBtn
= new Button(composite
, SWT
.CHECK
| SWT
.WRAP
);
228 .setText("Import only files (faster, a normalized action should be launched once done)");
229 filesOnlyBtn
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false,
233 selectAllBtn
.addSelectionListener(new SelectionAdapter() {
234 private static final long serialVersionUID
= -2071840477444152170L;
236 public void widgetSelected(SelectionEvent e
) {
237 wkspViewer
.setAllChecked(selectAllBtn
.getSelection());
238 getContainer().updateButtons();
242 // advancedBtn.addSelectionListener(new SelectionAdapter() {
243 // public void widgetSelected(SelectionEvent e) {
244 // if (advancedBtn.getSelection()){
247 // wkspViewer.setAllChecked();
251 chooseSourceRepoCmb
.addModifyListener(new ModifyListener() {
252 private static final long serialVersionUID
= 932462568382594523L;
254 public void modifyText(ModifyEvent e
) {
255 String chosenUri
= chooseSourceRepoCmb
256 .getItem(chooseSourceRepoCmb
.getSelectionIndex());
257 sourceRepoNode
= sourceReposMap
.get(chosenUri
);
258 wkspViewer
.setInput(sourceRepoNode
);
262 wkspViewer
.addCheckStateListener(new ICheckStateListener() {
263 public void checkStateChanged(CheckStateChangedEvent event
) {
264 getContainer().updateButtons();
268 // Initialise to first available repo
269 if (chooseSourceRepoCmb
.getItemCount() > 0)
270 chooseSourceRepoCmb
.select(0);
273 setControl(composite
);
277 public boolean isPageComplete() {
278 return wkspViewer
.getCheckedElements().length
!= 0;
282 public IWizardPage
getNextPage() {
283 // WARNING: page are added and never removed.
284 if (advancedBtn
.getSelection()
285 && wkspViewer
.getCheckedElements().length
!= 0) {
286 IWizardPage toReturn
= null;
287 for (Object obj
: wkspViewer
.getCheckedElements()) {
288 WkspObject curr
= (WkspObject
) obj
;
289 // currSelecteds.add(curr);
290 AdvancedFetchPage page
;
291 if (!advancedPages
.containsKey(curr
)) {
292 page
= new AdvancedFetchPage(curr
.srcName
, curr
);
294 advancedPages
.put(curr
, page
);
296 page
= advancedPages
.get(curr
);
297 if (toReturn
== null)
306 // Configure the workspace table
307 private void configureWkspTable(Table table
) {
308 table
.setLinesVisible(true);
309 table
.setHeaderVisible(true);
310 wkspViewer
= new CheckboxTableViewer(table
);
313 TableViewerColumn column
= ViewerUtils
.createTableViewerColumn(
314 wkspViewer
, "Source names", SWT
.NONE
, 250);
315 column
.setLabelProvider(new ColumnLabelProvider() {
316 private static final long serialVersionUID
= 5906079281065061967L;
319 public String
getText(Object element
) {
320 return ((WkspObject
) element
).srcName
;
324 // column = ViewerUtils.createTableViewerColumn(wkspViewer, "Size",
326 // column.setLabelProvider(new ColumnLabelProvider() {
328 // public String getText(Object element) {
329 // return ((WkspObject) element).getFormattedSize();
333 wkspViewer
.setContentProvider(new WkspContentProvider());
334 // A basic comparator
335 wkspViewer
.setComparator(new ViewerComparator());
339 private class AdvancedFetchPage
extends WizardPage
{
340 private static final long serialVersionUID
= 1109183561920445169L;
342 private final WkspObject currentWorkspace
;
344 private Text targetNameTxt
;
346 protected AdvancedFetchPage(String pageName
, WkspObject currentWorkspace
) {
348 this.currentWorkspace
= currentWorkspace
;
352 public void setVisible(boolean visible
) {
353 super.setVisible(visible
);
355 String msg
= "Define advanced parameters to fetch workspace "
356 + currentWorkspace
.srcName
;
358 targetNameTxt
.setText(currentWorkspace
.targetName
);
361 // currentWorkspace.targetName = targetNameTxt.getText();
364 public void createControl(Composite parent
) {
365 Composite body
= new Composite(parent
, SWT
.NO_FOCUS
);
366 body
.setLayout(new GridLayout(2, false));
367 new Label(body
, SWT
.NONE
).setText("Choose a new name");
368 targetNameTxt
= new Text(body
, SWT
.BORDER
);
369 targetNameTxt
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
,
374 protected WkspObject
getWorkspaceObject() {
375 currentWorkspace
.targetName
= targetNameTxt
.getText();
376 return currentWorkspace
;
380 public IWizardPage
getNextPage() {
381 // WARNING: page are added and never removed.
382 // IWizardPage toReturn = null;
383 // IWizardPage[] pages = ((Wizard) getContainer()).getPages();
384 Object
[] selected
= wkspViewer
.getCheckedElements();
385 for (int i
= 0; i
< selected
.length
- 1; i
++) {
386 WkspObject curr
= (WkspObject
) selected
[i
];
387 if (curr
.equals(currentWorkspace
))
388 return advancedPages
.get((WkspObject
) selected
[i
+ 1]);
394 private class RecapPage
extends WizardPage
{
395 private static final long serialVersionUID
= -7064862323304300989L;
396 private TableViewer recapViewer
;
399 super("Validate and launch");
400 setTitle("Validate and launch");
404 public boolean isPageComplete() {
405 return isCurrentPage();
408 public IWizardPage
getNextPage() {
414 public void setVisible(boolean visible
) {
415 super.setVisible(visible
);
418 String targetRepoUri
= targetRepoNode
.getProperty(
419 ArgeoNames
.ARGEO_URI
).getString();
420 String sourceRepoUri
= sourceRepoNode
.getProperty(
421 ArgeoNames
.ARGEO_URI
).getString();
423 String msg
= "Fetch data from: " + sourceRepoUri
424 + "\ninto target repository: " + targetRepoUri
;
425 // + "\nDo you really want to proceed ?";
428 // update values that will be used for the fetch
429 selectedWorkspaces
.clear();
431 for (Object obj
: wkspViewer
.getCheckedElements()) {
432 WkspObject curr
= (WkspObject
) obj
;
434 if (advancedBtn
.getSelection()) {
435 AdvancedFetchPage page
= advancedPages
.get(curr
);
436 selectedWorkspaces
.add(page
.getWorkspaceObject());
438 selectedWorkspaces
.add(curr
);
440 recapViewer
.setInput(selectedWorkspaces
);
441 recapViewer
.refresh();
443 } catch (RepositoryException re
) {
444 throw new SlcException("Unable to get repositories URIs",
450 public void createControl(Composite parent
) {
451 Table table
= new Table(parent
, SWT
.H_SCROLL
| SWT
.V_SCROLL
453 table
.setLinesVisible(true);
454 table
.setHeaderVisible(true);
455 recapViewer
= new TableViewer(table
);
458 TableViewerColumn column
= ViewerUtils
.createTableViewerColumn(
459 recapViewer
, "Sources", SWT
.NONE
, 250);
460 column
.setLabelProvider(new ColumnLabelProvider() {
461 private static final long serialVersionUID
= 3913459002502680377L;
464 public String
getText(Object element
) {
465 return ((WkspObject
) element
).srcName
;
469 column
= ViewerUtils
.createTableViewerColumn(recapViewer
,
470 "targets", SWT
.NONE
, 250);
471 column
.setLabelProvider(new ColumnLabelProvider() {
472 private static final long serialVersionUID
= -517920072332563632L;
475 public String
getText(Object element
) {
476 return ((WkspObject
) element
).targetName
;
480 recapViewer
.setContentProvider(new IStructuredContentProvider() {
481 private static final long serialVersionUID
= 4926999891003040865L;
483 public void inputChanged(Viewer viewer
, Object oldInput
,
485 // TODO Auto-generated method stub
488 public void dispose() {
491 public Object
[] getElements(Object inputElement
) {
492 return selectedWorkspaces
.toArray();
496 // A basic comparator
497 recapViewer
.setComparator(new ViewerComparator());
503 * Define the privileged job that will be run asynchronously to accomplish
506 private class FetchJob
extends PrivilegedJob
{
507 private RepoSync repoSync
;
509 public FetchJob(RepoSync repoSync
) {
511 this.repoSync
= repoSync
;
515 protected IStatus
doRun(IProgressMonitor progressMonitor
) {
517 JcrMonitor monitor
= new EclipseJcrMonitor(progressMonitor
);
518 repoSync
.setMonitor(monitor
);
520 } catch (Exception e
) {
521 return new Status(IStatus
.ERROR
, DistPlugin
.PLUGIN_ID
,
522 "Cannot fetch repository", e
);
524 return Status
.OK_STATUS
;
528 // ///////////////////////
530 private class WkspObject
{
531 protected final String srcName
;
532 protected String targetName
;
534 protected WkspObject(String srcName
) {
535 this.srcName
= srcName
;
536 this.targetName
= srcName
;
540 public String
toString() {
541 return "[" + srcName
+ " to " + targetName
+ "]";
545 // private class WkspComparator extends ViewerComparator {
549 private class WkspContentProvider
implements IStructuredContentProvider
{
550 private static final long serialVersionUID
= -925058051598536307L;
551 // caches current repo
552 private Node currSourceNodeRepo
;
553 private Repository currSourceRepo
;
554 private Credentials currSourceCred
;
556 private List
<WkspObject
> workspaces
= new ArrayList
<WkspObject
>();
558 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
559 if (newInput
!= null && newInput
instanceof Node
) {
560 Session session
= null;
562 Node newRepoNode
= (Node
) newInput
;
563 if (currSourceNodeRepo
== null
564 || !newRepoNode
.getPath().equals(
565 currSourceNodeRepo
.getPath())) {
568 currSourceNodeRepo
= newRepoNode
;
569 currSourceRepo
= RepoUtils
.getRepository(
570 repositoryFactory
, keyring
, currSourceNodeRepo
);
571 currSourceCred
= RepoUtils
.getRepositoryCredentials(
572 keyring
, currSourceNodeRepo
);
574 // reset workspace list
575 wkspViewer
.setAllChecked(false);
577 // FIXME make it more generic
578 session
= currSourceRepo
.login(currSourceCred
,RepoConstants
.DEFAULT_DEFAULT_WORKSPACE
);
579 // remove unvalid elements
580 for (String name
: session
.getWorkspace()
581 .getAccessibleWorkspaceNames())
582 // TODO implement a cleaner way to filter
584 if (name
.lastIndexOf('-') > 0) {
585 WkspObject currWksp
= new WkspObject(name
);
586 // compute wkspace size
587 // TODO implement this
588 // Session currSession = null;
590 // currSession = currSourceRepo.login(
591 // currSourceCred, name);
592 // currWksp.size = JcrUtils
593 // .getNodeApproxSize(currSession
596 // } catch (RepositoryException re) {
598 // "unable to compute size of workspace "
601 // JcrUtils.logoutQuietly(currSession);
603 workspaces
.add(currWksp
);
607 } catch (RepositoryException e
) {
608 throw new SlcException("Unexpected error while "
609 + "initializing fetch wizard", e
);
611 JcrUtils
.logoutQuietly(session
);
617 public void dispose() {
620 public Object
[] getElements(Object obj
) {
621 return workspaces
.toArray();
625 // ////////////////////////////
628 // populate available source repo list
629 private Map
<String
, Node
> getSourceRepoUris() {
631 Node repoList
= currSession
.getNode(NodeUtils
.getUserHome(
632 currSession
).getPath()
633 + RepoConstants
.REPOSITORIES_BASE_PATH
);
635 String targetRepoUri
= null;
636 if (targetRepoNode
!= null) {
637 targetRepoUri
= targetRepoNode
638 .getProperty(ArgeoNames
.ARGEO_URI
).getString();
640 NodeIterator ni
= repoList
.getNodes();
641 // List<String> sourceRepoNames = new ArrayList<String>();
642 // // caches a map of the source repo nodes with their URI as a key
643 // // to ease further processing
644 Map
<String
, Node
> sourceReposMap
= new HashMap
<String
, Node
>();
645 while (ni
.hasNext()) {
646 Node currNode
= ni
.nextNode();
647 if (currNode
.isNodeType(ArgeoTypes
.ARGEO_REMOTE_REPOSITORY
)) {
648 String currUri
= currNode
.getProperty(ArgeoNames
.ARGEO_URI
)
650 if (targetRepoUri
== null || !targetRepoUri
.equals(currUri
)) {
651 sourceReposMap
.put(currUri
, currNode
);
652 // sourceRepoNames.add(currUri);
656 return sourceReposMap
;
657 // sourceRepoNames.toArray(new String[sourceRepoNames
659 } catch (RepositoryException e
) {
660 throw new SlcException("Error while getting repo aliases", e
);
664 public void setTargetRepoNode(Node targetRepoNode
) {
665 this.targetRepoNode
= targetRepoNode
;
668 public void setSourceRepoNode(Node sourceRepoNode
) {
669 this.sourceRepoNode
= sourceRepoNode
;