2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.client
.ui
.dist
.wizards
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
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
;
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
;
71 * Defines parameters for the fetch process and run it using a {@link RepoSync}
74 public class FetchWizard
extends Wizard
{
76 // private final static Log log = LogFactory.getLog(FetchWizard.class);
79 private Keyring keyring
;
80 private RepositoryFactory repositoryFactory
;
81 private Session currSession
;
82 private Node targetRepoNode
, sourceRepoNode
;
85 private DefineModelPage page
;
86 private CheckboxTableViewer wkspViewer
;
87 private Button filesOnlyBtn
;
89 public FetchWizard(Keyring keyring
, RepositoryFactory repositoryFactory
,
90 Repository nodeRepository
) {
92 this.keyring
= keyring
;
93 this.repositoryFactory
= repositoryFactory
;
95 currSession
= nodeRepository
.login();
96 } catch (RepositoryException e
) {
97 throw new SlcException(
98 "Unexpected error while initializing fetch wizard", e
);
103 public void dispose() {
105 JcrUtils
.logoutQuietly(currSession
);
109 public void addPages() {
111 page
= new DefineModelPage();
113 setWindowTitle("Fetch...");
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
);
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(),
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 ?";
155 boolean result
= MessageDialog
.openConfirm(DistPlugin
.getDefault()
156 .getWorkbench().getDisplay().getActiveShell(),
157 "Confirm Fetch clear", msg
);
160 RepoSync repoSync
= new RepoSync(sourceRepo
, sourceCredentials
,
161 targetRepo
, targetCredentials
);
162 repoSync
.setTargetRepoUri(targetRepoUri
);
163 repoSync
.setSourceRepoUri(sourceRepoUri
);
165 // Specify workspaces to synchronise
166 List
<String
> wksps
= new ArrayList
<String
>();
167 for (Object obj
: wkspViewer
.getCheckedElements()) {
168 wksps
.add((String
) obj
);
170 repoSync
.setSourceWkspList(wksps
);
172 // Set the import files only option
173 repoSync
.setFilesOnly(filesOnlyBtn
.getSelection());
175 FetchJob job
= new FetchJob(repoSync
);
180 } catch (Exception e
) {
181 throw new SlcException(
182 "Unexpected error while launching the fetch", e
);
187 private class DefineModelPage
extends WizardPage
{
190 private Combo chooseSourceRepoCmb
;
193 private Map
<String
, Node
> sourceReposMap
;
195 public DefineModelPage() {
197 setTitle("Define fetch parameters");
200 public void createControl(Composite parent
) {
203 Composite composite
= new Composite(parent
, SWT
.NONE
);
204 composite
.setLayout(new GridLayout(2, false));
206 // Choose source repo
207 new Label(composite
, SWT
.NONE
)
208 .setText("Choose a source repository");
209 chooseSourceRepoCmb
= new Combo(composite
, SWT
.BORDER
211 chooseSourceRepoCmb
.setItems(getSourceRepoUris());
212 GridData gd
= new GridData(GridData
.FILL_HORIZONTAL
);
213 chooseSourceRepoCmb
.setLayoutData(gd
);
216 filesOnlyBtn
= new Button(composite
, SWT
.CHECK
| SWT
.WRAP
);
218 .setText("Import only files (faster, a normalized action should be launched once done)");
219 filesOnlyBtn
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false,
223 Composite wkspTable
= new Composite(composite
, SWT
.NONE
);
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
);
232 // Choose source repo
233 final Button selectAllBtn
= new Button(composite
, SWT
.CHECK
);
234 selectAllBtn
.setText("Select/Unselect all");
236 selectAllBtn
.addSelectionListener(new SelectionListener() {
237 public void widgetSelected(SelectionEvent e
) {
238 wkspViewer
.setAllChecked(selectAllBtn
.getSelection());
241 public void widgetDefaultSelected(SelectionEvent e
) {
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
);
254 // initialize to first avalaible repo
255 if (chooseSourceRepoCmb
.getItemCount() > 0)
256 chooseSourceRepoCmb
.select(0);
258 setControl(composite
);
261 // Helper to populate avalaible source repo list
262 protected String
[] getSourceRepoUris() {
264 Node repoList
= currSession
.getNode(UserJcrUtils
.getUserHome(
265 currSession
).getPath()
266 + RepoConstants
.REPOSITORIES_BASE_PATH
);
268 String targetRepoUri
= null;
269 if (targetRepoNode
!= null) {
270 targetRepoUri
= targetRepoNode
.getProperty(
271 ArgeoNames
.ARGEO_URI
).getString();
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
);
290 return sourceRepoNames
.toArray(new String
[sourceRepoNames
292 } catch (RepositoryException e
) {
293 throw new SlcException("Error while getting repo aliases", e
);
297 // Create the workspaces table
298 private void addWkspTablePart(Composite parent
) {
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
);
308 TableViewerColumn column
= ViewerUtils
.createTableViewerColumn(
309 wkspViewer
, "Workspaces", SWT
.NONE
, 400);
310 column
.setLabelProvider(new ColumnLabelProvider());
312 wkspViewer
.setContentProvider(new IStructuredContentProvider() {
313 // caches current repo
314 private Repository currSourceRepo
;
315 private Credentials currSourceCred
;
317 public void inputChanged(Viewer viewer
, Object oldInput
,
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);
330 public void dispose() {
333 public Object
[] getElements(Object obj
) {
334 Session session
= null;
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)
343 return result
.toArray();
344 } catch (RepositoryException e
) {
345 throw new SlcException(
346 "Unexpected error while initializing fetch wizard",
349 JcrUtils
.logoutQuietly(session
);
353 wkspViewer
.setComparator(new ArtifactNamesComparator());
359 * Define the privileged job that will be run asynchronously to accomplish
362 private class FetchJob
extends PrivilegedJob
{
363 private RepoSync repoSync
;
365 public FetchJob(RepoSync repoSync
) {
367 this.repoSync
= repoSync
;
371 protected IStatus
doRun(IProgressMonitor progressMonitor
) {
373 ArgeoMonitor monitor
= new EclipseArgeoMonitor(progressMonitor
);
374 repoSync
.setMonitor(monitor
);
376 } catch (Exception e
) {
377 return new Status(IStatus
.ERROR
, DistPlugin
.ID
,
378 "Cannot fetch repository", e
);
380 return Status
.OK_STATUS
;
384 public void setTargetRepoNode(Node targetRepoNode
) {
385 this.targetRepoNode
= targetRepoNode
;
388 public void setSourceRepoNode(Node sourceRepoNode
) {
389 this.sourceRepoNode
= sourceRepoNode
;