refactor and clean of the distribution view model.
authorBruno Sinou <bsinou@argeo.org>
Wed, 13 Mar 2013 21:09:13 +0000 (21:09 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 13 Mar 2013 21:09:13 +0000 (21:09 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6130 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

12 files changed:
plugins/org.argeo.slc.client.ui.dist/META-INF/spring/views.xml
plugins/org.argeo.slc.client.ui.dist/plugin.xml
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/AnonymousDistributionPerspective.java
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/DistributionPerspective.java
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/DistParentElem.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupElem.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/WorkspaceElem.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistSessionFactory.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeContentProvider.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeLabelProvider.java [new file with mode: 0644]
plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/DistributionsView.java

index 684e01fa9a0511362c88e593cb306e24eb03ab69..e65fc55ed5d7095d6ad15158e7e7bccec7e708e0 100644 (file)
 
        <bean id="distributionsView" class="org.argeo.slc.client.ui.dist.views.DistributionsView"
                scope="prototype">
-               <property name="repositoryFactory" ref="repositoryFactory" />
+               <!-- <property name="repositoryFactory" ref="repositoryFactory" /> -->
+               <!-- <property name="keyring" ref="keyring" /> -->
                <property name="nodeRepository" ref="nodeRepository" />
+               <property name="treeContentProvider" ref="distTreeContentProvider" />
+       </bean>
+
+       <!-- Corresponding content provider -->
+       <bean id="distTreeContentProvider"
+               class="org.argeo.slc.client.ui.dist.providers.DistTreeContentProvider"
+               scope="prototype">
+               <property name="repositoryFactory" ref="repositoryFactory" />
                <property name="keyring" ref="keyring" />
        </bean>
+
+       <!-- <bean id="distributionPerspective" class="org.argeo.slc.client.ui.dist.DistributionPerspective" 
+               scope="prototype"> <property name="repositoryFactory" ref="repositoryFactory" 
+               /> <property name="nodeRepository" ref="nodeRepository" /> </bean> -->
 </beans>
index 62c94737a96099c01e0efedb124b5664a711c126..4762d583db00bb12579ed80681a92895df50f997 100644 (file)
@@ -4,18 +4,18 @@
        <!-- Perspectives --> 
    <extension
          point="org.eclipse.ui.perspectives">
-      <perspective
+               <perspective
             name="SLC Repo"
             class="org.argeo.slc.client.ui.dist.DistributionPerspective"
             id="org.argeo.slc.client.ui.dist.distributionPerspective"
-            icon="icons/distribution_perspective.gif">
-      </perspective>
-      <perspective
+            icon="icons/repo.gif">
+               </perspective>
+               <perspective
             name="SLC Distribution"
             class="org.argeo.slc.client.ui.dist.AnonymousDistributionPerspective"
             id="org.argeo.slc.client.ui.dist.anonymousDistributionPerspective"
             icon="icons/distribution_perspective.gif">
-      </perspective>
+               </perspective>
    </extension>
    <!-- Views -->
    <extension
index fea97b88922e6e1d43c121aabe5065d43d67b322..c372d6a5bb0557a97da71b92dab1143f5b65e85e 100644 (file)
@@ -32,10 +32,5 @@ public class AnonymousDistributionPerspective implements IPerspectiveFactory {
                IFolderLayout main = layout.createFolder("main", IPageLayout.LEFT,
                                0.5f, editorArea);
                main.addView(DistributionsView.ID);
-//             main.addView(ArtifactsBrowser.ID);
-//             main.addView(QueryArtifactsForm.ID);
-//             main.addView(QueryBundlesForm.ID);
-//             main.addView(QueryArtifactsText.ID);
-               main.addView("org.eclipse.ui.views.ProgressView");
        }
 }
index 88879ab2c33b45fbf658ea93cf3229d1eebd1b5b..c9b5edf9ec181094840ee7526331d322853efe42 100644 (file)
@@ -20,11 +20,20 @@ import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
 
+/**
+ * User interface to manage a set of distributions split into several
+ * repositories
+ */
 public class DistributionPerspective implements IPerspectiveFactory {
 
+//     private RepositoryFactory repositoryFactory;
+//     private Repository nodeRepository;
+
        public final static String ID = DistPlugin.ID + ".distributionPerspective";
 
        public void createInitialLayout(IPageLayout layout) {
+               //initializeModel();
+
                String editorArea = layout.getEditorArea();
                layout.setEditorAreaVisible(true);
                layout.setFixed(false);
@@ -32,10 +41,52 @@ public class DistributionPerspective implements IPerspectiveFactory {
                IFolderLayout main = layout.createFolder("main", IPageLayout.LEFT,
                                0.5f, editorArea);
                main.addView(DistributionsView.ID);
-//             main.addView(ArtifactsBrowser.ID);
-//             main.addView(QueryArtifactsForm.ID);
-//             main.addView(QueryBundlesForm.ID);
-//             main.addView(QueryArtifactsText.ID);
                main.addView("org.eclipse.ui.views.ProgressView");
+
        }
+
+//     private void initializeModel() {
+//             Session nodeSession = null;
+//             try {
+//                     nodeSession = nodeRepository.login();
+//
+//                     Node homeNode = UserJcrUtils.getUserHome(nodeSession);
+//                     if (homeNode == null) // anonymous
+//                             throw new SlcException("User must be authenticated.");
+//
+//                     // make sure base directory is available
+//                     Node repos = JcrUtils.mkdirs(nodeSession, homeNode.getPath()
+//                                     + RepoConstants.REPOSITORIES_BASE_PATH);
+//                     nodeSession.save();
+//
+//                     // register default local java repository
+//                     String alias = RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS;
+//                     Repository javaRepository = ArgeoJcrUtils.getRepositoryByAlias(
+//                                     repositoryFactory, alias);
+//                     if (javaRepository != null) {
+//                             if (!repos.hasNode(alias)) {
+//                                     Node repoNode = repos.addNode(alias,
+//                                                     ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
+//                                     repoNode.setProperty(ArgeoNames.ARGEO_URI, "vm:///" + alias);
+//                                     repoNode.addMixin(NodeType.MIX_TITLE);
+//                                     repoNode.setProperty(Property.JCR_TITLE,
+//                                                     RepoConstants.DEFAULT_JAVA_REPOSITORY_LABEL);
+//                                     nodeSession.save();
+//                             }
+//                     }
+//             } catch (RepositoryException e) {
+//                     throw new SlcException("Cannot register repository", e);
+//             } finally {
+//                     JcrUtils.logoutQuietly(nodeSession);
+//             }
+//     }
+
+       // public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+       // this.repositoryFactory = repositoryFactory;
+       // }
+       //
+       // public void setRepository(Repository nodeRepository) {
+       // this.nodeRepository = nodeRepository;
+       // }
+
 }
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
new file mode 100644 (file)
index 0000000..f75423f
--- /dev/null
@@ -0,0 +1,29 @@
+package org.argeo.slc.client.ui.dist.model;
+
+public abstract class DistParentElem {
+       private boolean inHome = false;
+       private boolean isReadOnly = false;
+
+       public DistParentElem(boolean inHome, boolean isReadOnly) {
+               this.inHome = inHome;
+               this.isReadOnly = isReadOnly;
+       }
+
+       public DistParentElem() {
+       }
+
+       public abstract String getLabel();
+
+       public abstract Object[] getChildren();
+
+       public void dispose() {
+       }
+
+       public boolean inHome() {
+               return inHome;
+       }
+
+       public boolean isReadOnly() {
+               return isReadOnly;
+       }
+}
diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupElem.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/GroupElem.java
new file mode 100644 (file)
index 0000000..16c541f
--- /dev/null
@@ -0,0 +1,74 @@
+package org.argeo.slc.client.ui.dist.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+
+/**
+ * Abstracts a group of distribution, that is a bunch of workspaces with same
+ * prefix.
+ */
+public class GroupElem extends DistParentElem {
+       private RepoElem repoElem;
+       private String name;
+
+       public GroupElem(RepoElem repoElem, String prefix) {
+               super(repoElem.inHome(), repoElem.isReadOnly());
+               this.repoElem = repoElem;
+               this.name = prefix;
+       }
+
+       public Object[] getChildren() {
+               repoElem.connect();
+               Session session = null;
+               try {
+                       Repository repository = repoElem.getRepository();
+                       Node repoNode = repoElem.getRepoNode();
+                       session = repository.login(repoElem.getCredentials());
+
+                       String[] workspaceNames = session.getWorkspace()
+                                       .getAccessibleWorkspaceNames();
+                       List<WorkspaceElem> distributionElems = new ArrayList<WorkspaceElem>();
+                       for (String workspaceName : workspaceNames) {
+                               // filter technical workspaces
+                               if (workspaceName.startsWith(name)) {
+                                       Node workspaceNode = repoNode.hasNode(workspaceName) ? repoNode
+                                                       .getNode(workspaceName) : repoNode
+                                                       .addNode(workspaceName);
+                                       distributionElems.add(new WorkspaceElem(repoElem,
+                                                       workspaceNode));
+                                       // FIXME remove deleted workspaces
+                               }
+                       }
+                       return distributionElems.toArray();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot list workspaces for prefix " + name,
+                                       e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+       }
+
+       public String getLabel() {
+               return name;
+       }
+
+       public String toString() {
+               return getLabel();
+       }
+
+       public void dispose() {
+       }
+
+       public RepoElem getRepoElem() {
+               return repoElem;
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..75de44e
--- /dev/null
@@ -0,0 +1,136 @@
+package org.argeo.slc.client.ui.dist.model;
+
+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.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.RepoUtils;
+import org.argeo.util.security.Keyring;
+
+public class RepoElem extends DistParentElem {
+       private Node repoNode;
+       private Repository repository;
+       private Credentials credentials;
+
+       private RepositoryFactory repositoryFactory;
+       private Keyring keyring;
+
+       @Deprecated
+       public RepoElem(Node repoNode, boolean inHome, boolean isReadOnly) {
+               super(inHome, isReadOnly);
+               this.repoNode = repoNode;
+       }
+
+       /** Inject repofactory and keyring to enable lazy init */
+       public RepoElem(Node repoNode, RepositoryFactory repoFactory,
+                       Keyring keyring, boolean inHome, boolean isReadOnly) {
+               super(inHome, isReadOnly);
+               this.repoNode = repoNode;
+               this.repositoryFactory = repoFactory;
+               this.keyring = keyring;
+       }
+
+       /** Inject repofactory and keyring to enable lazy init */
+       public RepoElem(Node repoNode, RepositoryFactory repoFactory,
+                       Keyring keyring) {
+               this.repoNode = repoNode;
+               this.repositoryFactory = repoFactory;
+               this.keyring = keyring;
+       }
+
+       @Deprecated
+       public RepoElem(Node repoNode) {
+               this.repoNode = repoNode;
+       }
+
+       /** Lazily connects to repository */
+       protected void connect() {
+               if (repository != null)
+                       return;
+               repository = RepoUtils.getRepository(repositoryFactory, keyring,
+                               repoNode);
+               credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode);
+       }
+
+       public String getLabel() {
+               try {
+                       if (repoNode.isNodeType(NodeType.MIX_TITLE)) {
+                               return repoNode.getProperty(Property.JCR_TITLE).getString();
+                       } else {
+                               return repoNode.getName();
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot read label of " + repoNode, e);
+               }
+       }
+
+       public String toString() {
+               return repoNode.toString();
+       }
+
+       public Object[] getChildren() {
+               connect();
+               Session session = null;
+               try {
+                       session = repository.login(credentials);
+                       String[] workspaceNames = session.getWorkspace()
+                                       .getAccessibleWorkspaceNames();
+                       // List<DistributionElem> distributionElems = new
+                       // ArrayList<DistributionElem>();
+                       Map<String, GroupElem> children = new HashMap<String, GroupElem>();
+                       for (String workspaceName : workspaceNames) {
+                               // filter technical workspaces
+                               // FIXME: rely on a more robust rule than just wksp name
+                               if (workspaceName.lastIndexOf('-') > 0) {
+                                       String prefix = workspaceName.substring(0,
+                                                       workspaceName.lastIndexOf('-'));
+                                       if (!repoNode.hasNode(workspaceName))
+                                               repoNode.addNode(workspaceName);
+                                       repoNode.getSession().save();
+                                       if (!children.containsKey(prefix)) {
+                                               children.put(prefix, new GroupElem(RepoElem.this,
+                                                               prefix));
+                                       }
+                                       // FIXME remove deleted workspaces
+                               }
+                       }
+                       return children.values().toArray();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot list workspaces for " + repoNode, e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+       }
+
+       public String getRepoPath() {
+               try {
+                       return repoNode.getPath();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get path for " + repoNode, e);
+               }
+       }
+
+       public Repository getRepository() {
+               connect();
+               return repository;
+       }
+
+       public Credentials getCredentials() {
+               return credentials;
+       }
+
+       public Node getRepoNode() {
+               return repoNode;
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..e4562ee
--- /dev/null
@@ -0,0 +1,70 @@
+package org.argeo.slc.client.ui.dist.model;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+
+/** Abstracts a workspace that contains a given distribution */
+public class WorkspaceElem extends TreeParent {
+       private final RepoElem repoElem;
+       private final Node workspaceNode;
+
+       /**
+        * Helper to display only version when the workspace name is well formatted
+        */
+       private static String formatName(Node workspaceNode) {
+               String name = JcrUtils.getNameQuietly(workspaceNode);
+               if (name != null && name.lastIndexOf('-') > 0)
+                       return name.substring(name.lastIndexOf('-') + 1);
+               else
+                       return name;
+       }
+
+       public WorkspaceElem(RepoElem repoElem, Node workspaceNode) {
+               super(formatName(workspaceNode));
+               this.repoElem = repoElem;
+               this.workspaceNode = workspaceNode;
+       }
+
+       public Node getWorkspaceNode() {
+               return workspaceNode;
+       }
+
+       public String getWorkspaceName() {
+               return JcrUtils.getNameQuietly(workspaceNode);
+       }
+
+       public String getWorkspacePath() {
+               try {
+                       return workspaceNode.getPath();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get or add workspace path "
+                                       + getWorkspaceName(), e);
+               }
+       }
+
+       public String getRepoPath() {
+               try {
+                       return workspaceNode.getParent().getPath();
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get or add workspace path "
+                                       + getWorkspaceName(), e);
+               }
+       }
+
+       public RepoElem getRepoElem() {
+               return repoElem;
+       }
+
+       public Credentials getCredentials() {
+               return repoElem.getCredentials();
+       }
+
+       public boolean isReadOnly() {
+               return repoElem.isReadOnly();
+       }
+}
diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistSessionFactory.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistSessionFactory.java
new file mode 100644 (file)
index 0000000..b8f2c75
--- /dev/null
@@ -0,0 +1,87 @@
+package org.argeo.slc.client.ui.dist.providers;
+
+import javax.jcr.Credentials;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.RepoUtils;
+import org.argeo.util.security.Keyring;
+
+/**
+ * Provides shortcut to retrieve sessions, repositories and workspaces that are
+ * persisted in the current user node using path only.
+ */
+public class DistSessionFactory {
+
+       /* DEPENDENCY INJECTION */
+       private RepositoryFactory repositoryFactory;
+       private Keyring keyring;
+       private Repository nodeRepository;
+
+       /**
+        * Returns a new session on the given workspace. This session *must* be
+        * disposed by the caller. If the workspace does not exist and
+        * createIfNeeded==true, tries to create it
+        * 
+        * */
+       public Session getSessionFromWorkspacePath(String path,
+                       boolean createIfNeeded) {
+               Session nodeSession = null;
+               try {
+                       nodeSession = nodeRepository.login();
+                       Node localWksp = nodeSession.getNode(path);
+                       Repository repository = RepoUtils.getRepository(repositoryFactory,
+                                       keyring, localWksp.getParent());
+                       Credentials credentials = RepoUtils.getRepositoryCredentials(
+                                       keyring, localWksp.getParent());
+
+                       String wkspName = JcrUtils.lastPathElement(path);
+                       Session session = null;
+                       try {
+                               session = repository.login(credentials, wkspName);
+                       } catch (NoSuchWorkspaceException e) {
+                               if (createIfNeeded) {
+                                       Session defaultSession = repository.login(credentials);
+                                       try {
+                                               defaultSession.getWorkspace().createWorkspace(wkspName);
+                                       } catch (Exception e1) {
+                                               throw new SlcException("Cannot create new workspace "
+                                                               + wkspName, e);
+                                       } finally {
+                                               JcrUtils.logoutQuietly(defaultSession);
+                                       }
+                                       session = repository.login(credentials, wkspName);
+                               } else
+                                       throw new SlcException("Workspace" + wkspName
+                                                       + "does not exists and should not be created", e);
+                       }
+                       return session;
+               } catch (RepositoryException e) {
+                       throw new SlcException("cannot create session" + " for workspace "
+                                       + path, e);
+               } finally {
+                       JcrUtils.logoutQuietly(nodeSession);
+               }
+       }
+
+       /*
+        * DEPENDENCY INJECTION
+        */
+       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+               this.repositoryFactory = repositoryFactory;
+       }
+
+       public void setKeyring(Keyring keyring) {
+               this.keyring = keyring;
+       }
+
+       public void setRepository(Repository nodeRepository) {
+               this.nodeRepository = nodeRepository;
+       }
+}
\ 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/providers/DistTreeContentProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeContentProvider.java
new file mode 100644 (file)
index 0000000..e1f06c2
--- /dev/null
@@ -0,0 +1,150 @@
+package org.argeo.slc.client.ui.dist.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+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.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.ui.dist.model.DistParentElem;
+import org.argeo.slc.client.ui.dist.model.RepoElem;
+import org.argeo.slc.client.ui.dist.model.WorkspaceElem;
+import org.argeo.slc.repo.RepoConstants;
+import org.argeo.util.security.Keyring;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Enables browsing in local and remote slc distribution repositories. Keyring
+ * and repository factory must be injected
+ */
+public class DistTreeContentProvider implements ITreeContentProvider {
+       private Session nodeSession;
+       List<RepoElem> repositories = new ArrayList<RepoElem>();
+
+       private RepositoryFactory repositoryFactory;
+       private Keyring keyring;
+
+       public Object[] getElements(Object input) {
+               Repository nodeRepository = (Repository) input;
+               try {
+                       if (nodeSession != null)
+                               dispose();
+                       nodeSession = nodeRepository.login();
+
+                       String reposPath = UserJcrUtils.getUserHome(nodeSession).getPath()
+                                       + RepoConstants.REPOSITORIES_BASE_PATH;
+
+                       if (!nodeSession.itemExists(reposPath))
+                               initializeModel(nodeSession);
+
+                       NodeIterator repos = nodeSession.getNode(reposPath).getNodes();
+                       while (repos.hasNext()) {
+                               Node repoNode = repos.nextNode();
+                               if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
+                                       if (RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS
+                                                       .equals(repoNode.getName()))
+                                               repositories.add(new RepoElem(repoNode,
+                                                               repositoryFactory, keyring, true, false));
+                                       else if (repoNode.hasNode(ArgeoNames.ARGEO_PASSWORD))
+                                               repositories.add(new RepoElem(repoNode,
+                                                               repositoryFactory, keyring));
+                                       else
+                                               repositories.add(new RepoElem(repoNode,
+                                                               repositoryFactory, keyring, false, true));
+                               }
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot get base elements", e);
+               }
+               return repositories.toArray();
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+
+       public Object[] getChildren(Object parentElement) {
+               if (parentElement instanceof DistParentElem) {
+                       return ((DistParentElem) parentElement).getChildren();
+               } else if (parentElement instanceof WorkspaceElem) {
+                       return ((WorkspaceElem) parentElement).getChildren();
+               }
+               return null;
+       }
+
+       public Object getParent(Object element) {
+               // TODO register repo elem in distribution elem?
+               return null;
+       }
+
+       public boolean hasChildren(Object element) {
+               if (element instanceof DistParentElem) {
+                       return true;
+               } else if (element instanceof WorkspaceElem) {
+                       return false;
+               }
+               return false;
+       }
+
+       public void dispose() {
+               for (RepoElem repoElem : repositories)
+                       repoElem.dispose();
+               repositories = new ArrayList<RepoElem>();
+               JcrUtils.logoutQuietly(nodeSession);
+       }
+
+       private void initializeModel(Session nodeSession) {
+               try {
+
+                       Node homeNode = UserJcrUtils.getUserHome(nodeSession);
+                       if (homeNode == null) // anonymous
+                               throw new SlcException("User must be authenticated.");
+
+                       // make sure base directory is available
+                       Node repos = JcrUtils.mkdirs(nodeSession, homeNode.getPath()
+                                       + RepoConstants.REPOSITORIES_BASE_PATH);
+                       nodeSession.save();
+
+                       // register default local java repository
+                       String alias = RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS;
+                       Repository javaRepository = ArgeoJcrUtils.getRepositoryByAlias(
+                                       repositoryFactory, alias);
+                       if (javaRepository != null) {
+                               if (!repos.hasNode(alias)) {
+                                       Node repoNode = repos.addNode(alias,
+                                                       ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
+                                       repoNode.setProperty(ArgeoNames.ARGEO_URI, "vm:///" + alias);
+                                       repoNode.addMixin(NodeType.MIX_TITLE);
+                                       repoNode.setProperty(Property.JCR_TITLE,
+                                                       RepoConstants.DEFAULT_JAVA_REPOSITORY_LABEL);
+                                       nodeSession.save();
+                               }
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot initialize model", e);
+               }
+       }
+
+       /*
+        * DEPENDENCY INJECTION
+        */
+       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+               this.repositoryFactory = repositoryFactory;
+       }
+
+       public void setKeyring(Keyring keyring) {
+               this.keyring = keyring;
+       }
+}
\ 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/providers/DistTreeLabelProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeLabelProvider.java
new file mode 100644 (file)
index 0000000..de34e2a
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.slc.client.ui.dist.providers;
+
+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.GroupElem;
+import org.argeo.slc.client.ui.dist.model.RepoElem;
+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
+ */
+public class DistTreeLabelProvider extends ColumnLabelProvider {
+       @Override
+       public String getText(Object element) {
+               if (element instanceof DistParentElem)
+                       return ((DistParentElem) element).getLabel();
+               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 GroupElem) {
+                               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;
+       }
+}
\ No newline at end of file
index ed1848fc3f27b4384693a70b58eb5b7d4f246502..218e613faa40808e7eddbaa20261ff96c9e5286e 100644 (file)
  */
 package org.argeo.slc.client.ui.dist.views;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import javax.jcr.Credentials;
-import javax.jcr.NoSuchWorkspaceException;
 import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-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 javax.jcr.query.Query;
 import javax.jcr.query.QueryResult;
 
@@ -39,13 +32,8 @@ import org.argeo.ArgeoMonitor;
 import org.argeo.eclipse.ui.EclipseArgeoMonitor;
 import org.argeo.eclipse.ui.ErrorFeedback;
 import org.argeo.eclipse.ui.TreeParent;
-import org.argeo.jcr.ArgeoJcrUtils;
 import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
 import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.slc.SlcException;
-import org.argeo.slc.client.ui.dist.DistImages;
 import org.argeo.slc.client.ui.dist.DistPlugin;
 import org.argeo.slc.client.ui.dist.commands.CopyWorkspace;
 import org.argeo.slc.client.ui.dist.commands.CreateWorkspace;
@@ -58,12 +46,15 @@ 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.editors.DistributionEditor;
 import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput;
+import org.argeo.slc.client.ui.dist.model.DistParentElem;
+import org.argeo.slc.client.ui.dist.model.GroupElem;
+import org.argeo.slc.client.ui.dist.model.RepoElem;
+import org.argeo.slc.client.ui.dist.model.WorkspaceElem;
+import org.argeo.slc.client.ui.dist.providers.DistTreeContentProvider;
+import org.argeo.slc.client.ui.dist.providers.DistTreeLabelProvider;
 import org.argeo.slc.client.ui.dist.utils.ArtifactNamesComparator;
 import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
 import org.argeo.slc.jcr.SlcNames;
-import org.argeo.slc.repo.RepoConstants;
-import org.argeo.slc.repo.RepoUtils;
-import org.argeo.util.security.Keyring;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
@@ -72,11 +63,9 @@ import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.TreeViewerColumn;
 import org.eclipse.jface.viewers.Viewer;
@@ -88,7 +77,6 @@ import org.eclipse.swt.dnd.DragSourceEvent;
 import org.eclipse.swt.dnd.TextTransfer;
 import org.eclipse.swt.dnd.Transfer;
 import org.eclipse.swt.dnd.TransferData;
-import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Tree;
@@ -104,9 +92,9 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
        private final static Log log = LogFactory.getLog(DistributionsView.class);
        public final static String ID = DistPlugin.ID + ".distributionsView";
 
+       /* DEPENDENCY INJECTION */
        private Repository nodeRepository;
-       private RepositoryFactory repositoryFactory;
-       private Keyring keyring;
+       private DistTreeContentProvider treeContentProvider;
 
        private TreeViewer viewer;
 
@@ -118,13 +106,14 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
 
                TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.NONE);
                col.getColumn().setWidth(400);
-               col.setLabelProvider(new DistributionLabelProvider());
+               col.setLabelProvider(new DistTreeLabelProvider());
 
                final Tree tree = viewer.getTree();
                tree.setHeaderVisible(false);
                tree.setLinesVisible(false);
 
-               viewer.setContentProvider(new DistributionsContentProvider());
+               // viewer.setContentProvider(new DistTreeContentProvider());
+               viewer.setContentProvider(treeContentProvider);
                viewer.addDoubleClickListener(new DistributionsDCL());
                viewer.setComparator(new BrowserElementComparator());
 
@@ -147,42 +136,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                viewer.getTree().setMenu(menu);
                getSite().registerContextMenu(menuManager, viewer);
 
-               Session nodeSession = null;
-               try {
-                       nodeSession = nodeRepository.login();
-
-                       Node homeNode = UserJcrUtils.getUserHome(nodeSession);
-                       if (homeNode == null) // anonymous
-                               throw new SlcException("User must be authenticated.");
-
-                       // make sure base directory is available
-                       Node repos = JcrUtils.mkdirs(nodeSession, homeNode.getPath()
-                                       + RepoConstants.REPOSITORIES_BASE_PATH);
-                       nodeSession.save();
-
-                       // register default local java repository
-                       String alias = RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS;
-                       Repository javaRepository = ArgeoJcrUtils.getRepositoryByAlias(
-                                       repositoryFactory, alias);
-                       if (javaRepository != null) {
-                               if (!repos.hasNode(alias)) {
-                                       Node repoNode = repos.addNode(alias,
-                                                       ArgeoTypes.ARGEO_REMOTE_REPOSITORY);
-                                       repoNode.setProperty(ARGEO_URI, "vm:///" + alias);
-                                       repoNode.addMixin(NodeType.MIX_TITLE);
-                                       repoNode.setProperty(Property.JCR_TITLE,
-                                                       RepoConstants.DEFAULT_JAVA_REPOSITORY_LABEL);
-                                       nodeSession.save();
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot register repository", e);
-               } finally {
-                       JcrUtils.logoutQuietly(nodeSession);
-               }
-
-               viewer.setInput(nodeRepository);
-               viewer.expandToLevel(2);
+               // Initialize
+               refresh();
        }
 
        /** Programatically configure the context menu */
@@ -198,25 +153,25 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                                .getFirstElement();
 
                if (firstElement instanceof TreeParent
-                               || firstElement instanceof BrowserElem) {
+                               || firstElement instanceof DistParentElem) {
                        String targetRepoPath = null;
 
                        // Build conditions depending on element type
                        boolean isDistribElem = false, isRepoElem = false, isDistribGroupElem = false;
                        boolean isHomeRepo = false, isReadOnly = true;
 
-                       if (firstElement instanceof DistributionElem) {
-                               DistributionElem de = (DistributionElem) firstElement;
+                       if (firstElement instanceof WorkspaceElem) {
+                               WorkspaceElem de = (WorkspaceElem) firstElement;
                                isDistribElem = true;
                                isReadOnly = de.isReadOnly();
                        } else if (firstElement instanceof RepoElem) {
                                RepoElem re = (RepoElem) firstElement;
                                isRepoElem = true;
                                targetRepoPath = re.getRepoPath();
-                               isHomeRepo = re.isHomeRepo();
+                               isHomeRepo = re.inHome();
                                isReadOnly = re.isReadOnly();
-                       } else if (firstElement instanceof DistribGroupElem) {
-                               DistribGroupElem dge = (DistribGroupElem) firstElement;
+                       } else if (firstElement instanceof GroupElem) {
+                               GroupElem dge = (GroupElem) firstElement;
                                isReadOnly = dge.isReadOnly();
                                isDistribGroupElem = true;
                        }
@@ -333,8 +288,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                        dvse.repoNode = re.getRepoNode();
                        dvse.credentials = re.getCredentials();
                        dvse.repositoryDescription = getRepositoryDescription(re);
-               } else if (obj instanceof DistribGroupElem) {
-                       DistribGroupElem dge = (DistribGroupElem) obj;
+               } else if (obj instanceof GroupElem) {
+                       GroupElem dge = (GroupElem) obj;
                        dvse.isWorkspaceGroup = true;
                        dvse.isReadOnly = dge.isReadOnly();
                        dvse.repository = dge.getRepoElem().getRepository();
@@ -343,8 +298,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                        dvse.wkspPrefix = dge.getLabel();
                        dvse.repositoryDescription = getRepositoryDescription(dge
                                        .getRepoElem());
-               } else if (obj instanceof DistributionElem) {
-                       DistributionElem de = (DistributionElem) obj;
+               } else if (obj instanceof WorkspaceElem) {
+                       WorkspaceElem de = (WorkspaceElem) obj;
                        dvse.isWorkspace = true;
                        dvse.isReadOnly = de.isReadOnly();
                        dvse.repository = de.getRepoElem().getRepository();
@@ -375,113 +330,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
         * Force refresh of the whole view
         */
        public void refresh() {
-               viewer.setContentProvider(new DistributionsContentProvider());
-       }
-
-       /*
-        * UI MODEL
-        */
-       private class DistributionLabelProvider extends ColumnLabelProvider {
-               @Override
-               public String getText(Object element) {
-                       if (element instanceof BrowserElem)
-                               return ((BrowserElem) element).getLabel();
-                       else
-                               return element.toString();
-               }
-
-               @Override
-               public Image getImage(Object element) {
-                       if (element instanceof BrowserElem) {
-                               BrowserElem bElement = (BrowserElem) element;
-                               if (bElement instanceof RepoElem) {
-                                       if (bElement.isHomeRepo())
-                                               return DistImages.IMG_HOME_REPO;
-                                       else if (bElement.isReadOnly())
-                                               return DistImages.IMG_REPO_READONLY;
-                                       else
-                                               return DistImages.IMG_REPO;
-
-                               } else if (bElement instanceof DistribGroupElem) {
-                                       return DistImages.IMG_WKSP;
-                               }
-                       } else if (element instanceof DistributionElem)
-                               if (((DistributionElem) element).isReadOnly())
-                                       return DistImages.IMG_DISTGRP_READONLY;
-                               else
-                                       return DistImages.IMG_DISTGRP;
-
-                       return null;
-               }
-       }
-
-       /** Content provider */
-       private class DistributionsContentProvider implements ITreeContentProvider {
-               Session nodeSession;
-               List<RepoElem> repositories = new ArrayList<RepoElem>();
-
-               public Object[] getElements(Object input) {
-                       Repository nodeRepository = (Repository) input;
-                       try {
-                               if (nodeSession != null)
-                                       dispose();
-                               nodeSession = nodeRepository.login();
-
-                               String reposPath = UserJcrUtils.getUserHome(nodeSession)
-                                               .getPath() + RepoConstants.REPOSITORIES_BASE_PATH;
-                               NodeIterator repos = nodeSession.getNode(reposPath).getNodes();
-                               while (repos.hasNext()) {
-                                       Node repoNode = repos.nextNode();
-                                       if (repoNode.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY)) {
-                                               if (RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS
-                                                               .equals(repoNode.getName()))
-                                                       repositories
-                                                                       .add(new RepoElem(repoNode, true, false));
-                                               else if (repoNode.hasNode(ARGEO_PASSWORD))
-                                                       repositories.add(new RepoElem(repoNode));
-                                               else
-                                                       repositories
-                                                                       .add(new RepoElem(repoNode, false, true));
-                                       }
-                               }
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot get base elements", e);
-                       }
-                       return repositories.toArray();
-               }
-
-               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-               }
-
-               public Object[] getChildren(Object parentElement) {
-                       if (parentElement instanceof BrowserElem) {
-                               return ((BrowserElem) parentElement).getChildren();
-                       } else if (parentElement instanceof DistributionElem) {
-                               return ((DistributionElem) parentElement).getChildren();
-                       }
-                       return null;
-               }
-
-               public Object getParent(Object element) {
-                       // TODO register repo elem in distribution elem?
-                       return null;
-               }
-
-               public boolean hasChildren(Object element) {
-                       if (element instanceof BrowserElem) {
-                               return true;
-                       } else if (element instanceof DistributionElem) {
-                               return false;
-                       }
-                       return false;
-               }
-
-               public void dispose() {
-                       for (RepoElem repoElem : repositories)
-                               repoElem.dispose();
-                       repositories = new ArrayList<RepoElem>();
-                       JcrUtils.logoutQuietly(nodeSession);
-               }
+               viewer.setInput(nodeRepository);
+               viewer.expandToLevel(2);
        }
 
        /** Add some view specific behaviours to the comparator */
@@ -489,8 +339,7 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                @Override
                public int category(Object element) {
                        // Home repository always first
-                       if (element instanceof RepoElem
-                                       && ((RepoElem) element).isHomeRepo())
+                       if (element instanceof RepoElem && ((RepoElem) element).inHome())
                                return 2;
                        else
                                return super.category(element);
@@ -499,7 +348,7 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                @Override
                public int compare(Viewer viewer, Object e1, Object e2) {
                        // reverse order for versions
-                       if (e1 instanceof DistributionElem)
+                       if (e1 instanceof WorkspaceElem)
                                return -super.compare(viewer, e1, e2);
                        else
                                return super.compare(viewer, e1, e2);
@@ -507,264 +356,16 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
        }
 
        /** Abstract class to simplify UI conditions build */
-       abstract class BrowserElem {
-               private boolean isHomeRepo = false;
-               private boolean isReadOnly = false;
-
-               public BrowserElem(boolean isHomeRepo, boolean isReadOnly) {
-                       this.isHomeRepo = isHomeRepo;
-                       this.isReadOnly = isReadOnly;
-               }
-
-               public BrowserElem() {
-               }
-
-               public abstract String getLabel();
-
-               public abstract Object[] getChildren();
-
-               public void dispose() {
-               }
-
-               public boolean isHomeRepo() {
-                       return isHomeRepo;
-               }
-
-               public boolean isReadOnly() {
-                       return isReadOnly;
-               }
-       }
 
        /** A software repository */
-       private class RepoElem extends BrowserElem {
-               private Node repoNode;
-               private Repository repository;
-               private Credentials credentials;
-
-               public RepoElem(Node repoNode, boolean isHomeRepo, boolean isReadOnly) {
-                       super(isHomeRepo, isReadOnly);
-                       this.repoNode = repoNode;
-               }
-
-               public RepoElem(Node repoNode) {
-                       this.repoNode = repoNode;
-               }
-
-               /** Lazily connects to repository */
-               protected void connect() {
-                       if (repository != null)
-                               return;
-                       repository = RepoUtils.getRepository(repositoryFactory, keyring,
-                                       repoNode);
-                       credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode);
-               }
-
-               public String getLabel() {
-                       try {
-                               if (repoNode.isNodeType(NodeType.MIX_TITLE)) {
-                                       return repoNode.getProperty(Property.JCR_TITLE).getString();
-                               } else {
-                                       return repoNode.getName();
-                               }
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot read label of " + repoNode, e);
-                       }
-               }
-
-               public String toString() {
-                       return repoNode.toString();
-               }
-
-               public Object[] getChildren() {
-                       connect();
-                       Session session = null;
-                       try {
-                               session = repository.login(credentials);
-                               String[] workspaceNames = session.getWorkspace()
-                                               .getAccessibleWorkspaceNames();
-                               // List<DistributionElem> distributionElems = new
-                               // ArrayList<DistributionElem>();
-                               Map<String, DistribGroupElem> children = new HashMap<String, DistributionsView.DistribGroupElem>();
-                               for (String workspaceName : workspaceNames) {
-                                       // filter technical workspaces
-                                       // FIXME: rely on a more robust rule than just wksp name
-                                       if (workspaceName.lastIndexOf('-') > 0) {
-                                               String prefix = workspaceName.substring(0,
-                                                               workspaceName.lastIndexOf('-'));
-                                               if (!repoNode.hasNode(workspaceName))
-                                                       repoNode.addNode(workspaceName);
-                                               repoNode.getSession().save();
-                                               if (!children.containsKey(prefix)) {
-                                                       children.put(prefix, new DistribGroupElem(
-                                                                       RepoElem.this, prefix));
-                                               }
-                                               // FIXME remove deleted workspaces
-                                       }
-                               }
-                               return children.values().toArray();
-                       } catch (RepositoryException e) {
-                               throw new SlcException(
-                                               "Cannot list workspaces for " + repoNode, e);
-                       } finally {
-                               JcrUtils.logoutQuietly(session);
-                       }
-               }
-
-               public String getRepoPath() {
-                       try {
-                               return repoNode.getPath();
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot get path for " + repoNode, e);
-                       }
-               }
-
-               public Repository getRepository() {
-                       connect();
-                       return repository;
-               }
-
-               public Credentials getCredentials() {
-                       return credentials;
-               }
-
-               public Node getRepoNode() {
-                       return repoNode;
-               }
-
-       }
-
-       /**
-        * Abstracts a group of distribution, that is a bunch of workspaces with
-        * same prefix.
-        */
-       private class DistribGroupElem extends BrowserElem {
-               private RepoElem repoElem;
-               private String name;
-
-               public DistribGroupElem(RepoElem repoElem, String prefix) {
-                       super(repoElem.isHomeRepo(), repoElem.isReadOnly());
-                       this.repoElem = repoElem;
-                       this.name = prefix;
-               }
-
-               public Object[] getChildren() {
-                       repoElem.connect();
-                       Session session = null;
-                       try {
-                               Repository repository = repoElem.getRepository();
-                               Node repoNode = repoElem.getRepoNode();
-                               session = repository.login(repoElem.getCredentials());
-
-                               String[] workspaceNames = session.getWorkspace()
-                                               .getAccessibleWorkspaceNames();
-                               List<DistributionElem> distributionElems = new ArrayList<DistributionElem>();
-                               for (String workspaceName : workspaceNames) {
-                                       // filter technical workspaces
-                                       if (workspaceName.startsWith(name)) {
-                                               Node workspaceNode = repoNode.hasNode(workspaceName) ? repoNode
-                                                               .getNode(workspaceName) : repoNode
-                                                               .addNode(workspaceName);
-                                               distributionElems.add(new DistributionElem(repoElem,
-                                                               workspaceNode));
-                                               // FIXME remove deleted workspaces
-                                       }
-                               }
-                               return distributionElems.toArray();
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot list workspaces for prefix "
-                                               + name, e);
-                       } finally {
-                               JcrUtils.logoutQuietly(session);
-                       }
-               }
-
-               public String getLabel() {
-                       return name;
-               }
-
-               public String toString() {
-                       return getLabel();
-               }
-
-               public void dispose() {
-               }
-
-               public RepoElem getRepoElem() {
-                       return repoElem;
-               }
-
-       }
-
-       /** Abstracts a distribution, that is a workspace */
-       private static class DistributionElem extends TreeParent {
-               private final RepoElem repoElem;
-               private final Node workspaceNode;
-
-               /**
-                * Helper to display only version when the workspace name is well
-                * formatted
-                */
-               private static String formatName(Node workspaceNode) {
-                       String name = JcrUtils.getNameQuietly(workspaceNode);
-                       if (name != null && name.lastIndexOf('-') > 0)
-                               return name.substring(name.lastIndexOf('-') + 1);
-                       else
-                               return name;
-               }
-
-               public DistributionElem(RepoElem repoElem, Node workspaceNode) {
-                       super(formatName(workspaceNode));
-                       this.repoElem = repoElem;
-                       this.workspaceNode = workspaceNode;
-               }
-
-               public Node getWorkspaceNode() {
-                       return workspaceNode;
-               }
-
-               public String getWorkspaceName() {
-                       return JcrUtils.getNameQuietly(workspaceNode);
-               }
-
-               public String getWorkspacePath() {
-                       try {
-                               return workspaceNode.getPath();
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot get or add workspace path "
-                                               + getWorkspaceName(), e);
-                       }
-               }
-
-               public String getRepoPath() {
-                       try {
-                               return workspaceNode.getParent().getPath();
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot get or add workspace path "
-                                               + getWorkspaceName(), e);
-                       }
-               }
-
-               public RepoElem getRepoElem() {
-                       return repoElem;
-               }
-
-               public Credentials getCredentials() {
-                       return repoElem.getCredentials();
-               }
-
-               public boolean isReadOnly() {
-                       return repoElem.isReadOnly();
-               }
-       }
 
        /** Listens to drag */
        class ViewDragListener extends DragSourceAdapter {
                public void dragSetData(DragSourceEvent event) {
                        IStructuredSelection selection = (IStructuredSelection) viewer
                                        .getSelection();
-                       if (selection.getFirstElement() instanceof DistributionElem) {
-                               DistributionElem de = (DistributionElem) selection
-                                               .getFirstElement();
+                       if (selection.getFirstElement() instanceof WorkspaceElem) {
+                               WorkspaceElem de = (WorkspaceElem) selection.getFirstElement();
                                if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
                                        event.data = de.getWorkspacePath();
                                }
@@ -781,76 +382,79 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
 
                @Override
                public boolean performDrop(Object data) {
-                       DistributionElem sourceDist = (DistributionElem) getSelectedObject();
+                       WorkspaceElem sourceDist = (WorkspaceElem) getSelectedObject();
                        RepoElem targetRepo = (RepoElem) getCurrentTarget();
 
                        Boolean ok = MessageDialog.openConfirm(getSite().getShell(),
-                                       "Confirm distribution merge", "Do you want to merge "
-                                                       + sourceDist.getWorkspaceName() + " (from repo "
+                                       "FIXME: BROKEN BY REFACTORING--Confirm distribution merge",
+                                       "Do you want to merge " + sourceDist.getWorkspaceName()
+                                                       + " (from repo "
                                                        + sourceDist.getRepoElem().getLabel()
                                                        + ") to repo " + targetRepo.getLabel() + "?");
                        if (!ok)
                                return false;
 
-                       try {
-                               String sourceWorkspace = sourceDist.getWorkspaceName();
-                               Repository sourceRepository = RepoUtils.getRepository(
-                                               repositoryFactory, keyring, sourceDist
-                                                               .getWorkspaceNode().getParent());
-                               Credentials sourceCredentials = RepoUtils
-                                               .getRepositoryCredentials(keyring, sourceDist
-                                                               .getWorkspaceNode().getParent());
-
-                               String targetWorkspace = sourceWorkspace;
-                               Repository targetRepository = RepoUtils.getRepository(
-                                               repositoryFactory, keyring, targetRepo.getRepoNode());
-                               Credentials targetCredentials = RepoUtils
-                                               .getRepositoryCredentials(keyring,
-                                                               targetRepo.getRepoNode());
-
-                               // Open sessions here since the background thread
-                               // won't necessarily be authenticated.
-                               // Job should close the sessions.
-                               Session sourceSession = sourceRepository.login(
-                                               sourceCredentials, sourceWorkspace);
-                               Session targetSession;
-                               try {
-                                       targetSession = targetRepository.login(targetCredentials,
-                                                       targetWorkspace);
-                               } catch (NoSuchWorkspaceException e) {
-                                       Session defaultSession = targetRepository
-                                                       .login(targetCredentials);
-                                       try {
-                                               defaultSession.getWorkspace().createWorkspace(
-                                                               targetWorkspace);
-                                       } catch (Exception e1) {
-                                               throw new SlcException("Cannot create new workspace "
-                                                               + targetWorkspace, e);
-                                       } finally {
-                                               JcrUtils.logoutQuietly(defaultSession);
-                                       }
-                                       targetSession = targetRepository.login(targetCredentials,
-                                                       targetWorkspace);
-                               }
-
-                               Job workspaceMergeJob = new WorkspaceMergeJob(sourceSession,
-                                               targetSession);
-                               workspaceMergeJob.setUser(true);
-                               workspaceMergeJob.schedule();
-                               return true;
-                       } catch (RepositoryException e) {
-                               throw new SlcException("Cannot process drop from " + sourceDist
-                                               + " to " + targetRepo, e);
-                       }
+                       // TODO uncomment that
+                       return true;
+                       // try {
+                       // String sourceWorkspace = sourceDist.getWorkspaceName();
+                       // Repository sourceRepository = RepoUtils.getRepository(
+                       // repositoryFactory, keyring, sourceDist
+                       // .getWorkspaceNode().getParent());
+                       // Credentials sourceCredentials = RepoUtils
+                       // .getRepositoryCredentials(keyring, sourceDist
+                       // .getWorkspaceNode().getParent());
+                       //
+                       // String targetWorkspace = sourceWorkspace;
+                       // Repository targetRepository = RepoUtils.getRepository(
+                       // repositoryFactory, keyring, targetRepo.getRepoNode());
+                       // Credentials targetCredentials = RepoUtils
+                       // .getRepositoryCredentials(keyring,
+                       // targetRepo.getRepoNode());
+                       //
+                       // // Open sessions here since the background thread
+                       // // won't necessarily be authenticated.
+                       // // Job should close the sessions.
+                       // Session sourceSession = sourceRepository.login(
+                       // sourceCredentials, sourceWorkspace);
+                       // Session targetSession;
+                       // try {
+                       // targetSession = targetRepository.login(targetCredentials,
+                       // targetWorkspace);
+                       // } catch (NoSuchWorkspaceException e) {
+                       // Session defaultSession = targetRepository
+                       // .login(targetCredentials);
+                       // try {
+                       // defaultSession.getWorkspace().createWorkspace(
+                       // targetWorkspace);
+                       // } catch (Exception e1) {
+                       // throw new SlcException("Cannot create new workspace "
+                       // + targetWorkspace, e);
+                       // } finally {
+                       // JcrUtils.logoutQuietly(defaultSession);
+                       // }
+                       // targetSession = targetRepository.login(targetCredentials,
+                       // targetWorkspace);
+                       // }
+                       //
+                       // Job workspaceMergeJob = new WorkspaceMergeJob(sourceSession,
+                       // targetSession);
+                       // workspaceMergeJob.setUser(true);
+                       // workspaceMergeJob.schedule();
+                       // return true;
+                       // } catch (RepositoryException e) {
+                       // throw new SlcException("Cannot process drop from " + sourceDist
+                       // + " to " + targetRepo, e);
+                       // }
                }
 
                @Override
                public boolean validateDrop(Object target, int operation,
                                TransferData transferType) {
                        if (target instanceof RepoElem) {
-                               if (getSelectedObject() instanceof DistributionElem) {
+                               if (getSelectedObject() instanceof WorkspaceElem) {
                                        // check if not same repository
-                                       String srcRepoPath = ((DistributionElem) getSelectedObject())
+                                       String srcRepoPath = ((WorkspaceElem) getSelectedObject())
                                                        .getRepoPath();
                                        String targetRepoPath = ((RepoElem) target).getRepoPath();
                                        return !targetRepoPath.equals(srcRepoPath);
@@ -917,8 +521,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
                                return;
                        Object obj = ((IStructuredSelection) event.getSelection())
                                        .getFirstElement();
-                       if (obj instanceof DistributionElem) {
-                               DistributionElem distributionElem = (DistributionElem) obj;
+                       if (obj instanceof WorkspaceElem) {
+                               WorkspaceElem distributionElem = (WorkspaceElem) obj;
                                DistributionEditorInput dei = new DistributionEditorInput(
                                                distributionElem.getName(),
                                                getRepositoryDescription(distributionElem.getRepoElem()),
@@ -940,15 +544,12 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames
        /*
         * DEPENDENCY INJECTION
         */
-       public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
-               this.repositoryFactory = repositoryFactory;
-       }
-
-       public void setKeyring(Keyring keyring) {
-               this.keyring = keyring;
-       }
-
        public void setNodeRepository(Repository repository) {
                this.nodeRepository = repository;
        }
+
+       public void setTreeContentProvider(
+                       DistTreeContentProvider treeContentProvider) {
+               this.treeContentProvider = treeContentProvider;
+       }
 }
\ No newline at end of file