From: Bruno Sinou Date: Fri, 15 Mar 2013 01:06:47 +0000 (+0000) Subject: + first draft of anonymous perspective X-Git-Tag: argeo-slc-2.1.7~405 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=0d236262a853a1286b317c30d64d4692bc21c7a4;hp=dc95cc0fdc36c88e778cdfd52d443d0a0b8d926c;p=gpl%2Fargeo-slc.git + first draft of anonymous perspective + clean and refactor model + enhance bundle detail editor, bundle browser & bundle raw detail page + fixe a few bugs git-svn-id: https://svn.argeo.org/slc/trunk@6135 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/demo/slc_demo_rap.properties b/demo/slc_demo_rap.properties index b914693f6..9def0ad04 100644 --- a/demo/slc_demo_rap.properties +++ b/demo/slc_demo_rap.properties @@ -38,6 +38,9 @@ org.argeo.security.ui.initialPerspective=org.argeo.slc.client.ui.dist.anonymousD #spring.security.strategy=MODE_INHERITABLETHREADLOCAL +# anonymous url: http://localhost:7070/ui/public +# authenticated url: http://localhost:7070/ui/node + # LDAP (Apache DS) #argeo.ads.init.ldif=osgibundle:init-argeo.ldif 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 ec6176f1a..ddc3d05af 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 @@ -53,4 +53,36 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/views.xml b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/views.xml index e65fc55ed..e18ed1137 100644 --- a/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/views.xml +++ b/plugins/org.argeo.slc.client.ui.dist/META-INF/spring/views.xml @@ -53,12 +53,26 @@ + + + + + + + + + + diff --git a/plugins/org.argeo.slc.client.ui.dist/plugin.xml b/plugins/org.argeo.slc.client.ui.dist/plugin.xml index 4762d583d..2513bcb31 100644 --- a/plugins/org.argeo.slc.client.ui.dist/plugin.xml +++ b/plugins/org.argeo.slc.client.ui.dist/plugin.xml @@ -20,6 +20,24 @@ + + + + + + - - - - - - - - - - - - - - - @@ -131,8 +116,6 @@ - - + name="Target repo uri"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + repositories = new ArrayList(); + private RepoElem publicRepo; + + private RepositoryFactory repositoryFactory; + + /** + * @param input + * the URI to the public repository to browse + */ + public Object[] getElements(Object input) { + String uri = (String) input; + publicRepo = new RepoElem(repositoryFactory, uri, + "Argeo Public Repository"); + return publicRepo.getChildren(); + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof DistParentElem) { + return ((DistParentElem) parentElement).getChildren(); + } else + return null; + } + + public Object getParent(Object element) { + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof WorkspaceElem) + return false; + else if (element instanceof DistParentElem) + return true; + else + return false; + } + + public void dispose() { + publicRepo.dispose(); + } + + /* + * DEPENDENCY INJECTION + */ + public void setRepositoryFactory(RepositoryFactory repositoryFactory) { + this.repositoryFactory = repositoryFactory; + } +} \ 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/ArtifactLabelProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/ArtifactLabelProvider.java new file mode 100644 index 000000000..c689df8c9 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/ArtifactLabelProvider.java @@ -0,0 +1,109 @@ +/* + * 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.controllers; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.client.ui.dist.DistConstants; +import org.argeo.slc.client.ui.dist.DistImages; +import org.argeo.slc.jcr.SlcTypes; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.graphics.Image; + +public class ArtifactLabelProvider extends ColumnLabelProvider implements + DistConstants, SlcTypes { + + // To be able to change column order easily + public static final int COLUMN_TREE = 0; + public static final int COLUMN_DATE = 1; + public static final int COLUMN_SIZE = 2; + + // Utils + protected static DateFormat timeFormatter = new SimpleDateFormat( + DATE_TIME_FORMAT); + + public void update(ViewerCell cell) { + int colIndex = cell.getColumnIndex(); + Object element = cell.getElement(); + cell.setText(getColumnText(element, colIndex)); + if (element instanceof Node && colIndex == 0) { + Node node = (Node) element; + try { + if (node.isNodeType(SLC_ARTIFACT_BASE)) + cell.setImage(DistImages.IMG_ARTIFACT_BASE); + else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) + cell.setImage(DistImages.IMG_ARTIFACT_VERSION_BASE); + } catch (RepositoryException e) { + // Silent + } + } + } + + @Override + public Image getImage(Object element) { + + if (element instanceof Node) { + Node node = (Node) element; + try { + if (node.isNodeType(SLC_ARTIFACT_BASE)) { + return DistImages.IMG_ARTIFACT_BASE; + } else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) { + return DistImages.IMG_ARTIFACT_VERSION_BASE; + } + } catch (RepositoryException e) { + // Silent + } + } + return null; + } + + public String getColumnText(Object element, int columnIndex) { + try { + if (element instanceof Node) { + Node node = (Node) element; + switch (columnIndex) { + case COLUMN_TREE: + return node.getName(); + case COLUMN_SIZE: + long size = JcrUtils.getNodeApproxSize(node) / 1024; + if (size > 1024) + return size / 1024 + " MB"; + else + return size + " KB"; + case COLUMN_DATE: + if (node.hasProperty(Property.JCR_LAST_MODIFIED)) + return timeFormatter.format(node + .getProperty(Property.JCR_LAST_MODIFIED) + .getDate().getTime()); + else + return null; + } + } + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexepected error while getting property values", re); + } + return null; + } +} diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/ArtifactsTreeContentProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/ArtifactsTreeContentProvider.java new file mode 100644 index 000000000..ef3fef21f --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/ArtifactsTreeContentProvider.java @@ -0,0 +1,104 @@ +/* + * 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.controllers; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; + +import org.argeo.ArgeoException; +import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; +import org.argeo.slc.jcr.SlcTypes; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class ArtifactsTreeContentProvider implements ITreeContentProvider, + SlcTypes { + + // Utils + private boolean sortChildren = true; + private JcrItemsComparator itemComparator = new JcrItemsComparator(); + + public Object[] getElements(Object parent) { + return getChildren(parent); + } + + public Object getParent(Object child) { + return null; + } + + public Object[] getChildren(Object parent) { + Object[] elements = null; + try { + if (parent instanceof Node) { + Node node = (Node) parent; + NodeIterator ni = node.getNodes(); + List nodesList = new ArrayList(); + while (ni.hasNext()) { + nodesList.add(ni.nextNode()); + } + if (sortChildren) { + Node[] arr = (Node[]) nodesList.toArray(new Node[nodesList + .size()]); + Arrays.sort(arr, itemComparator); + return arr; + } else + return nodesList.toArray(); + + } + } catch (RepositoryException e) { + throw new ArgeoException( + "Unexpected exception while listing node properties", e); + } + return elements; + } + + public boolean hasChildren(Object parent) { + try { + if (parent instanceof Node) { + Node curNode = (Node) parent; + // We manually stop digging at this level + if (curNode.isNodeType(SLC_ARTIFACT_VERSION_BASE)) + return false; + else if (curNode.hasNodes()) + return true; + } + } catch (RepositoryException e) { + throw new ArgeoException( + "Unexpected exception while checking if property is multiple", + e); + } + return false; + } + + public void setSortChildren(boolean sortChildren) { + this.sortChildren = sortChildren; + } + + public boolean getSortChildren() { + return sortChildren; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + public void dispose() { + } +} \ 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/DistSessionFactory.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistSessionFactory.java new file mode 100644 index 000000000..0788f5703 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistSessionFactory.java @@ -0,0 +1,87 @@ +package org.argeo.slc.client.ui.dist.controllers; + +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/controllers/DistTreeComparator.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeComparator.java new file mode 100644 index 000000000..5bfbc98a8 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeComparator.java @@ -0,0 +1,52 @@ +package org.argeo.slc.client.ui.dist.controllers; + +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.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; + +/** Specific behaviour to enhence Distribution tree browsers */ +public class DistTreeComparator extends ViewerComparator { + + public int category(Object element) { + if (element instanceof RepoElem) + if (((RepoElem) element).inHome()) + // Home repository always first + return 2; + else + return 5; + else if (element instanceof GroupElem) + return 10; + else if (element instanceof WorkspaceElem) + return 15; + else + return 20; + } + + public int compare(Viewer viewer, Object e1, Object e2) { + int cat1 = category(e1); + int cat2 = category(e2); + + if (cat1 != cat2) { + return cat1 - cat2; + } + + String s1, s2; + + if (e1 instanceof DistParentElem) { + s1 = ((DistParentElem) e1).getLabel(); + s2 = ((DistParentElem) e2).getLabel(); + } else { + s1 = e1.toString(); + s2 = e2.toString(); + } + + if (e1 instanceof WorkspaceElem) + // Reverse order for versions + return s2.compareTo(s1); + else + return s1.compareTo(s2); + } +} \ 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/DistTreeContentProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeContentProvider.java new file mode 100644 index 000000000..61347b5ef --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeContentProvider.java @@ -0,0 +1,141 @@ +package org.argeo.slc.client.ui.dist.controllers; + +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 repositories = new ArrayList(); + + 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)) + repositories.add(new RepoElem(repoNode, repositoryFactory, + keyring)); + } + } 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 WorkspaceElem) + return false; + else if (element instanceof DistParentElem) + return true; + else + return false; + } + + public void dispose() { + for (RepoElem repoElem : repositories) + repoElem.dispose(); + repositories = new ArrayList(); + 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/controllers/DistTreeDoubleClickListener.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java new file mode 100644 index 000000000..45fcfa168 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeDoubleClickListener.java @@ -0,0 +1,37 @@ +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 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; + +/** Listen to double-clicks */ +public class DistTreeDoubleClickListener implements IDoubleClickListener { + + 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); + } + } + } +} \ 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 new file mode 100644 index 000000000..fe45871f7 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/controllers/DistTreeLabelProvider.java @@ -0,0 +1,44 @@ +package org.argeo.slc.client.ui.dist.controllers; + +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 diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/ArtifactsBrowserPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/ArtifactsBrowserPage.java index 9f44f1611..48afaec6c 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/ArtifactsBrowserPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/ArtifactsBrowserPage.java @@ -15,283 +15,275 @@ */ package org.argeo.slc.client.ui.dist.editors; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; import javax.jcr.Node; -import javax.jcr.Property; +import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; +import javax.jcr.query.qom.Ordering; +import javax.jcr.query.qom.QueryObjectModel; +import javax.jcr.query.qom.QueryObjectModelFactory; +import javax.jcr.query.qom.Selector; import org.argeo.ArgeoException; import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; import org.argeo.slc.client.ui.dist.DistConstants; import org.argeo.slc.client.ui.dist.DistImages; -import org.argeo.slc.client.ui.dist.providers.ArtifactsTreeContentProvider; -import org.argeo.slc.client.ui.dist.utils.GenericDoubleClickListener; +import org.argeo.slc.client.ui.dist.DistPlugin; +import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; import org.argeo.slc.repo.RepoConstants; import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.widgets.ScrolledForm; /** - * Basic View to browse a maven based repository. - * - * By Default size of the various bundles is not computed but it can be - * activated the view command. + * Exposes the various group id of a distribution as a tree. */ public class ArtifactsBrowserPage extends FormPage implements DistConstants, RepoConstants { + final static String PAGE_ID = "artifactsBrowserPage"; // private final static Log log = LogFactory // .getLog(ArtifactsBrowserPage.class); - /* DEPENDENCY INJECTION */ - private Session jcrSession; - - // Business objects - private Node rootNode; + // Business object + private Session session; // This page widgets private TreeViewer artifactTreeViewer; - private boolean isSizeVisible = false; - - // To be able to configure columns easily - public static final int COLUMN_TREE = 0; - public static final int COLUMN_DATE = 1; - public static final int COLUMN_SIZE = 2; - private static final int SIZE_COL_WIDTH = 55; public ArtifactsBrowserPage(FormEditor editor, String title, Session session) { super(editor, PAGE_ID, title); - this.jcrSession = session; + this.session = session; } @Override protected void createFormContent(IManagedForm managedForm) { - ScrolledForm form = managedForm.getForm(); - Composite parent = form.getBody(); - // Enable the different parts to fill the whole page when the tab is - // maximized - parent.setLayout(new FillLayout()); - artifactTreeViewer = createArtifactsTreeViewer(parent); - - // context menu : it is completely defined in the plugin.xml file. - // Nothing in the context menu for the time being - // MenuManager menuManager = new MenuManager(); - // Menu menu = - // menuManager.createContextMenu(artifactTreeViewer.getTree()); - // artifactTreeViewer.getTree().setMenu(menu); - // getSite().registerContextMenu(menuManager, artifactTreeViewer); - - getEditor().getSite().setSelectionProvider(artifactTreeViewer); - - // packagesViewer.setComparer(new NodeViewerComparer()); - - // Model initialisation - if (jcrSession != null) { - try { - DistributionEditorInput dei = (DistributionEditorInput) getEditorInput(); - if (dei.getArtifactsBase().equals(DEFAULT_ARTIFACTS_BASE_PATH)) { - rootNode = jcrSession.getRootNode(); - } else { - rootNode = jcrSession.getNode(dei.getArtifactsBase()); - } - artifactTreeViewer.setInput(rootNode); - } catch (RepositoryException e) { - throw new ArgeoException("Cannot load base artifact nodes", e); - } + try { + ScrolledForm form = managedForm.getForm(); + Composite parent = form.getBody(); + // Enable the different parts to fill the whole page when the tab is + // maximized + parent.setLayout(new FillLayout()); + createExportPackageSection(parent); + getEditor().getSite().setSelectionProvider(artifactTreeViewer); + } catch (RepositoryException e) { + throw new SlcException("Cannot create artifact browser page", e); } } - protected TreeViewer createArtifactsTreeViewer(Composite parent) { - int style = SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION; - Tree tree = new Tree(parent, style); - createColumn(tree, "Artifacts", SWT.LEFT, 300); - createColumn(tree, "Date created", SWT.LEFT, 105); - createColumn(tree, "Size", SWT.RIGHT, 0); - tree.setLinesVisible(true); - tree.setHeaderVisible(true); + private NodeIterator listNodes(String nodeType, String orderBy) + throws RepositoryException { + QueryManager queryManager = session.getWorkspace().getQueryManager(); + QueryObjectModelFactory factory = queryManager.getQOMFactory(); - TreeViewer viewer = new TreeViewer(tree); + final String nodeSelector = "nodes"; + Selector source = factory.selector(nodeType, nodeSelector); - viewer.setContentProvider(new ArtifactsTreeContentProvider()); - viewer.setLabelProvider(new ArtifactLabelProvider()); - viewer.addSelectionChangedListener(new ArtifactTreeSelectionListener()); - viewer.addDoubleClickListener(new GenericDoubleClickListener()); - viewer.setInput(rootNode); + Ordering order = factory.ascending(factory.propertyValue(nodeSelector, + orderBy)); + Ordering[] orderings = { order }; - return viewer; - } + QueryObjectModel query = factory.createQuery(source, null, orderings, + null); - private static TreeColumn createColumn(Tree parent, String name, int style, - int width) { - TreeColumn result = new TreeColumn(parent, style); - result.setText(name); - result.setWidth(width); - result.setMoveable(true); - result.setResizable(true); - return result; - } + QueryResult result = query.execute(); - protected TreeViewer getArtifactTreeViewer() { - return artifactTreeViewer; + return result.getNodes(); } - /** - * Refresh the given element of the tree browser. If null is passed as a - * parameter, it refreshes the whole tree - */ - public void refresh(Object element) { - if (element == null) { - artifactTreeViewer.refresh(rootNode); - } else - artifactTreeViewer.refresh(element); - } + /** Export Package Section */ + private void createExportPackageSection(Composite parent) + throws RepositoryException { - /** Returns wether size column is visible or not */ - public boolean isSizeVisible() { - return isSizeVisible; - } - - /** Sets the visibility of the size column */ - public void setSizeVisible(boolean visible) { - if (isSizeVisible == visible) - return; // nothing has changed - else - isSizeVisible = visible; - - if (visible) { - artifactTreeViewer.getTree().getColumn(COLUMN_SIZE) - .setWidth(SIZE_COL_WIDTH); - } else { - // we just hide the column, we don't refresh the whole tree. - artifactTreeViewer.getTree().getColumn(COLUMN_SIZE).setWidth(0); - } - } - - private class ArtifactLabelProvider extends ColumnLabelProvider implements - DistConstants, SlcTypes { - - // Utils - protected DateFormat timeFormatter = new SimpleDateFormat( - DATE_TIME_FORMAT); + int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.BORDER; + Tree tree = new Tree(parent, style); + createColumn(tree, "Artifacts", SWT.LEFT, 300); + tree.setLinesVisible(true); + tree.setHeaderVisible(true); - public void update(ViewerCell cell) { - int colIndex = cell.getColumnIndex(); - Object element = cell.getElement(); - cell.setText(getColumnText(element, colIndex)); + artifactTreeViewer = new TreeViewer(tree); - if (element instanceof Node && colIndex == 0) { + artifactTreeViewer.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { Node node = (Node) element; try { - if (node.isNodeType(SLC_ARTIFACT_BASE)) - cell.setImage(DistImages.IMG_ARTIFACT_BASE); - else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) - cell.setImage(DistImages.IMG_ARTIFACT_VERSION_BASE); + if (node.isNodeType(SlcTypes.SLC_GROUP_BASE)) + return JcrUtils.get((Node) element, + SlcNames.SLC_GROUP_BASE_ID); + else if (node.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) + return JcrUtils.get((Node) element, + SlcNames.SLC_ARTIFACT_ID); + else + return node.getName(); } catch (RepositoryException e) { - // Silent + throw new SlcException("Cannot browse artifacts", e); } } - } - - @Override - public Image getImage(Object element) { - if (element instanceof Node) { + @Override + public Image getImage(Object element) { Node node = (Node) element; try { - if (node.isNodeType(SLC_ARTIFACT_BASE)) { + + if (node.isNodeType(SlcTypes.SLC_GROUP_BASE)) + return DistImages.IMG_WKSP; + else if (node.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) return DistImages.IMG_ARTIFACT_BASE; - } else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) { + else if (node + .isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) return DistImages.IMG_ARTIFACT_VERSION_BASE; - } + else + return null; } catch (RepositoryException e) { - // Silent + throw new SlcException("Cannot get images for artifacts", e); } } - return null; - } + }); - public String getColumnText(Object element, int columnIndex) { - try { - if (element instanceof Node) { - Node node = (Node) element; - switch (columnIndex) { - case COLUMN_TREE: - return node.getName(); - case COLUMN_SIZE: - if (isSizeVisible) { - long size = JcrUtils.getNodeApproxSize(node) / 1024; - if (size > 1024) - return size / 1024 + " MB"; - else - return size + " KB"; - } else - return ""; - case COLUMN_DATE: - if (node.hasProperty(Property.JCR_CREATED)) - return timeFormatter.format(node - .getProperty(Property.JCR_CREATED) - .getDate().getTime()); - else - return null; + artifactTreeViewer.setContentProvider(new ITreeContentProvider() { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public Object[] getElements(Object inputElement) { + try { + List nodes = JcrUtils.nodeIteratorToList(listNodes( + SlcTypes.SLC_GROUP_BASE, SlcNames.SLC_NAME)); + return nodes.toArray(); + } catch (RepositoryException e) { + throw new SlcException("Cannot list children Nodes", e); + } + } + + public Object[] getChildren(Object parentElement) { + // Only 3 levels for the time being + try { + Node pNode = (Node) parentElement; + if (pNode.isNodeType(SlcTypes.SLC_GROUP_BASE)) { + return getArtifactBase(pNode, + SlcTypes.SLC_ARTIFACT_BASE); + } else if (pNode.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) { + return getArtifactBase(pNode, + SlcTypes.SLC_ARTIFACT_VERSION_BASE); } + return null; + } catch (RepositoryException e) { + throw new SlcException("Cannot list children Nodes", e); } - } catch (RepositoryException re) { - throw new ArgeoException( - "Unexepected error while getting property values", re); } - return null; - } - // private String formatValueAsString(Value value) { - // // TODO enhance this method - // try { - // String strValue; - // - // if (value.getType() == PropertyType.BINARY) - // strValue = ""; - // else if (value.getType() == PropertyType.DATE) - // strValue = timeFormatter.format(value.getDate().getTime()); - // else - // strValue = value.getString(); - // return strValue; - // } catch (RepositoryException e) { - // throw new ArgeoException( - // "unexpected error while formatting value", e); - // } - // } - } + // Helper to get children because current version of Jackrabbit is + // buggy in remote + private Object[] getArtifactBase(Node parent, String nodeType) + throws RepositoryException { + List nodes = new ArrayList(); + NodeIterator ni = parent.getNodes(); + while (ni.hasNext()) { + Node node = ni.nextNode(); + if (node.isNodeType(nodeType)) + nodes.add(node); + } + return nodes.toArray(); + } - private class ArtifactTreeSelectionListener implements - ISelectionChangedListener { + public Object getParent(Object element) { + return null; + } - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection != null && selection instanceof IStructuredSelection) { - IStructuredSelection iss = (IStructuredSelection) selection; - if (iss.size() == 1) { - artifactTreeViewer.refresh(iss.getFirstElement()); + public boolean hasChildren(Object element) { + try { + Node pNode = (Node) element; + if (pNode.isNodeType(SlcTypes.SLC_GROUP_BASE) + || pNode.isNodeType(SlcTypes.SLC_ARTIFACT_BASE)) { + // might return true even if there is no "valid" child + return pNode.hasNodes(); + } else + return false; + } catch (RepositoryException e) { + throw new SlcException("Cannot check children Nodes", e); } } + }); + + artifactTreeViewer.addDoubleClickListener(new DoubleClickListener()); + artifactTreeViewer.setInput("Initialize"); + } + + private class DoubleClickListener implements IDoubleClickListener { + + public void doubleClick(DoubleClickEvent event) { + Object obj = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + try { + if (obj instanceof Node) { + Node node = (Node) obj; + if (node.isNodeType(SlcTypes.SLC_ARTIFACT_VERSION_BASE)) { + // TODO fix using QOM after jcr upgrade + NodeIterator ni = node.getNodes(); + while (ni.hasNext()) { + Node curr = ni.nextNode(); + if (curr.isNodeType(SlcTypes.SLC_BUNDLE_ARTIFACT)) { + GenericBundleEditorInput gaei = new GenericBundleEditorInput( + curr); + DistPlugin + .getDefault() + .getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .openEditor(gaei, + GenericBundleEditor.ID); + } + } + } + } + } catch (RepositoryException re) { + throw new ArgeoException( + "Repository error while getting node info", re); + } catch (PartInitException pie) { + throw new ArgeoException( + "Unexepected exception while opening artifact editor", + pie); + } } + } + private static TreeColumn createColumn(Tree parent, String name, int style, + int width) { + TreeColumn result = new TreeColumn(parent, style); + result.setText(name); + result.setWidth(width); + result.setMoveable(true); + result.setResizable(true); + return result; } + } diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailsPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailsPage.java index 4e67d5f4e..052301a00 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailsPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleDetailsPage.java @@ -136,7 +136,7 @@ public class BundleDetailsPage extends FormPage implements SlcNames, SlcTypes { tree.setLayoutData(gd); TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.FILL); - col.getColumn().setWidth(200); + col.getColumn().setWidth(400); col.setLabelProvider(new ColumnLabelProvider() { @Override @@ -208,6 +208,9 @@ public class BundleDetailsPage extends FormPage implements SlcNames, SlcTypes { headerSection.setClient(tree); viewer.setInput("Initialize"); + // work around a display problem : the tree table has only a few lines + // when the tree is not expended + viewer.expandToLevel(2); } /** Import Package Section */ @@ -221,7 +224,7 @@ public class BundleDetailsPage extends FormPage implements SlcNames, SlcTypes { // Name TableViewerColumn col = new TableViewerColumn(viewer, SWT.NONE); - col.getColumn().setWidth(300); + col.getColumn().setWidth(350); col.getColumn().setText("Name"); col.setLabelProvider(new ColumnLabelProvider() { @Override diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleRawPage.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleRawPage.java index d989cff93..8bd5d63e5 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleRawPage.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/BundleRawPage.java @@ -29,7 +29,6 @@ import javax.jcr.nodetype.NodeType; import org.argeo.ArgeoException; import org.argeo.slc.client.ui.dist.DistImages; import org.argeo.slc.client.ui.dist.utils.DistUiHelpers; -import org.argeo.slc.client.ui.dist.utils.GenericDoubleClickListener; import org.argeo.slc.jcr.SlcNames; import org.argeo.slc.jcr.SlcTypes; import org.eclipse.jface.viewers.ColumnLabelProvider; @@ -91,7 +90,7 @@ public class BundleRawPage extends FormPage implements SlcNames, SlcTypes { complexTree = new TreeViewer(tree); // Configure - complexTree.addDoubleClickListener(new GenericDoubleClickListener()); + // complexTree.addDoubleClickListener(new GenericDoubleClickListener()); complexTree = new TreeViewer(tree); complexTree.setContentProvider(new TreeContentProvider()); complexTree.setLabelProvider(new TreeLabelProvider()); @@ -238,6 +237,16 @@ public class BundleRawPage extends FormPage implements SlcNames, SlcTypes { elements.add(child); } } + + // Properties + PropertyIterator pi = node.getProperties(); + while (pi.hasNext()) { + Property curProp = pi.nextProperty(); + if (!curProp.getName().startsWith("jcr:") + && !curProp.isMultiple()) + elements.add(curProp); + } + } catch (RepositoryException e) { throw new ArgeoException( "Unexpected exception while listing node properties", e); diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionEditorInput.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionEditorInput.java index d0f27dd89..323e9ee65 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionEditorInput.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionEditorInput.java @@ -29,16 +29,18 @@ import org.eclipse.ui.IPersistableElement; * */ public class DistributionEditorInput implements IEditorInput, SlcNames { + private Repository repository; + private Credentials credentials; private String repositoryName; private String repositoryDescription; - private Repository repository; private String workspaceName; - private String artifactsBase = RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH; - private Credentials credentials; - public DistributionEditorInput(String repositoryName, - String repositoryDescription, Repository repository, - String workspaceName, String artifactsBase, Credentials credentials) { + private String artifactsBase; + + public DistributionEditorInput(Repository repository, + Credentials credentials, String repositoryName, + String repositoryDescription, String workspaceName, + String artifactsBase) { super(); this.repository = repository; this.repositoryName = repositoryName; @@ -48,11 +50,11 @@ public class DistributionEditorInput implements IEditorInput, SlcNames { this.credentials = credentials; } - public DistributionEditorInput(String repositoryName, - String repositoryDescription, Repository repository, - String workspaceName, Credentials credentials) { - this(repositoryName, repositoryDescription, repository, workspaceName, - RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH, credentials); + public DistributionEditorInput(Repository repository, + Credentials credentials, String repositoryName, + String repositoryDescription, String workspaceName) { + this(repository, credentials, repositoryName, repositoryDescription, + workspaceName, RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH); } public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { 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 403617654..accde864d 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 @@ -41,6 +41,7 @@ import org.argeo.slc.SlcException; import org.argeo.slc.client.ui.dist.DistConstants; import org.argeo.slc.client.ui.dist.DistImages; import org.argeo.slc.client.ui.dist.DistPlugin; +import org.argeo.slc.client.ui.dist.PrivilegedJob; import org.argeo.slc.client.ui.dist.commands.DeleteArtifacts; import org.argeo.slc.client.ui.dist.utils.CommandHelpers; import org.argeo.slc.client.ui.dist.utils.NodeViewerComparator; @@ -49,7 +50,6 @@ import org.argeo.slc.jcr.SlcTypes; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; @@ -73,6 +73,7 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; @@ -109,32 +110,37 @@ public class DistributionOverviewPage extends FormPage implements SlcNames { } private void asynchronousRefresh() { - refreshFilteredList(); - // FIXME Does not work yet: how can the job set the viewer input ? - // RefreshJob job = new RefreshJob(session, artifactTxt.getText()); - // job.setUser(true); - // job.schedule(); - // viewer.setInput(nodes); + RefreshJob job = new RefreshJob(artifactTxt.getText(), viewer, + getSite().getShell().getDisplay()); + job.setUser(true); + job.schedule(); } - private class RefreshJob extends Job { - private Session session; - private List nodes; + private class RefreshJob extends PrivilegedJob { + private TableViewer viewer; private String filter; + private Display display; - public RefreshJob(Session session, String filter, List nodes) { + public RefreshJob(String filter, TableViewer viewer, Display display) { super("Get bundle list"); - this.session = session; + this.filter = filter; + this.viewer = viewer; + this.display = display; } @Override - protected IStatus run(IProgressMonitor progressMonitor) { + protected IStatus doRun(IProgressMonitor progressMonitor) { try { ArgeoMonitor monitor = new EclipseArgeoMonitor(progressMonitor); monitor.beginTask("Getting bundle list", -1); - List result = JcrUtils + final List result = JcrUtils .nodeIteratorToList(listBundleArtifacts(session, filter)); - nodes.addAll(result); + + display.asyncExec(new Runnable() { + public void run() { + viewer.setInput(result); + } + }); } catch (Exception e) { return new Status(IStatus.ERROR, DistPlugin.ID, "Cannot get bundle list", e); 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 f75423fe3..8b1f045d3 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,5 +1,6 @@ package org.argeo.slc.client.ui.dist.model; +/** Common super class for all dist tree elements */ public abstract class DistParentElem { private boolean inHome = false; private boolean isReadOnly = false; @@ -16,9 +17,21 @@ public abstract class DistParentElem { public abstract Object[] getChildren(); + public boolean hasChildren() { + return true; + } + public void dispose() { } + public void setInHome(boolean inHome) { + this.inHome = inHome; + } + + public void setReadOnly(boolean isReadOnly) { + this.isReadOnly = isReadOnly; + } + public boolean inHome() { return inHome; } 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 index 16c541fe9..512f1b5f9 100644 --- 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 @@ -3,7 +3,6 @@ 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; @@ -26,11 +25,10 @@ public class GroupElem extends DistParentElem { } public Object[] getChildren() { - repoElem.connect(); Session session = null; try { Repository repository = repoElem.getRepository(); - Node repoNode = repoElem.getRepoNode(); + // Node repoNode = repoElem.getRepoNode(); session = repository.login(repoElem.getCredentials()); String[] workspaceNames = session.getWorkspace() @@ -39,12 +37,8 @@ public class GroupElem extends DistParentElem { 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 + workspaceName)); } } return distributionElems.toArray(); 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 75de44e77..8e48d231f 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 @@ -12,70 +12,91 @@ 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.JcrUtils; import org.argeo.slc.SlcException; +import org.argeo.slc.repo.RepoConstants; import org.argeo.slc.repo.RepoUtils; import org.argeo.util.security.Keyring; +/** + * Abstract a repository. 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 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; - } + // Defines current repo + private Node repoNode = null; + private String label; + private String uri; - /** Inject repofactory and keyring to enable lazy init */ + /** + * Creates a RepoElement for an authenticated user. repofactory and keyring + * are used to enable lazy init + * + */ public RepoElem(Node repoNode, RepositoryFactory repoFactory, Keyring keyring) { this.repoNode = repoNode; this.repositoryFactory = repoFactory; this.keyring = keyring; + try { + // initialize this repo informations + setInHome(RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS + .equals(repoNode.getName())); + if (!inHome()) + 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); + } } - @Deprecated - public RepoElem(Node repoNode) { - this.repoNode = repoNode; + /** + * 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; } /** Lazily connects to repository */ protected void connect() { if (repository != null) return; - repository = RepoUtils.getRepository(repositoryFactory, keyring, - repoNode); - credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode); + if (repoNode == null) + // Anonymous + repository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, + uri); + else { + 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); - } + return label; + } + + public String getUri() { + return uri; } public String toString() { - return repoNode.toString(); + return repoNode != null ? repoNode.toString() : label; } public Object[] getChildren() { @@ -85,23 +106,43 @@ public class RepoElem extends DistParentElem { session = repository.login(credentials); String[] workspaceNames = session.getWorkspace() .getAccessibleWorkspaceNames(); - // List distributionElems = new - // ArrayList(); Map children = new HashMap(); - for (String workspaceName : workspaceNames) { + + buildWksp: for (String workspaceName : workspaceNames) { + // Add a supplementary check to hide workspace that are not + // public to anonymous user + + // TODO fix this + // if (repoNode == null) { + // Session tmpSession = null; + // try { + // tmpSession = repository.login(); + // Privilege[] priv = new Privilege[1]; + // priv[0] = tmpSession.getAccessControlManager() + // .privilegeFromName(Privilege.JCR_READ); + // Privilege[] tmp = tmpSession.getAccessControlManager() + // .getPrivileges("/"); + // boolean res = tmpSession.getAccessControlManager() + // .hasPrivileges("/", priv); + // if (!res) + // continue buildWksp; + // } catch (RepositoryException e) { + // throw new SlcException( + // "Cannot list workspaces for anonymous user", e); + // } finally { + // JcrUtils.logoutQuietly(tmpSession); + // } + // } + // 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(); @@ -112,14 +153,6 @@ public class RepoElem extends DistParentElem { } } - 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; @@ -129,8 +162,15 @@ public class RepoElem extends DistParentElem { return credentials; } + public String getDescription() { + String desc = label; + if (repoNode != null) + desc = label + " (" + uri + ")"; + return desc; + } + + /** Might return null in case of an anonymous user */ public Node getRepoNode() { return repoNode; } - -} +} \ 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 e4562ee71..5c5181d77 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,70 +1,49 @@ 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 { +public class WorkspaceElem extends DistParentElem { private final RepoElem repoElem; - private final Node workspaceNode; + private String workspaceName; + private String label; /** * Helper to display only version when the workspace name is well formatted */ - private static String formatName(Node workspaceNode) { - String name = JcrUtils.getNameQuietly(workspaceNode); + private static String formatName(String name) { if (name != null && name.lastIndexOf('-') > 0) return name.substring(name.lastIndexOf('-') + 1); else return name; } - public WorkspaceElem(RepoElem repoElem, Node workspaceNode) { - super(formatName(workspaceNode)); + public WorkspaceElem(RepoElem repoElem, String workspaceName) { this.repoElem = repoElem; - this.workspaceNode = workspaceNode; - } - - public Node getWorkspaceNode() { - return workspaceNode; + this.workspaceName = workspaceName; + this.label = formatName(workspaceName); } public String getWorkspaceName() { - return JcrUtils.getNameQuietly(workspaceNode); + return workspaceName; } - public String getWorkspacePath() { - try { - return workspaceNode.getPath(); - } catch (RepositoryException e) { - throw new SlcException("Cannot get or add workspace path " - + getWorkspaceName(), e); - } + public RepoElem getRepoElem() { + return repoElem; } - public String getRepoPath() { - try { - return workspaceNode.getParent().getPath(); - } catch (RepositoryException e) { - throw new SlcException("Cannot get or add workspace path " - + getWorkspaceName(), e); - } + public boolean isReadOnly() { + return repoElem.isReadOnly(); } - public RepoElem getRepoElem() { - return repoElem; + public boolean hasChildren() { + return false; } - public Credentials getCredentials() { - return repoElem.getCredentials(); + public Object[] getChildren() { + return null; } - public boolean isReadOnly() { - return repoElem.isReadOnly(); + @Override + public String getLabel() { + return label; } } diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactLabelProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactLabelProvider.java deleted file mode 100644 index 17b8e6f3f..000000000 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactLabelProvider.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.providers; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.RepositoryException; - -import org.argeo.ArgeoException; -import org.argeo.jcr.JcrUtils; -import org.argeo.slc.client.ui.dist.DistConstants; -import org.argeo.slc.client.ui.dist.DistImages; -import org.argeo.slc.jcr.SlcTypes; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.swt.graphics.Image; - -public class ArtifactLabelProvider extends ColumnLabelProvider implements - DistConstants, SlcTypes { - - // To be able to change column order easily - public static final int COLUMN_TREE = 0; - public static final int COLUMN_DATE = 1; - public static final int COLUMN_SIZE = 2; - - // Utils - protected static DateFormat timeFormatter = new SimpleDateFormat( - DATE_TIME_FORMAT); - - public void update(ViewerCell cell) { - int colIndex = cell.getColumnIndex(); - Object element = cell.getElement(); - cell.setText(getColumnText(element, colIndex)); - if (element instanceof Node && colIndex == 0) { - Node node = (Node) element; - try { - if (node.isNodeType(SLC_ARTIFACT_BASE)) - cell.setImage(DistImages.IMG_ARTIFACT_BASE); - else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) - cell.setImage(DistImages.IMG_ARTIFACT_VERSION_BASE); - } catch (RepositoryException e) { - // Silent - } - } - } - - @Override - public Image getImage(Object element) { - - if (element instanceof Node) { - Node node = (Node) element; - try { - if (node.isNodeType(SLC_ARTIFACT_BASE)) { - return DistImages.IMG_ARTIFACT_BASE; - } else if (node.isNodeType(SLC_ARTIFACT_VERSION_BASE)) { - return DistImages.IMG_ARTIFACT_VERSION_BASE; - } - } catch (RepositoryException e) { - // Silent - } - } - return null; - } - - public String getColumnText(Object element, int columnIndex) { - try { - if (element instanceof Node) { - Node node = (Node) element; - switch (columnIndex) { - case COLUMN_TREE: - return node.getName(); - case COLUMN_SIZE: - long size = JcrUtils.getNodeApproxSize(node) / 1024; - if (size > 1024) - return size / 1024 + " MB"; - else - return size + " KB"; - case COLUMN_DATE: - if (node.hasProperty(Property.JCR_LAST_MODIFIED)) - return timeFormatter.format(node - .getProperty(Property.JCR_LAST_MODIFIED) - .getDate().getTime()); - else - return null; - } - } - } catch (RepositoryException re) { - throw new ArgeoException( - "Unexepected error while getting property values", re); - } - return null; - } -} diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactsTreeContentProvider.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactsTreeContentProvider.java deleted file mode 100644 index e35d819e9..000000000 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/ArtifactsTreeContentProvider.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.providers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; - -import org.argeo.ArgeoException; -import org.argeo.eclipse.ui.jcr.utils.JcrItemsComparator; -import org.argeo.slc.jcr.SlcTypes; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -public class ArtifactsTreeContentProvider implements ITreeContentProvider, - SlcTypes { - - // Utils - private boolean sortChildren = true; - private JcrItemsComparator itemComparator = new JcrItemsComparator(); - - public Object[] getElements(Object parent) { - return getChildren(parent); - } - - public Object getParent(Object child) { - return null; - } - - public Object[] getChildren(Object parent) { - Object[] elements = null; - try { - if (parent instanceof Node) { - Node node = (Node) parent; - NodeIterator ni = node.getNodes(); - List nodesList = new ArrayList(); - while (ni.hasNext()) { - nodesList.add(ni.nextNode()); - } - if (sortChildren) { - Node[] arr = (Node[]) nodesList.toArray(new Node[nodesList - .size()]); - Arrays.sort(arr, itemComparator); - return arr; - } else - return nodesList.toArray(); - - } - } catch (RepositoryException e) { - throw new ArgeoException( - "Unexpected exception while listing node properties", e); - } - return elements; - } - - public boolean hasChildren(Object parent) { - try { - if (parent instanceof Node) { - Node curNode = (Node) parent; - // We manually stop digging at this level - if (curNode.isNodeType(SLC_ARTIFACT_VERSION_BASE)) - return false; - else if (curNode.hasNodes()) - return true; - } - } catch (RepositoryException e) { - throw new ArgeoException( - "Unexpected exception while checking if property is multiple", - e); - } - return false; - } - - public void setSortChildren(boolean sortChildren) { - this.sortChildren = sortChildren; - } - - public boolean getSortChildren() { - return sortChildren; - } - - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - public void dispose() { - } -} \ 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/DistSessionFactory.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistSessionFactory.java deleted file mode 100644 index b8f2c7541..000000000 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistSessionFactory.java +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index e1f06c2f4..000000000 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeContentProvider.java +++ /dev/null @@ -1,150 +0,0 @@ -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 repositories = new ArrayList(); - - 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(); - 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 deleted file mode 100644 index de34e2a34..000000000 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/providers/DistTreeLabelProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -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 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 new file mode 100644 index 000000000..004e06957 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/AnonymousDistributionsView.java @@ -0,0 +1,91 @@ +/* + * 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.views; + +import org.argeo.jcr.ArgeoNames; +import org.argeo.slc.client.ui.dist.DistConstants; +import org.argeo.slc.client.ui.dist.DistPlugin; +import org.argeo.slc.client.ui.dist.controllers.DistTreeComparator; +import org.argeo.slc.client.ui.dist.controllers.DistTreeDoubleClickListener; +import org.argeo.slc.client.ui.dist.controllers.DistTreeLabelProvider; +import org.argeo.slc.jcr.SlcNames; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.part.ViewPart; + +/** + * Browse, manipulate and manage distributions accross multiple repositories + * (like fetch, merge, publish, etc.). + */ +public class AnonymousDistributionsView extends ViewPart implements SlcNames, + ArgeoNames { + // private final static Log log = LogFactory + // .getLog(AnonymousDistributionsView.class); + public final static String ID = DistPlugin.ID + ".anonymousDistributionsView"; + + /* DEPENDENCY INJECTION */ + private ITreeContentProvider treeContentProvider; + + // This view widgets + private TreeViewer viewer; + + @Override + public void createPartControl(Composite parent) { + // Define the TableViewer + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.BORDER); + + TreeViewerColumn col = new TreeViewerColumn(viewer, SWT.NONE); + col.getColumn().setWidth(400); + col.setLabelProvider(new DistTreeLabelProvider()); + + final Tree tree = viewer.getTree(); + tree.setHeaderVisible(false); + tree.setLinesVisible(false); + + // viewer.setContentProvider(new DistTreeContentProvider()); + viewer.setContentProvider(treeContentProvider); + viewer.addDoubleClickListener(new DistTreeDoubleClickListener()); + viewer.setComparator(new DistTreeComparator()); + + // Initialize + refresh(); + } + + /** + * Force refresh of the whole view + */ + public void refresh() { + viewer.setInput(DistConstants.DEFAULT_PUBLIC_REPOSITORY_URI); + viewer.expandToLevel(2); + } + + @Override + public void setFocus() { + viewer.getTree().setFocus(); + } + + /* + * DEPENDENCY INJECTION + */ + public void setTreeContentProvider(ITreeContentProvider treeContentProvider) { + this.treeContentProvider = treeContentProvider; + } +} \ 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/views/ArtifactsBrowser.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/ArtifactsBrowser.java index 10a38454c..31cf7eb03 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/ArtifactsBrowser.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/ArtifactsBrowser.java @@ -20,19 +20,15 @@ import java.text.SimpleDateFormat; import javax.jcr.Node; import javax.jcr.Property; -import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.Value; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.jcr.JcrUtils; import org.argeo.slc.client.ui.dist.DistConstants; import org.argeo.slc.client.ui.dist.DistImages; import org.argeo.slc.client.ui.dist.DistPlugin; -import org.argeo.slc.client.ui.dist.providers.ArtifactsTreeContentProvider; +import org.argeo.slc.client.ui.dist.controllers.ArtifactsTreeContentProvider; import org.argeo.slc.client.ui.dist.utils.GenericDoubleClickListener; import org.argeo.slc.jcr.SlcTypes; import org.argeo.slc.repo.RepoConstants; @@ -60,7 +56,7 @@ import org.eclipse.ui.part.ViewPart; public class ArtifactsBrowser extends ViewPart implements DistConstants, RepoConstants { - private final static Log log = LogFactory.getLog(ArtifactsBrowser.class); + // private final static Log log = LogFactory.getLog(ArtifactsBrowser.class); public final static String ID = DistPlugin.ID + ".artifactsBrowser"; /* DEPENDENCY INJECTION */ @@ -255,23 +251,23 @@ public class ArtifactsBrowser extends ViewPart implements DistConstants, return null; } - private String formatValueAsString(Value value) { - // TODO enhance this method - try { - String strValue; - - if (value.getType() == PropertyType.BINARY) - strValue = ""; - else if (value.getType() == PropertyType.DATE) - strValue = timeFormatter.format(value.getDate().getTime()); - else - strValue = value.getString(); - return strValue; - } catch (RepositoryException e) { - throw new ArgeoException( - "unexpected error while formatting value", e); - } - } + // private String formatValueAsString(Value value) { + // // TODO enhance this method + // try { + // String strValue; + // + // if (value.getType() == PropertyType.BINARY) + // strValue = ""; + // else if (value.getType() == PropertyType.DATE) + // strValue = timeFormatter.format(value.getDate().getTime()); + // else + // strValue = value.getString(); + // return strValue; + // } catch (RepositoryException e) { + // throw new ArgeoException( + // "unexpected error while formatting value", e); + // } + // } } private class ArtifactTreeSelectionListener implements 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 218e613fa..84d00e673 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 @@ -18,53 +18,38 @@ package org.argeo.slc.client.ui.dist.views; import java.util.HashMap; import java.util.Map; -import javax.jcr.Credentials; -import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -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.ArgeoNames; -import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; 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; import org.argeo.slc.client.ui.dist.commands.DeleteWorkspace; import org.argeo.slc.client.ui.dist.commands.DisplayRepoInformation; import org.argeo.slc.client.ui.dist.commands.Fetch; +import org.argeo.slc.client.ui.dist.commands.MergeWorkspaces; import org.argeo.slc.client.ui.dist.commands.NormalizeDistribution; import org.argeo.slc.client.ui.dist.commands.PublishWorkspace; +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.editors.DistributionEditor; -import org.argeo.slc.client.ui.dist.editors.DistributionEditorInput; +import org.argeo.slc.client.ui.dist.controllers.DistTreeComparator; +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.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.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; 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.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; @@ -81,7 +66,6 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; /** @@ -89,7 +73,8 @@ import org.eclipse.ui.part.ViewPart; * (like fetch, merge, publish, etc.). */ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames { - private final static Log log = LogFactory.getLog(DistributionsView.class); + // private final static Log log = + // LogFactory.getLog(DistributionsView.class); public final static String ID = DistPlugin.ID + ".distributionsView"; /* DEPENDENCY INJECTION */ @@ -114,8 +99,8 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames // viewer.setContentProvider(new DistTreeContentProvider()); viewer.setContentProvider(treeContentProvider); - viewer.addDoubleClickListener(new DistributionsDCL()); - viewer.setComparator(new BrowserElementComparator()); + viewer.addDoubleClickListener(new DistTreeDoubleClickListener()); + viewer.setComparator(new DistTreeComparator()); // Enable selection retrieving from outside the view getSite().setSelectionProvider(viewer); @@ -144,181 +129,148 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames protected void contextMenuAboutToShow(IMenuManager menuManager) { IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench() .getActiveWorkbenchWindow(); - // Most of the implemented commands support only one selected - // element - boolean singleElement = ((IStructuredSelection) viewer.getSelection()) - .size() == 1; - // Get Current selected item : - Object firstElement = ((IStructuredSelection) viewer.getSelection()) - .getFirstElement(); - - if (firstElement instanceof TreeParent - || 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 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.inHome(); - isReadOnly = re.isReadOnly(); - } else if (firstElement instanceof GroupElem) { - GroupElem dge = (GroupElem) firstElement; - isReadOnly = dge.isReadOnly(); - isDistribGroupElem = true; - } - // Display repo info - CommandHelpers.refreshCommand(menuManager, window, - DisplayRepoInformation.ID, - DisplayRepoInformation.DEFAULT_LABEL, - DisplayRepoInformation.DEFAULT_ICON_PATH, isRepoElem - && singleElement); - - // create workspace - CommandHelpers.refreshCommand(menuManager, window, - CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL, - CreateWorkspace.DEFAULT_ICON_PATH, - (isRepoElem || isDistribGroupElem) && singleElement - && !isReadOnly); - // publish workspace - CommandHelpers.refreshCommand(menuManager, window, - PublishWorkspace.ID, PublishWorkspace.DEFAULT_LABEL, - PublishWorkspace.DEFAULT_ICON_PATH, isDistribElem - && singleElement && !isReadOnly); - - // Register a remote repository - CommandHelpers.refreshCommand(menuManager, window, - RegisterRepository.ID, RegisterRepository.DEFAULT_LABEL, - RegisterRepository.DEFAULT_ICON_PATH, isRepoElem - && singleElement); - - // Unregister a remote repository - Map params = new HashMap(); - params.put(UnregisterRemoteRepo.PARAM_REPO_PATH, targetRepoPath); - CommandHelpers.refreshParameterizedCommand(menuManager, window, - UnregisterRemoteRepo.ID, - UnregisterRemoteRepo.DEFAULT_LABEL, - UnregisterRemoteRepo.DEFAULT_ICON_PATH, isRepoElem - && !isHomeRepo && singleElement, params); - - // Fetch repository - params = new HashMap(); - params.put(Fetch.PARAM_TARGET_REPO, targetRepoPath); - CommandHelpers.refreshParameterizedCommand(menuManager, window, - Fetch.ID, Fetch.DEFAULT_LABEL, Fetch.DEFAULT_ICON_PATH, - isRepoElem && singleElement && !isReadOnly, params); - - // Normalize workspace - CommandHelpers.refreshCommand(menuManager, window, - NormalizeDistribution.ID, - NormalizeDistribution.DEFAULT_LABEL, - NormalizeDistribution.DEFAULT_ICON_PATH, isDistribElem - && singleElement && !isReadOnly); - - // Copy workspace - CommandHelpers.refreshCommand(menuManager, window, - CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL, - CopyWorkspace.DEFAULT_ICON_PATH, isDistribElem - && singleElement); - - // Clear Workspace - CommandHelpers.refreshCommand(menuManager, window, - DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL, - DeleteWorkspace.DEFAULT_ICON_PATH, isDistribElem - && singleElement && !isReadOnly); - - // // Manage workspace authorizations - // params = new HashMap(); - // params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName); - // CommandHelpers.refreshParameterizedCommand(menuManager, window, - // ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL, - // ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem - // && singleElement && !isReadOnly, params); - } - // } catch (RepositoryException e) { - // throw new SlcException("unexpected errror while " - // + "building context menu", e); - // } - } + try { + // Most of the implemented commands support only one selected + // element + boolean singleElement = ((IStructuredSelection) viewer + .getSelection()).size() == 1; + // Get Current selected item : + Object firstElement = ((IStructuredSelection) viewer.getSelection()) + .getFirstElement(); - /** - * Exposes some Repository and workspace information about the selected - * element without exposing the UI model - */ - public class DistributionViewSelectedElement { - public boolean isRepository = false; - public boolean isWorkspaceGroup = false; - public boolean isWorkspace = false; - public boolean isReadOnly = false; - public String repositoryDescription; - public Node repoNode; - public String wkspName; - public String wkspPrefix; - public Repository repository; - public Credentials credentials; - } + if (firstElement instanceof TreeParent + || firstElement instanceof DistParentElem) { + + String targetRepoPath = null, workspaceName = null, workspacePrefix = null; + // String targetRepoUri = null; + // Build conditions depending on element type + boolean isDistribElem = false, isRepoElem = false, isDistribGroupElem = false; + boolean isHomeRepo = false, isReadOnly = true; + + RepoElem re = null; + + if (firstElement instanceof WorkspaceElem) { + WorkspaceElem de = (WorkspaceElem) firstElement; + re = de.getRepoElem(); + isDistribElem = true; + isReadOnly = de.isReadOnly(); + workspaceName = de.getWorkspaceName(); + } else if (firstElement instanceof RepoElem) { + re = (RepoElem) firstElement; + isRepoElem = true; + isHomeRepo = re.inHome(); + isReadOnly = re.isReadOnly(); + } else if (firstElement instanceof GroupElem) { + GroupElem dge = (GroupElem) firstElement; + isReadOnly = dge.isReadOnly(); + isDistribGroupElem = true; + re = dge.getRepoElem(); + workspacePrefix = dge.getLabel(); + } - /** - * Returns a {@see DistributionViewSelectedElement} if one and only one - * valid element is currently selected. - * - */ - public DistributionViewSelectedElement getSelectedElement() { - - IStructuredSelection iss = (IStructuredSelection) viewer.getSelection(); - if (iss.isEmpty() || iss.size() > 1) - return null; - - DistributionViewSelectedElement dvse = new DistributionViewSelectedElement(); - Object obj = iss.getFirstElement(); - if (obj instanceof RepoElem) { - RepoElem re = (RepoElem) obj; - dvse.isRepository = true; - dvse.isReadOnly = re.isReadOnly(); - dvse.repository = re.getRepository(); - dvse.repoNode = re.getRepoNode(); - dvse.credentials = re.getCredentials(); - dvse.repositoryDescription = getRepositoryDescription(re); - } else if (obj instanceof GroupElem) { - GroupElem dge = (GroupElem) obj; - dvse.isWorkspaceGroup = true; - dvse.isReadOnly = dge.isReadOnly(); - dvse.repository = dge.getRepoElem().getRepository(); - dvse.repoNode = dge.getRepoElem().getRepoNode(); - dvse.credentials = dge.getRepoElem().getCredentials(); - dvse.wkspPrefix = dge.getLabel(); - dvse.repositoryDescription = getRepositoryDescription(dge - .getRepoElem()); - } else if (obj instanceof WorkspaceElem) { - WorkspaceElem de = (WorkspaceElem) obj; - dvse.isWorkspace = true; - dvse.isReadOnly = de.isReadOnly(); - dvse.repository = de.getRepoElem().getRepository(); - dvse.repoNode = de.getRepoElem().getRepoNode(); - dvse.credentials = de.getRepoElem().getCredentials(); - dvse.wkspName = de.getWorkspaceName(); - dvse.repositoryDescription = getRepositoryDescription(de - .getRepoElem()); - } - return dvse; - } + if (re != null) { + // targetRepoUri = re.getUri(); + targetRepoPath = re.getRepoNode().getPath(); + } - private String getRepositoryDescription(RepoElem repo) { - StringBuffer repoDesc = new StringBuffer(); - repoDesc.append(repo.getLabel()); - repoDesc.append(" ("); - repoDesc.append(JcrUtils.get(repo.getRepoNode(), ARGEO_URI)); - repoDesc.append(")"); - return repoDesc.toString(); + // Display repo info + CommandHelpers.refreshCommand(menuManager, window, + DisplayRepoInformation.ID, + DisplayRepoInformation.DEFAULT_LABEL, + DisplayRepoInformation.DEFAULT_ICON_PATH, isRepoElem + && singleElement); + + // create workspace + Map params = new HashMap(); + params.put(CreateWorkspace.PARAM_TARGET_REPO_PATH, + targetRepoPath); + params.put(CreateWorkspace.PARAM_WORKSPACE_PREFIX, + workspacePrefix); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + CreateWorkspace.ID, CreateWorkspace.DEFAULT_LABEL, + CreateWorkspace.DEFAULT_ICON_PATH, + (isRepoElem || isDistribGroupElem) && singleElement + && !isReadOnly, params); + + // publish workspace + params = new HashMap(); + params.put(PublishWorkspace.PARAM_TARGET_REPO_PATH, + targetRepoPath); + params.put(PublishWorkspace.PARAM_WORKSPACE_NAME, workspaceName); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + PublishWorkspace.ID, PublishWorkspace.DEFAULT_LABEL, + PublishWorkspace.DEFAULT_ICON_PATH, isDistribElem + && singleElement && !isReadOnly, params); + + // Register a remote repository + CommandHelpers.refreshCommand(menuManager, window, + RegisterRepository.ID, + RegisterRepository.DEFAULT_LABEL, + RegisterRepository.DEFAULT_ICON_PATH, isRepoElem + && singleElement); + + // Unregister a remote repository + params = new HashMap(); + params.put(UnregisterRemoteRepo.PARAM_REPO_PATH, targetRepoPath); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + UnregisterRemoteRepo.ID, + UnregisterRemoteRepo.DEFAULT_LABEL, + UnregisterRemoteRepo.DEFAULT_ICON_PATH, isRepoElem + && !isHomeRepo && singleElement, params); + + // Fetch repository + params = new HashMap(); + params.put(Fetch.PARAM_TARGET_REPO_PATH, targetRepoPath); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + Fetch.ID, Fetch.DEFAULT_LABEL, Fetch.DEFAULT_ICON_PATH, + isRepoElem && singleElement && !isReadOnly, params); + + // Normalize workspace + params = new HashMap(); + params.put(NormalizeDistribution.PARAM_TARGET_REPO_PATH, + targetRepoPath); + params.put(NormalizeDistribution.PARAM_WORKSPACE_NAME, + workspaceName); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + NormalizeDistribution.ID, + NormalizeDistribution.DEFAULT_LABEL, + NormalizeDistribution.DEFAULT_ICON_PATH, isDistribElem + && singleElement && !isReadOnly, params); + + // Copy workspace + params = new HashMap(); + params.put(CopyWorkspace.PARAM_TARGET_REPO_PATH, targetRepoPath); + params.put(CopyWorkspace.PARAM_SOURCE_WORKSPACE_NAME, + workspaceName); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + CopyWorkspace.ID, CopyWorkspace.DEFAULT_LABEL, + CopyWorkspace.DEFAULT_ICON_PATH, isDistribElem + && singleElement, params); + + // Clear Workspace + params = new HashMap(); + params.put(DeleteWorkspace.PARAM_TARGET_REPO_PATH, + targetRepoPath); + params.put(DeleteWorkspace.PARAM_WORKSPACE_NAME, workspaceName); + CommandHelpers.refreshParameterizedCommand(menuManager, window, + DeleteWorkspace.ID, DeleteWorkspace.DEFAULT_LABEL, + DeleteWorkspace.DEFAULT_ICON_PATH, isDistribElem + && singleElement && !isReadOnly, params); + + // // Manage workspace authorizations + // params = new HashMap(); + // params.put(ManageWorkspaceAuth.PARAM_WORKSPACE_NAME, wsName); + // CommandHelpers.refreshParameterizedCommand(menuManager, + // window, + // ManageWorkspaceAuth.ID, ManageWorkspaceAuth.DEFAULT_LABEL, + // ManageWorkspaceAuth.DEFAULT_ICON_PATH, isDistribElem + // && singleElement && !isReadOnly, params); + } + } catch (RepositoryException e) { + throw new SlcException("unexpected errror while " + + "building context menu", e); + } } @Override @@ -334,31 +286,6 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames viewer.expandToLevel(2); } - /** Add some view specific behaviours to the comparator */ - private class BrowserElementComparator extends ArtifactNamesComparator { - @Override - public int category(Object element) { - // Home repository always first - if (element instanceof RepoElem && ((RepoElem) element).inHome()) - return 2; - else - return super.category(element); - } - - @Override - public int compare(Viewer viewer, Object e1, Object e2) { - // reverse order for versions - if (e1 instanceof WorkspaceElem) - return -super.compare(viewer, e1, e2); - else - return super.compare(viewer, e1, e2); - } - } - - /** Abstract class to simplify UI conditions build */ - - /** A software repository */ - /** Listens to drag */ class ViewDragListener extends DragSourceAdapter { public void dragSetData(DragSourceEvent event) { @@ -367,7 +294,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.getWorkspacePath(); + event.data = de.getRepoElem().getUri() + "/" + + de.getWorkspaceName(); } } } @@ -386,66 +314,27 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames RepoElem targetRepo = (RepoElem) getCurrentTarget(); Boolean ok = MessageDialog.openConfirm(getSite().getShell(), - "FIXME: BROKEN BY REFACTORING--Confirm distribution merge", - "Do you want to merge " + sourceDist.getWorkspaceName() - + " (from repo " + "Confirm distribution merge", "Do you want to merge " + + sourceDist.getWorkspaceName() + " (from repo " + sourceDist.getRepoElem().getLabel() + ") to repo " + targetRepo.getLabel() + "?"); if (!ok) return false; - // 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); - // } + try { + 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_WORKSPACE_NAME, + sourceDist.getWorkspaceName()); + CommandHelpers.callCommand(RefreshDistributionsView.ID, params); + return true; + } catch (RepositoryException e) { + throw new SlcException("Cannot process drop from " + sourceDist + + " to " + targetRepo, e); + } } @Override @@ -454,93 +343,16 @@ public class DistributionsView extends ViewPart implements SlcNames, ArgeoNames if (target instanceof RepoElem) { if (getSelectedObject() instanceof WorkspaceElem) { // check if not same repository - String srcRepoPath = ((WorkspaceElem) getSelectedObject()) - .getRepoPath(); - String targetRepoPath = ((RepoElem) target).getRepoPath(); - return !targetRepoPath.equals(srcRepoPath); + String srcRepoUri = ((WorkspaceElem) getSelectedObject()) + .getRepoElem().getUri(); + String targetRepoUri = ((RepoElem) target).getUri(); + return !targetRepoUri.equals(srcRepoUri); } } return false; } } - private static class WorkspaceMergeJob extends Job { - private Session sourceSession; - private Session targetSession; - - public WorkspaceMergeJob(Session sourceSession, Session targetSession) { - super("Workspace merge"); - this.sourceSession = sourceSession; - this.targetSession = targetSession; - } - - @Override - protected IStatus run(IProgressMonitor eclipseMonitor) { - long begin = System.currentTimeMillis(); - try { - Query countQuery = sourceSession - .getWorkspace() - .getQueryManager() - .createQuery("select file from [nt:file] as file", - Query.JCR_SQL2); - QueryResult result = countQuery.execute(); - Long expectedCount = result.getNodes().getSize(); - if (log.isDebugEnabled()) - log.debug("Will copy " + expectedCount + " files..."); - - ArgeoMonitor monitor = new EclipseArgeoMonitor(eclipseMonitor); - eclipseMonitor - .beginTask("Copy files", expectedCount.intValue()); - - Long count = JcrUtils.copyFiles(sourceSession.getRootNode(), - targetSession.getRootNode(), true, monitor); - - monitor.done(); - long duration = (System.currentTimeMillis() - begin) / 1000;// in - // s - if (log.isDebugEnabled()) - log.debug("Copied " + count + " files in " - + (duration / 60) + "min " + (duration % 60) + "s"); - - return Status.OK_STATUS; - } catch (RepositoryException e) { - return new Status(IStatus.ERROR, DistPlugin.ID, "Cannot merge", - e); - } finally { - JcrUtils.logoutQuietly(sourceSession); - JcrUtils.logoutQuietly(targetSession); - } - } - } - - /** Listen to double-clicks */ - private class DistributionsDCL implements IDoubleClickListener { - - public void doubleClick(DoubleClickEvent event) { - if (event.getSelection() == null || event.getSelection().isEmpty()) - return; - Object obj = ((IStructuredSelection) event.getSelection()) - .getFirstElement(); - if (obj instanceof WorkspaceElem) { - WorkspaceElem distributionElem = (WorkspaceElem) obj; - DistributionEditorInput dei = new DistributionEditorInput( - distributionElem.getName(), - getRepositoryDescription(distributionElem.getRepoElem()), - distributionElem.getRepoElem().getRepository(), - distributionElem.getWorkspaceName(), distributionElem - .getCredentials()); - try { - DistPlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getActivePage() - .openEditor(dei, DistributionEditor.ID); - } catch (PartInitException e) { - ErrorFeedback.show("Cannot open editor for " - + distributionElem.getWorkspaceName(), e); - } - } - } - } - /* * DEPENDENCY INJECTION */ diff --git a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/HelpView.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/HelpView.java new file mode 100644 index 000000000..e5454e325 --- /dev/null +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/HelpView.java @@ -0,0 +1,52 @@ +/* + * 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.views; + +import org.argeo.slc.client.ui.dist.DistPlugin; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +/** + * + * Displays some info about the distribution + * + */ +public class HelpView extends ViewPart { + public final static String ID = DistPlugin.ID + ".helpView"; + + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new GridLayout(2, false)); + Browser browser = new Browser(parent, SWT.NONE); + browser.setUrl("http://www.argeo.org"); + browser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); + } + + /** + * Force refresh of the whole view + */ + public void refresh() { + } + + @Override + public void setFocus() { + } + +} \ 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/wizards/RegisterRepoWizard.java b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/wizards/RegisterRepoWizard.java index fb80ac3cf..fbc7c639d 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 @@ -19,6 +19,7 @@ import java.net.URI; import java.util.Hashtable; import javax.jcr.Node; +import javax.jcr.NodeIterator; import javax.jcr.Property; import javax.jcr.Repository; import javax.jcr.RepositoryFactory; @@ -26,7 +27,6 @@ import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.jcr.nodetype.NodeType; -import org.argeo.ArgeoException; import org.argeo.eclipse.ui.ErrorFeedback; import org.argeo.jcr.ArgeoJcrConstants; import org.argeo.jcr.ArgeoJcrUtils; @@ -113,9 +113,26 @@ public class RegisterRepoWizard extends Wizard { Node repos = nodeSession.getNode(reposPath); String repoNodeName = JcrUtils.replaceInvalidChars(name.getText()); if (repos.hasNode(repoNodeName)) - throw new ArgeoException( + throw new SlcException( "There is already a remote repository named " + repoNodeName); + + // check if the same URI has already been registered + NodeIterator ni = repos.getNodes(); + while (ni.hasNext()) { + Node node = ni.nextNode(); + if (node.isNodeType(ArgeoTypes.ARGEO_REMOTE_REPOSITORY) + && node.hasProperty(ArgeoNames.ARGEO_URI) + && node.getProperty(ArgeoNames.ARGEO_URI).getString() + .equals(uri.getText())) + throw new SlcException( + "This URI " + + uri.getText() + + " is already registered, " + + "for the time being, only one instance of a single " + + "repository at a time is implemented."); + } + Node repoNode = repos.addNode(repoNodeName, ArgeoTypes.ARGEO_REMOTE_REPOSITORY); repoNode.setProperty(ArgeoNames.ARGEO_URI, uri.getText()); diff --git a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java index 99d131d8f..c0e750187 100644 --- a/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java +++ b/plugins/org.argeo.slc.client.ui/src/main/java/org/argeo/slc/client/ui/views/JcrResultTreeView.java @@ -32,8 +32,6 @@ import javax.jcr.observation.Event; import javax.jcr.observation.EventListener; import javax.jcr.observation.ObservationManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; import org.argeo.eclipse.ui.jcr.AsyncUiEventListener; import org.argeo.eclipse.ui.utils.CommandUtils; @@ -105,7 +103,8 @@ public class JcrResultTreeView extends ViewPart { private final static DateFormat dateFormat = new SimpleDateFormat( SlcUiConstants.DEFAULT_DISPLAY_DATE_TIME_FORMAT); - private final static Log log = LogFactory.getLog(JcrResultTreeView.class); + // private final static Log log = + // LogFactory.getLog(JcrResultTreeView.class); /* DEPENDENCY INJECTION */ private Session session; @@ -677,7 +676,7 @@ public class JcrResultTreeView extends ViewPart { ResultParentUtils.updatePassedStatus( session.getNode(JcrUtils.parentPath(sourcePath)), true); - Node target = session.getNode(destPath); + // Node target = session.getNode(destPath); session.save(); return true; }