From 706b98df2c68382d7bd501fa05cb128f329087ee Mon Sep 17 00:00:00 2001 From: Bruno Sinou Date: Fri, 28 Feb 2014 20:28:45 +0000 Subject: [PATCH] Full refactoring of the UI distribution view: + introduce group base in the tree viewer + prepare the use of listener for refresh + remove hard links between the various UI parts + clean the UI object model git-svn-id: https://svn.argeo.org/slc/trunk@6861 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../META-INF/spring/commands.xml | 102 ++++--- .../META-INF/spring/editors.xml | 8 + .../org.argeo.slc.client.ui.dist/plugin.xml | 255 +++++++++-------- .../argeo/slc/client/ui/dist/DistImages.java | 3 + .../ui/dist/DistributionPerspective.java | 4 +- .../dist/commands/DisplayRepoInformation.java | 55 ++-- .../ui/dist/commands/OpenWorkspaceEditor.java | 99 +++++++ .../AnonymousDistTreeContentProvider.java | 22 +- .../dist/controllers/DistTreeComparator.java | 6 +- .../ui/dist/controllers/DistTreeComparer.java | 28 ++ .../controllers/DistTreeContentProvider.java | 44 +-- .../DistTreeDoubleClickListener.java | 69 +++-- .../controllers/DistTreeLabelProvider.java | 44 +-- .../editors/DistributionOverviewPage.java | 20 +- .../editors/DistributionWorkspaceEditor.java | 127 +++++++++ .../ui/dist/editors/GroupBaseEditorInput.java | 65 +++++ .../ui/dist/editors/WorkspaceEditorInput.java | 120 ++++++++ .../client/ui/dist/model/DistParentElem.java | 48 +++- .../client/ui/dist/model/GroupBaseElem.java | 24 +- .../slc/client/ui/dist/model/RepoElem.java | 256 +++++++++++------- .../client/ui/dist/model/WkspGroupElem.java | 143 +++++----- .../client/ui/dist/model/WorkspaceElem.java | 91 +++++-- .../views/AnonymousDistributionsView.java | 2 +- .../ui/dist/views/DistributionsView.java | 60 ++-- .../ui/dist/wizards/RegisterRepoWizard.java | 4 +- .../java/org/argeo/slc/repo/RepoUtils.java | 38 ++- 26 files changed, 1252 insertions(+), 485 deletions(-) create mode 100644 plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/commands/OpenWorkspaceEditor.java create mode 100644 plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeComparer.java create mode 100644 plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionWorkspaceEditor.java create mode 100644 plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/GroupBaseEditorInput.java create mode 100644 plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/WorkspaceEditorInput.java diff --git a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/commands.xml b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/commands.xml index 92a326ed2..858d11fbb 100644 --- a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/commands.xml +++ b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/commands.xml @@ -4,50 +4,63 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - - - - - - - + + + + + - + + + - - + + - + + - + + + - + - + + + + + + + @@ -59,36 +72,51 @@ + + + - - - - + + + + - - - - + + + + - - - - + + + + + + + + + \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/editors.xml b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/editors.xml index 069bb1559..36f95dcb9 100644 --- a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/editors.xml +++ b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/editors.xml @@ -9,4 +9,12 @@ class="org.argeo.eclipse.ui.jcr.editors.GenericJcrQueryEditor" scope="prototype"> + + + + + + diff --git a/plugins/org.argeo.slc.client.ui.dist/plugin.xml b/plugins/org.argeo.slc.client.ui.dist/plugin.xml index 79c7950e0..21337e840 100644 --- a/plugins/org.argeo.slc.client.ui.dist/plugin.xml +++ b/plugins/org.argeo.slc.client.ui.dist/plugin.xml @@ -1,9 +1,9 @@ - - + + - + - + - - + - - + - - + - - + - - + - - + + - - + - - - - - - - - - - + + + + + + + + + + + + + - + + + id="org.argeo.slc.client.ui.dist.normalizeDistribution" + defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler" + name="Normalize Distribution"> + + + + + + - - - - - - - + id="org.argeo.slc.client.ui.dist.registerRepository" + defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler" + name="Add Repository"> - - - @@ -127,20 +131,29 @@ - - + id="org.argeo.slc.client.ui.dist.displayRepoInformation" + name="Display repository information"> + + + name="Open Workspace Editor"> + + + + + + - - - - - - - - - - - + name="Normalize Workspace"> @@ -180,22 +177,19 @@ - - - - + name="Manage workspace authorizations"> + + + + name="Publish selected workspace"> @@ -206,10 +200,24 @@ - + + name="Create Workspace"> + + + + + + @@ -233,6 +241,7 @@ name="Target repo node path"> + + + + + + + + + + + + + + name="Run in OSGi"> + + + repositories = new ArrayList(); + /* DEPENDENCY INJECTION */ private RepositoryFactory repositoryFactory; private Keyring keyring; @@ -53,9 +53,13 @@ public class DistTreeContentProvider implements ITreeContentProvider { NodeIterator repos = nodeSession.getNode(reposPath).getNodes(); while (repos.hasNext()) { Node repoNode = repos.nextNode(); - if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) - repositories.add(new RepoElem(repoNode, repositoryFactory, - keyring)); + if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) { + String label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode + .getProperty(Property.JCR_TITLE).getString() + : repoNode.getName(); + repositories.add(new RepoElem(repositoryFactory, keyring, + repoNode, label)); + } } } catch (RepositoryException e) { throw new SlcException("Cannot get base elements", e); @@ -66,25 +70,25 @@ public class DistTreeContentProvider implements ITreeContentProvider { public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } + // @Override public Object[] getChildren(Object parentElement) { - if (parentElement instanceof DistParentElem) { - return ((DistParentElem) parentElement).getChildren(); - } else if (parentElement instanceof WorkspaceElem) { - return ((WorkspaceElem) parentElement).getChildren(); - } - return null; + if (parentElement instanceof TreeParent) + return ((TreeParent) parentElement).getChildren(); + else + return null; } + // @Override public Object getParent(Object element) { - // TODO register repo elem in distribution elem? + if (element instanceof TreeParent) + return ((TreeParent) element).getParent(); return null; } + // @Override public boolean hasChildren(Object element) { - if (element instanceof WorkspaceElem) - return false; - else if (element instanceof DistParentElem) - return true; + if (element instanceof TreeParent) + return ((TreeParent) element).hasChildren(); else return false; } @@ -128,9 +132,7 @@ public class DistTreeContentProvider implements ITreeContentProvider { } } - /* - * DEPENDENCY INJECTION - */ + /* DEPENDENCY INJECTION */ public void setRepositoryFactory(RepositoryFactory repositoryFactory) { this.repositoryFactory = repositoryFactory; } diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java index bfa976658..6e8d53734 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java @@ -1,37 +1,70 @@ package org.argeo.slc.client.ui.dist.controllers; -import org.argeo.eclipse.ui.ErrorFeedback; -import org.argeo.slc.client.ui.dist.DistPlugin; -import org.argeo.slc.client.ui.dist.editors.DistributionEditor; -import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput; +import java.util.HashMap; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.eclipse.ui.utils.CommandUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.client.ui.dist.commands.OpenWorkspaceEditor; +import org.argeo.slc.client.ui.dist.model.RepoElem; import org.argeo.slc.client.ui.dist.model.WorkspaceElem; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.ui.PartInitException; +import org.eclipse.jface.viewers.TreeViewer; /** Listen to double-clicks on the distributions view tree. */ public class DistTreeDoubleClickListener implements IDoubleClickListener { + private TreeViewer treeViewer; + + public DistTreeDoubleClickListener(TreeViewer treeViewer) { + this.treeViewer = treeViewer; + } + public void doubleClick(DoubleClickEvent event) { if (event.getSelection() == null || event.getSelection().isEmpty()) return; Object obj = ((IStructuredSelection) event.getSelection()) .getFirstElement(); - if (obj instanceof WorkspaceElem) { - WorkspaceElem we = (WorkspaceElem) obj; - DistributionEditorInput dei = new DistributionEditorInput(we - .getRepoElem().getRepository(), we.getRepoElem() - .getCredentials(), we.getRepoElem().getLabel(), we - .getRepoElem().getDescription(), we.getWorkspaceName()); - try { - DistPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getActivePage() - .openEditor(dei, DistributionEditor.ID); - } catch (PartInitException e) { - ErrorFeedback.show( - "Cannot open editor for " + we.getWorkspaceName(), e); + + if (obj instanceof RepoElem) { + RepoElem rpNode = (RepoElem) obj; + if (!rpNode.isConnected()) { + rpNode.login(); + treeViewer.refresh(obj); + } + } else if (obj instanceof WorkspaceElem) { + WorkspaceElem wn = (WorkspaceElem) obj; + if (!wn.isConnected()) + wn.login(); + else { + WorkspaceElem we = (WorkspaceElem) obj; + + try { + RepoElem repoElem = we.getRepoElem(); + Map params = new HashMap(); + + Node repoNode = repoElem.getRepoNode(); + if (repoNode != null) + params.put(OpenWorkspaceEditor.PARAM_REPO_NODE_PATH, + repoNode.getPath()); + params.put(OpenWorkspaceEditor.PARAM_REPO_URI, + repoElem.getUri()); + params.put(OpenWorkspaceEditor.PARAM_WORKSPACE_NAME, + we.getWorkspaceName()); + CommandUtils.callCommand(OpenWorkspaceEditor.ID, params); + } catch (RepositoryException re) { + throw new SlcException( + "Cannot get path for node while " + + "setting parameters of command OpenWorkspaceEditor", + re); + } } + treeViewer.refresh(obj); } } } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeLabelProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeLabelProvider.java index b504ae6f3..b2ca9f290 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeLabelProvider.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeLabelProvider.java @@ -1,44 +1,46 @@ package org.argeo.slc.client.ui.dist.controllers; +import org.argeo.eclipse.ui.jcr.JcrImages; import org.argeo.slc.client.ui.dist.DistImages; import org.argeo.slc.client.ui.dist.model.DistParentElem; -import org.argeo.slc.client.ui.dist.model.WkspGroupElem; +import org.argeo.slc.client.ui.dist.model.GroupBaseElem; import org.argeo.slc.client.ui.dist.model.RepoElem; +import org.argeo.slc.client.ui.dist.model.WkspGroupElem; import org.argeo.slc.client.ui.dist.model.WorkspaceElem; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.swt.graphics.Image; /** - * Manages icons and labels for the distributions browser + * Manages icons and labels for the Distributions tree browser */ public class DistTreeLabelProvider extends ColumnLabelProvider { @Override public String getText(Object element) { if (element instanceof DistParentElem) - return ((DistParentElem) element).getLabel(); + return ((DistParentElem) element).getName(); else return element.toString(); } @Override public Image getImage(Object element) { - if (element instanceof DistParentElem) { - DistParentElem bElement = (DistParentElem) element; - if (bElement instanceof RepoElem) - if (bElement.inHome()) - return DistImages.IMG_HOME_REPO; - else if (bElement.isReadOnly()) - return DistImages.IMG_REPO_READONLY; - else - return DistImages.IMG_REPO; - else if (bElement instanceof WkspGroupElem) - return DistImages.IMG_WKSP; - else if (element instanceof WorkspaceElem) - if (((WorkspaceElem) element).isReadOnly()) - return DistImages.IMG_DISTGRP_READONLY; - else - return DistImages.IMG_DISTGRP; - } - return null; + if (element instanceof RepoElem) { + RepoElem re = ((RepoElem) element); + if (re.inHome()) + return DistImages.IMG_HOME_REPO; + else if (re.isConnected()) + return JcrImages.REPOSITORY_CONNECTED; + else + return JcrImages.REPOSITORY_DISCONNECTED; + } else if (element instanceof WorkspaceElem) { + if (((WorkspaceElem) element).isConnected()) + return JcrImages.WORKSPACE_CONNECTED; + else + return JcrImages.WORKSPACE_DISCONNECTED; + } else if (element instanceof WkspGroupElem) + return JcrImages.WORKSPACE_CONNECTED; + else if (element instanceof GroupBaseElem) + return DistImages.IMG_GROUP_BASE; + return super.getImage(element); } } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java index 1499bd5b7..edd848fe9 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java @@ -20,9 +20,11 @@ import java.util.List; import javax.jcr.Node; import javax.jcr.NodeIterator; +import javax.jcr.Property; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; import javax.jcr.query.QueryManager; import javax.jcr.query.QueryResult; import javax.jcr.query.qom.Constraint; @@ -247,8 +249,22 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { header.setLayoutData(gd); // Title: some meta information - String desc = ((DistributionEditorInput) getEditorInput()) - .getRepositoryDescription(); + // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode + // .getProperty(Property.JCR_TITLE).getString() : repoNode + // .getName(); + + String desc = null; + Node repoNode = ((DistributionWorkspaceEditor) getEditor()) + .getRepoNode(); + if (repoNode != null) + try { + desc = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode + .getProperty(Property.JCR_TITLE).getString() : repoNode + .getName(); + } catch (RepositoryException e1) { + throw new SlcException("Unable to get repository alias ", e1); + } + desc += " (" + ((WorkspaceEditorInput) getEditorInput()).getUri() + ")"; Label lbl = tk.createLabel(header, desc, SWT.NONE); gd = new GridData(SWT.FILL, SWT.FILL, false, false); diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionWorkspaceEditor.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionWorkspaceEditor.java new file mode 100644 index 000000000..723bb4dd3 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionWorkspaceEditor.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.slc.client.ui.dist.editors; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.RepositoryFactory; +import javax.jcr.Session; + +import org.argeo.ArgeoException; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.client.ui.dist.DistPlugin; +import org.argeo.slc.jcr.SlcNames; +import org.argeo.slc.repo.RepoUtils; +import org.argeo.util.security.Keyring; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.editor.FormEditor; + +/** + * Browse, analyse and modify a workspace containing software distributions + */ +public class DistributionWorkspaceEditor extends FormEditor implements SlcNames { + // private final static Log log = + // LogFactory.getLog(DistributionEditor.class); + public final static String ID = DistPlugin.ID + + ".distributionWorkspaceEditor"; + + /* DEPENDENCY INJECTION */ + private RepositoryFactory repositoryFactory; + private Repository localRepository; + private Keyring keyring; + + // Business objects + private Node repoNode; + // Session that provides the node in the home of the local repository + private Session localSession = null; + // The business Session on optionally remote repository + private Session businessSession; + private WorkspaceEditorInput editorInput; + + @Override + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + editorInput = (WorkspaceEditorInput) input; + + try { + localSession = localRepository.login(); + if (editorInput.getRepoNodePath() != null + && localSession.nodeExists(editorInput.getRepoNodePath())) + repoNode = localSession.getNode(editorInput.getRepoNodePath()); + + businessSession = RepoUtils.getCorrespondingSession( + repositoryFactory, keyring, repoNode, editorInput.getUri(), + editorInput.getWorkspaceName()); + } catch (RepositoryException e) { + throw new PartInitException("Cannot log to workspace " + + editorInput.getName(), e); + } + setPartName(editorInput.getWorkspaceName()); + super.init(site, input); + } + + @Override + protected void addPages() { + try { + addPage(new DistributionOverviewPage(this, "Overview", + businessSession)); + addPage(new ArtifactsBrowserPage(this, "Browser", businessSession)); + } catch (PartInitException e) { + throw new ArgeoException("Cannot add distribution editor pages", e); + } + } + + @Override + public void doSave(IProgressMonitor arg0) { + } + + @Override + public void dispose() { + JcrUtils.logoutQuietly(businessSession); + JcrUtils.logoutQuietly(localSession); + super.dispose(); + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + protected Node getRepoNode() { + return repoNode; + } + + /* DEPENDENCY INJECTION */ + public void setRepositoryFactory(RepositoryFactory repositoryFactory) { + this.repositoryFactory = repositoryFactory; + } + + public void setKeyring(Keyring keyring) { + this.keyring = keyring; + } + + public void setLocalRepository(Repository localRepository) { + this.localRepository = localRepository; + } +} \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/GroupBaseEditorInput.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/GroupBaseEditorInput.java new file mode 100644 index 000000000..bd9c788dc --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/GroupBaseEditorInput.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.slc.client.ui.dist.editors; + +import org.argeo.slc.SlcException; + +/** + * An editor input pointing to a given group base in a distribution workspace + */ +public class GroupBaseEditorInput extends WorkspaceEditorInput { + + private final String groupBaseId; + + /** uri, workspace name and group base Id cannot be null */ + public GroupBaseEditorInput(String repoNodePath, String uri, + String workspaceName, String groupBaseId) { + super(repoNodePath, uri, workspaceName); + if (groupBaseId == null) + throw new SlcException("Group base ID cannot be null"); + this.groupBaseId = groupBaseId; + } + + public String getToolTipText() { + return "Editor for group base of ID " + groupBaseId + " in workspace " + + getWorkspaceName() + " in " + getUri(); + } + + public String getName() { + return groupBaseId; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof GroupBaseEditorInput)) + return false; + + GroupBaseEditorInput other = (GroupBaseEditorInput) obj; + + if (groupBaseId.equals(other.getGroupBaseId())) + return super.equals(obj); + else + return false; + } + + public String getGroupBaseId() { + return groupBaseId; + } + +} \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/WorkspaceEditorInput.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/WorkspaceEditorInput.java new file mode 100644 index 000000000..a440cbcdc --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/WorkspaceEditorInput.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.argeo.slc.client.ui.dist.editors; + +import org.argeo.slc.SlcException; +import org.argeo.slc.jcr.SlcNames; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * An editor input pointing to a distribution workspace + */ +public class WorkspaceEditorInput implements IEditorInput, SlcNames { + + // Injected + // private RepositoryFactory repositoryFactory; + // private Keyring keyring; + // private Node repoNode; + private String repoNodePath; + private String uri; + + // Local variables + private String workspaceName; + + // public WorkspaceEditorInput(RepositoryFactory repositoryFactory, + // Keyring keyring, Repository localRepository, Node repoNode, + // String uri) { + // // this.repositoryFactory = repositoryFactory; + // // this.keyring = keyring; + // this.localRepository = localRepository; + // // this.repoNode= repoNode; + // this.uri = uri; + // + // } + + /** uri and workspace name cannot be null */ + public WorkspaceEditorInput(String repoNodePath, String uri, + String workspaceName) { + if (workspaceName == null) + throw new SlcException("Workspace name cannot be null"); + if (uri == null) + throw new SlcException("URI for repository cannot be null"); + this.repoNodePath = repoNodePath; + this.workspaceName = workspaceName; + this.uri = uri; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public boolean exists() { + return true; + } + + public ImageDescriptor getImageDescriptor() { + return null; + } + + // Dummy compulsory methods + public String getToolTipText() { + return "Editor for workspace " + workspaceName + + " in repository of URI " + uri; + } + + public String getName() { + return workspaceName + "@" + uri; + } + + public IPersistableElement getPersistable() { + return null; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof WorkspaceEditorInput)) + return false; + + WorkspaceEditorInput other = (WorkspaceEditorInput) obj; + + if (!workspaceName.equals(other.getWorkspaceName())) + return false; + if (!uri.equals(other.getUri())) + return false; + + if (repoNodePath == null) + return other.getRepoNodePath() == null; + else + return repoNodePath.equals(other.getRepoNodePath()); + } + + public String getUri() { + return uri; + } + + public String getWorkspaceName() { + return workspaceName; + } + + public String getRepoNodePath() { + return repoNodePath; + } +} \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/DistParentElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/DistParentElem.java index 09dede9e8..fe960b43f 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/DistParentElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/DistParentElem.java @@ -1,30 +1,48 @@ package org.argeo.slc.client.ui.dist.model; -/** Common super class for all tree elements of the Distributions View*/ -public abstract class DistParentElem { - public final static Character VERSION_SEP = '-'; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.argeo.eclipse.ui.TreeParent; + +/** Common super class for all tree elements of the Distributions View */ +public abstract class DistParentElem extends TreeParent { + protected final static Character VERSION_SEP = '-'; + + protected static final List ARGEO_SYSTEM_WKSP; + static { + List tmpList = new ArrayList(); + tmpList.add("main"); + tmpList.add("proxy"); + tmpList.add("security"); + tmpList.add("localrepo"); + ARGEO_SYSTEM_WKSP = Collections.unmodifiableList(tmpList); + } private boolean inHome = false; private boolean isReadOnly = false; - public DistParentElem(boolean inHome, boolean isReadOnly) { + public DistParentElem(String name, boolean inHome, boolean isReadOnly) { + super(name); this.inHome = inHome; this.isReadOnly = isReadOnly; } - public DistParentElem() { + public DistParentElem(String name) { + super(name); } - public abstract String getLabel(); - - public abstract Object[] getChildren(); - - public boolean hasChildren() { - return true; - } - - public void dispose() { - } + // public abstract String getLabel(); + // + // public abstract Object[] getChildren(); + // + // public boolean hasChildren() { + // return true; + // } + // + // public void dispose() { + // } public void setInHome(boolean inHome) { this.inHome = inHome; diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupBaseElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupBaseElem.java index 9b6b3ff77..2b9a8fe12 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupBaseElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupBaseElem.java @@ -5,12 +5,14 @@ package org.argeo.slc.client.ui.dist.model; * have the same group ID */ public class GroupBaseElem extends DistParentElem { - private WorkspaceElem wkspElem; + // private WorkspaceElem wkspElem; private String groupId; public GroupBaseElem(WorkspaceElem wkspElem, String groupId) { - super(wkspElem.inHome(), wkspElem.isReadOnly()); - this.wkspElem = wkspElem; + super(groupId, wkspElem.inHome(), wkspElem.isReadOnly()); + + setParent(wkspElem); + // this.wkspElem = wkspElem; this.groupId = groupId; } @@ -22,14 +24,18 @@ public class GroupBaseElem extends DistParentElem { return groupId; } - public String toString() { - return getLabel(); - } + // public String toString() { + // return getLabel(); + // } - public void dispose() { - } + // public void dispose() { + // } public WorkspaceElem getWorkspaceElem() { - return wkspElem; + return (WorkspaceElem) getParent(); + } + + public String getGroupId() { + return getName(); } } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java index 60916bec5..3dc56ed2b 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java @@ -1,20 +1,14 @@ package org.argeo.slc.client.ui.dist.model; import java.security.AccessControlException; -import java.util.HashMap; -import java.util.Map; import javax.jcr.Credentials; import javax.jcr.Node; -import javax.jcr.Property; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.jcr.ArgeoJcrUtils; import org.argeo.jcr.ArgeoNames; import org.argeo.jcr.JcrUtils; @@ -24,152 +18,205 @@ import org.argeo.slc.repo.RepoUtils; import org.argeo.util.security.Keyring; /** - * Abstract a repository. It might be persisted by a node in the current user home - * Node or just an URI and a label if user is anonymous + * Abstract a repository. It might be persisted by a node in the current user + * home Node or just an URI and a label if user is anonymous */ public class RepoElem extends DistParentElem { - private final static Log log = LogFactory.getLog(RepoElem.class); + // private final static Log log = LogFactory.getLog(RepoElem.class); - private Repository repository; - private Credentials credentials; private RepositoryFactory repositoryFactory; private Keyring keyring; + private Credentials credentials; + private Session defaultSession = null; // Defines current repo private Node repoNode = null; private String label; private String uri; + private Repository repository; + /** - * Creates a RepoElement for an authenticated user. repofactory and keyring - * are used to enable lazy init + * Creates a RepoElement for anonymous user. The {@code RepositoryFactory} + * is used to enable lazy initialisation + */ + public RepoElem(RepositoryFactory repoFactory, String uri, String label) { + super(label); + this.repositoryFactory = repoFactory; + this.uri = uri; + this.label = label; + } + + /** + * Creates a RepoElement for an authenticated user. The + * {@code RepositoryFactory} and {@code Keyring} are used to enable lazy + * initialisation * */ - public RepoElem(Node repoNode, RepositoryFactory repoFactory, - Keyring keyring) { + public RepoElem(RepositoryFactory repoFactory, Keyring keyring, + Node repoNode, String alias) { + super(alias); + this.label = alias; + // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode + // .getProperty(Property.JCR_TITLE).getString() : repoNode + // .getName(); this.repoNode = repoNode; this.repositoryFactory = repoFactory; this.keyring = keyring; try { - // initialize this repo informations + // Initialize this repo information setInHome(RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS .equals(repoNode.getName())); - if (!inHome()) + if (inHome()) + // Directly log and retrieve children for local repository + login(); + else setReadOnly(!repoNode.hasNode(ArgeoNames.ARGEO_PASSWORD)); uri = JcrUtils.get(repoNode, ArgeoNames.ARGEO_URI); - label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode - .getProperty(Property.JCR_TITLE).getString() : repoNode - .getName(); } catch (RepositoryException e) { throw new SlcException("Unable to " + "initialize repo element", e); } } - /** - * Creates a RepoElement for anonymous user. repofactory is used to enable - * lazy init - * - */ - public RepoElem(RepositoryFactory repoFactory, String uri, String label) { - this.repositoryFactory = repoFactory; - this.uri = uri; - this.label = label; + /** Effective login. Does nothing if the session is already there. */ + public void login() { + if (isConnected()) + return; + + if (repository == null) + if (repoNode == null) + // Anonymous + repository = ArgeoJcrUtils.getRepositoryByUri( + repositoryFactory, uri); + else { + repository = RepoUtils.getRepository(repositoryFactory, + keyring, repoNode); + credentials = RepoUtils.getRepositoryCredentials(keyring, + repoNode); + } + + try { + defaultSession = repository.login(credentials); + refreshChildren(); + } catch (RepositoryException e) { + throw new SlcException("Cannot login repository " + label + + " with credential " + credentials, e); + } } - /** Lazily connects to repository */ - protected void connect() { - if (repository != null) - return; - if (repoNode == null) - // Anonymous - repository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, - uri); - else { - repository = RepoUtils.getRepository(repositoryFactory, keyring, - repoNode); - credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode); + protected void refreshChildren() { + try { + // TODO also remove deleted children (only adds for the time being + String[] workspaceNames = defaultSession.getWorkspace() + .getAccessibleWorkspaceNames(); + buildWksp: for (String workspaceName : workspaceNames) { + if (!isWorkspaceVisible(workspaceName)) + continue buildWksp; + + String prefix = getPrefix(workspaceName); + if (getChildByName(prefix) == null) { + WkspGroupElem wkspGpElem = new WkspGroupElem(RepoElem.this, + prefix); + addChild(wkspGpElem); + } + } + } catch (RepositoryException e) { + throw new SlcException("Cannot list workspaces for " + repoNode, e); } } - public String getLabel() { - return label; + @Override + public synchronized void dispose() { + JcrUtils.logoutQuietly(defaultSession); + super.dispose(); } - public String getUri() { - return uri; + private String getPrefix(String workspaceName) { + // Here is the tricks - we rely on a "hard coded" convention + // Workspace name should be like: name-major.minor + if (workspaceName.lastIndexOf(VERSION_SEP) > 0) + return workspaceName.substring(0, + workspaceName.lastIndexOf(VERSION_SEP)); + else + return workspaceName; } - public String toString() { - return repoNode != null ? repoNode.toString() : label; + /* Exposes this to the children workspace group */ + protected boolean isWorkspaceVisible(String wkspName) { + Boolean result = true; + if (ARGEO_SYSTEM_WKSP.contains(wkspName)) + return false; + // Add a supplementary check to hide workspace that are not + // public to anonymous user + if (repoNode == null) { + Session tmpSession = null; + try { + tmpSession = repository.login(wkspName); + try { + tmpSession.checkPermission("/", "read"); + } catch (AccessControlException e) { + result = false; + } + } catch (RepositoryException e) { + throw new SlcException( + "Cannot list workspaces for anonymous user", e); + } finally { + JcrUtils.logoutQuietly(tmpSession); + } + } + return result; } - public Object[] getChildren() { + /** + * Actual call to the + * {@link Repository#login(javax.jcr.Credentials, String)} method. To be + * overridden. + * + * Creates a new session with correct credentials using the information + * contained in the corresponding repo node. It provides all UI children + * elements an unique entry point to retrieve a new Session. Caller must + * close the session when it is not in use anymore. + * + */ + protected Session repositoryLogin(String workspaceName) { try { - connect(); - } catch (Exception e) { - log.error("Cannot connect to " + uri + " return no children.", e); - return new Object[0]; + return repository.login(credentials, workspaceName); + } catch (RepositoryException e) { + throw new SlcException("Cannot login repository " + label + + " with credential " + credentials, e); } + } - Session session = null; - try { - session = repository.login(credentials); - String[] workspaceNames = session.getWorkspace() - .getAccessibleWorkspaceNames(); - Map children = new HashMap(); + public Boolean isConnected() { + if (defaultSession != null && defaultSession.isLive()) + return true; + else + return false; + } - buildWksp: for (String workspaceName : workspaceNames) { - // Add a supplementary check to hide workspace that are not - // public to anonymous user - - if (repoNode == null) { - Session tmpSession = null; - try { - tmpSession = repository.login(workspaceName); - Boolean res = true; - try { - tmpSession.checkPermission("/", "read"); - } catch (AccessControlException e) { - res = false; - } - if (!res) - continue buildWksp; - } catch (RepositoryException e) { - throw new SlcException( - "Cannot list workspaces for anonymous user", e); - } finally { - JcrUtils.logoutQuietly(tmpSession); - } - } + /** Exposes URI to the current repository */ + public String getUri() { + return uri; + } - // filter technical workspaces - // FIXME: rely on a more robust rule than just wksp name - if (workspaceName.lastIndexOf(VERSION_SEP) > 0) { - String prefix = workspaceName.substring(0, - workspaceName.lastIndexOf(VERSION_SEP)); - if (!children.containsKey(prefix)) { - children.put(prefix, new WkspGroupElem(RepoElem.this, - prefix)); - } - } - } - return children.values().toArray(); - } catch (RepositoryException e) { - throw new SlcException("Cannot list workspaces for " + repoNode, e); - } finally { - JcrUtils.logoutQuietly(session); - } + /** + * Exposes the local repoNode that completely define a connection to a + * repository (including a set of credentials). Might return null in case of + * an anonymous user + */ + public Node getRepoNode() { + return repoNode; } public Repository getRepository() { - connect(); return repository; } - + public Credentials getCredentials() { return credentials; } + // META INFO public String getDescription() { String desc = label; if (repoNode != null) @@ -177,8 +224,11 @@ public class RepoElem extends DistParentElem { return desc; } - /** Might return null in case of an anonymous user */ - public Node getRepoNode() { - return repoNode; + public String getLabel() { + return label; + } + + public String toString() { + return repoNode != null ? repoNode.toString() : label; } } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WkspGroupElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WkspGroupElem.java index 685a8e053..95d28ebb3 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WkspGroupElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WkspGroupElem.java @@ -1,92 +1,105 @@ package org.argeo.slc.client.ui.dist.model; -import java.security.AccessControlException; -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import org.argeo.ArgeoException; import org.argeo.jcr.JcrUtils; -import org.argeo.slc.SlcException; /** * Abstract set of similar workspaces, that is a bunch of workspaces with same * prefix. */ public class WkspGroupElem extends DistParentElem { - private RepoElem repoElem; - private String name; - public WkspGroupElem(RepoElem repoElem, String prefix) { - super(repoElem.inHome(), repoElem.isReadOnly()); - this.repoElem = repoElem; - this.name = prefix; - } + private Session defaultSession; - public Object[] getChildren() { - Session session = null; + /** + */ + public WkspGroupElem(RepoElem repoElem, String prefix) { + super(prefix, repoElem.inHome(), repoElem.isReadOnly()); + setParent(repoElem); + // Directly adds children upon creation try { - Repository repository = repoElem.getRepository(); - session = repository.login(repoElem.getCredentials()); - - String[] workspaceNames = session.getWorkspace() + defaultSession = repoElem.repositoryLogin(null); + String[] wkpNames = defaultSession.getWorkspace() .getAccessibleWorkspaceNames(); - List distributionElems = new ArrayList(); - buildWksp: for (String workspaceName : workspaceNames) { - - // Filter non-public workspaces for user anonymous. - if (repoElem.getRepoNode() == null) { - Session tmpSession = null; - try { - tmpSession = repository.login(workspaceName); - Boolean res = true; - try { - tmpSession.checkPermission("/", "read"); - } catch (AccessControlException e) { - res = false; - } - if (!res) - continue buildWksp; - } catch (RepositoryException e) { - throw new SlcException( - "Cannot list workspaces for anonymous user", e); - } finally { - JcrUtils.logoutQuietly(tmpSession); - } - } - - // filter technical workspaces - if (workspaceName.startsWith(name) - && workspaceName.substring(0, - workspaceName.lastIndexOf(VERSION_SEP)).equals( - name)) { - distributionElems.add(new WorkspaceElem(repoElem, - workspaceName)); - } + for (String wkpName : wkpNames) { + if (wkpName.startsWith(prefix) + && repoElem.isWorkspaceVisible(wkpName)) + addChild(new WorkspaceElem(WkspGroupElem.this, repoElem, + wkpName)); } - return distributionElems.toArray(); } catch (RepositoryException e) { - throw new SlcException("Cannot list workspaces for prefix " + name, - e); - } finally { - JcrUtils.logoutQuietly(session); + throw new ArgeoException("Cannot retrieve workspace names", e); } } - public String getLabel() { - return name; - } + // + // public Object[] getChildren() { + // Session session = null; + // try { + // Repository repository = repoElem.getRepository(); + // session = repository.login(repoElem.getCredentials()); + // + // String[] workspaceNames = session.getWorkspace() + // .getAccessibleWorkspaceNames(); + // List distributionElems = new ArrayList(); + // buildWksp: for (String workspaceName : workspaceNames) { + // + // // Filter non-public workspaces for user anonymous. + // if (repoElem.getRepoNode() == null) { + // Session tmpSession = null; + // try { + // tmpSession = repository.login(workspaceName); + // Boolean res = true; + // try { + // tmpSession.checkPermission("/", "read"); + // } catch (AccessControlException e) { + // res = false; + // } + // if (!res) + // continue buildWksp; + // } catch (RepositoryException e) { + // throw new SlcException( + // "Cannot list workspaces for anonymous user", e); + // } finally { + // JcrUtils.logoutQuietly(tmpSession); + // } + // } + // + // // filter technical workspaces + // if (workspaceName.startsWith(name) + // && workspaceName.substring(0, + // workspaceName.lastIndexOf(VERSION_SEP)).equals( + // name)) { + // distributionElems.add(new WorkspaceElem(repoElem, + // workspaceName)); + // } + // } + // return distributionElems.toArray(); + // } catch (RepositoryException e) { + // throw new SlcException("Cannot list workspaces for prefix " + name, + // e); + // } finally { + // JcrUtils.logoutQuietly(session); + // } + // } - public String toString() { - return getLabel(); - } + // public String getLabel() { + // return name; + // } + // + // public String toString() { + // return getLabel(); + // } public void dispose() { + JcrUtils.logoutQuietly(defaultSession); + super.dispose(); } - public RepoElem getRepoElem() { - return repoElem; - } + // public RepoElem getRepoElem() { + // return repoElem; + // } } \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WorkspaceElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WorkspaceElem.java index 9cf295c5f..52acdac7d 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WorkspaceElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WorkspaceElem.java @@ -1,26 +1,26 @@ package org.argeo.slc.client.ui.dist.model; -/** Abstracts a workspace that contains a given distribution */ +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.query.Query; + +import org.argeo.ArgeoException; +import org.argeo.slc.jcr.SlcNames; +import org.argeo.slc.jcr.SlcTypes; + +/** Abstract a workspace that contains a software distribution */ public class WorkspaceElem extends DistParentElem { private final RepoElem repoElem; private String workspaceName; - private String label; - - // /** - // * Helper to display only version when the workspace name is well - // formatted - // */ - // private static String formatName(String name) { - // if (name != null && name.lastIndexOf(VERSION_SEP) > 0) - // return name.substring(name.lastIndexOf(VERSION_SEP) + 1); - // else - // return name; - // } - - public WorkspaceElem(RepoElem repoElem, String workspaceName) { + private Session defaultSession; + + public WorkspaceElem(WkspGroupElem parent, RepoElem repoElem, + String workspaceName) { + super(workspaceName, repoElem.inHome(), repoElem.isReadOnly()); this.repoElem = repoElem; this.workspaceName = workspaceName; - this.label = workspaceName; // formatName(workspaceName); + setParent(parent); } public String getWorkspaceName() { @@ -31,20 +31,63 @@ public class WorkspaceElem extends DistParentElem { return repoElem; } - public boolean isReadOnly() { - return repoElem.isReadOnly(); + public Boolean isConnected() { + if (defaultSession != null && defaultSession.isLive()) + return true; + else + return false; } - public boolean hasChildren() { - return false; + public void login() { + defaultSession = repoElem.repositoryLogin(getName()); } - public Object[] getChildren() { - return null; + public boolean hasChildren() { + try { + if (isConnected()) + return defaultSession.getRootNode().hasNodes(); + else + return false; + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while checking children node existence", + re); + } } + /** Override normal behaviour to initialize display of the workspace */ @Override - public String getLabel() { - return label; + public synchronized Object[] getChildren() { + if (isLoaded()) { + return super.getChildren(); + } else { + // initialize current object + try { + if (defaultSession == null) + return null; + else { + Query groupQuery = defaultSession + .getWorkspace() + .getQueryManager() + .createQuery( + "select * from [" + SlcTypes.SLC_GROUP_BASE + + "] as group order by group.[" + + SlcNames.SLC_GROUP_BASE_ID + "]", + Query.JCR_SQL2); + NodeIterator groups = groupQuery.execute().getNodes(); + while (groups.hasNext()) { + addChild(new GroupBaseElem(WorkspaceElem.this, groups + .nextNode() + .getProperty(SlcNames.SLC_GROUP_BASE_ID) + .getString())); + } + } + return super.getChildren(); + } catch (RepositoryException e) { + throw new ArgeoException( + "Cannot initialize WorkspaceNode UI object." + + getName(), e); + } + } } } diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/AnonymousDistributionsView.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/AnonymousDistributionsView.java index ed57feccd..21e8f37b0 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/AnonymousDistributionsView.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/AnonymousDistributionsView.java @@ -63,7 +63,7 @@ public class AnonymousDistributionsView extends ViewPart implements SlcNames, // viewer.setContentProvider(new DistTreeContentProvider()); viewer.setContentProvider(treeContentProvider); - viewer.addDoubleClickListener(new DistTreeDoubleClickListener()); + viewer.addDoubleClickListener(new DistTreeDoubleClickListener(viewer)); viewer.setComparator(new DistTreeComparator()); // Initialize diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/DistributionsView.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/DistributionsView.java index 29797590d..09119524f 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/DistributionsView.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/DistributionsView.java @@ -39,12 +39,13 @@ import org.argeo.slc.client.ui.dist.commands.RefreshDistributionsView; import org.argeo.slc.client.ui.dist.commands.RegisterRepository; import org.argeo.slc.client.ui.dist.commands.UnregisterRemoteRepo; import org.argeo.slc.client.ui.dist.controllers.DistTreeComparator; +import org.argeo.slc.client.ui.dist.controllers.DistTreeComparer; import org.argeo.slc.client.ui.dist.controllers.DistTreeContentProvider; import org.argeo.slc.client.ui.dist.controllers.DistTreeDoubleClickListener; import org.argeo.slc.client.ui.dist.controllers.DistTreeLabelProvider; import org.argeo.slc.client.ui.dist.model.DistParentElem; -import org.argeo.slc.client.ui.dist.model.WkspGroupElem; import org.argeo.slc.client.ui.dist.model.RepoElem; +import org.argeo.slc.client.ui.dist.model.WkspGroupElem; import org.argeo.slc.client.ui.dist.model.WorkspaceElem; import org.argeo.slc.client.ui.dist.utils.CommandHelpers; import org.argeo.slc.jcr.SlcNames; @@ -57,6 +58,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerDropAdapter; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; @@ -103,9 +105,14 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames // viewer.setContentProvider(new DistTreeContentProvider()); viewer.setContentProvider(treeContentProvider); - viewer.addDoubleClickListener(new DistTreeDoubleClickListener()); + viewer.addDoubleClickListener(new DistTreeDoubleClickListener(viewer)); + viewer.setComparer(new DistTreeComparer()); + viewer.setComparator(new DistTreeComparator()); + @SuppressWarnings("unused") + ViewerComparator vc = viewer.getComparator(); + // Enable retrieving current tree selected items from outside the view getSite().setSelectionProvider(viewer); @@ -156,7 +163,7 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames if (firstElement instanceof WorkspaceElem) { WorkspaceElem de = (WorkspaceElem) firstElement; - re = de.getRepoElem(); + re = (RepoElem) de.getParent().getParent(); isDistribElem = true; isReadOnly = de.isReadOnly(); workspaceName = de.getWorkspaceName(); @@ -166,13 +173,15 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames isHomeRepo = re.inHome(); isReadOnly = re.isReadOnly(); } else if (firstElement instanceof WkspGroupElem) { - WkspGroupElem dge = (WkspGroupElem) firstElement; - isReadOnly = dge.isReadOnly(); + WkspGroupElem wge = (WkspGroupElem) firstElement; + isReadOnly = wge.isReadOnly(); isDistribGroupElem = true; - re = dge.getRepoElem(); - workspacePrefix = dge.getLabel(); + re = (RepoElem) wge.getParent(); + workspacePrefix = wge.getName(); } + // TODO add case for goups + if (re != null) { // targetRepoUri = re.getUri(); targetRepoPath = re.getRepoNode().getPath(); @@ -270,7 +279,7 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames PublishWorkspace.ID, PublishWorkspace.DEFAULT_LABEL, PublishWorkspace.DEFAULT_ICON, isDistribElem && singleElement && !isReadOnly, params); - + // Normalize distribution (Legacy) params = new HashMap(); params.put(NormalizeDistribution.PARAM_TARGET_REPO_PATH, @@ -283,8 +292,6 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames NormalizeDistribution.DEFAULT_ICON, isDistribElem && singleElement && !isReadOnly, params); - - if (submenu.getSize() > 0) menuManager.add(submenu); @@ -324,8 +331,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames if (selection.getFirstElement() instanceof WorkspaceElem) { WorkspaceElem de = (WorkspaceElem) selection.getFirstElement(); if (TextTransfer.getInstance().isSupportedType(event.dataType)) { - event.data = de.getRepoElem().getUri() + "/" - + de.getWorkspaceName(); + event.data = ((RepoElem) de.getParent().getParent()) + .getUri() + "/" + de.getWorkspaceName(); } } } @@ -340,14 +347,18 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames @Override public boolean performDrop(Object data) { - WorkspaceElem sourceDist = (WorkspaceElem) getSelectedObject(); + WorkspaceElem sourceWksp = (WorkspaceElem) getSelectedObject(); RepoElem targetRepo = (RepoElem) getCurrentTarget(); - Boolean ok = MessageDialog.openConfirm(getSite().getShell(), - "Confirm distribution merge", "Do you want to merge " - + sourceDist.getWorkspaceName() + " (from repo " - + sourceDist.getRepoElem().getLabel() - + ") to repo " + targetRepo.getLabel() + "?"); + Boolean ok = MessageDialog.openConfirm( + getSite().getShell(), + "Confirm distribution merge", + "Do you want to merge " + + sourceWksp.getWorkspaceName() + + " (from repo " + + ((RepoElem) sourceWksp.getParent().getParent()) + .getLabel() + ") to repo " + + targetRepo.getLabel() + "?"); if (!ok) return false; @@ -355,14 +366,15 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames Map params = new HashMap(); params.put(MergeWorkspaces.PARAM_TARGET_REPO_PATH, targetRepo .getRepoNode().getPath()); - params.put(MergeWorkspaces.PARAM_SOURCE_REPO_PATH, sourceDist - .getRepoElem().getRepoNode().getPath()); + params.put(MergeWorkspaces.PARAM_SOURCE_REPO_PATH, + ((RepoElem) sourceWksp.getParent().getParent()) + .getRepoNode().getPath()); params.put(MergeWorkspaces.PARAM_SOURCE_WORKSPACE_NAME, - sourceDist.getWorkspaceName()); + sourceWksp.getWorkspaceName()); CommandHelpers.callCommand(RefreshDistributionsView.ID, params); return true; } catch (RepositoryException e) { - throw new SlcException("Cannot process drop from " + sourceDist + throw new SlcException("Cannot process drop from " + sourceWksp + " to " + targetRepo, e); } } @@ -373,8 +385,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames if (target instanceof RepoElem) { if (getSelectedObject() instanceof WorkspaceElem) { // check if not same repository - String srcRepoUri = ((WorkspaceElem) getSelectedObject()) - .getRepoElem().getUri(); + String srcRepoUri = ((RepoElem) ((WorkspaceElem) getSelectedObject()) + .getParent().getParent()).getUri(); String targetRepoUri = ((RepoElem) target).getUri(); return !targetRepoUri.equals(srcRepoUri); } diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/RegisterRepoWizard.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/RegisterRepoWizard.java index 76df06274..3f7f30c65 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/RegisterRepoWizard.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/RegisterRepoWizard.java @@ -224,7 +224,7 @@ public class RegisterRepoWizard extends Wizard { /** Creates label and text. */ protected Text createLT(Composite parent, String label, String initial) { - new Label(parent, SWT.NONE).setText(label); + new Label(parent, SWT.RIGHT).setText(label); Text text = new Text(parent, SWT.SINGLE | SWT.LEAD | SWT.BORDER); text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); text.setText(initial); @@ -234,7 +234,7 @@ public class RegisterRepoWizard extends Wizard { /** Creates label and check. */ protected Button createLC(Composite parent, String label, Boolean initial) { - new Label(parent, SWT.NONE).setText(label); + new Label(parent, SWT.RIGHT).setText(label); Button check = new Button(parent, SWT.CHECK); check.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); check.setSelection(initial); diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java index 7b901af43..591da8e47 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoUtils.java @@ -388,7 +388,7 @@ public class RepoUtils implements ArgeoNames, SlcNames { } /** - * Reads credentials from node, using keyring if there is a password. Cann + * Reads credentials from node, using keyring if there is a password. Can * return null if no credentials needed (local repo) at all, but returns * {@link GuestCredentials} if user id is 'anonymous' . */ @@ -416,6 +416,42 @@ public class RepoUtils implements ArgeoNames, SlcNames { } } + /** + * Shortcut to retrieve a session given variable information: Handle the + * case where we only have an URI of the repository, that we want to connect + * as anonymous or the case of a identified connexion to a local or remote + * repository. + * + * Callers must close the session once it has been used + */ + public static Session getCorrespondingSession( + RepositoryFactory repositoryFactory, Keyring keyring, + Node repoNode, String uri, String workspaceName) { + try { + if (repoNode == null && uri == null) + throw new SlcException( + "At least one of repoNode and uri must be defined"); + Repository currRepo = null; + Credentials credentials = null; + // Anonymous URI only workspace + if (repoNode == null) + // Anonymous + currRepo = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, + uri); + else { + currRepo = RepoUtils.getRepository(repositoryFactory, keyring, + repoNode); + credentials = RepoUtils.getRepositoryCredentials(keyring, + repoNode); + } + return currRepo.login(credentials, workspaceName); + } catch (RepositoryException e) { + throw new SlcException("Cannot connect to workspace " + + workspaceName + " of repository " + repoNode + + " with URI " + uri, e); + } + } + /** * Write group indexes: 'binaries' lists all bundles and their versions, * 'sources' list theire sources, and 'sdk' aggregates both. -- 2.39.2