X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=plugins%2Forg.argeo.slc.client.ui.dist%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fclient%2Fui%2Fdist%2Fmodel%2FRepoElem.java;h=28841c8695aaf51195a6fe881e7af9756ba3dfd6;hb=1e6cf7254fb9f150251594cf0383b3b1c5210517;hp=6d07d1c672725063c1a49aae3ea313576b8d3d0a;hpb=adec844f9bcb5c6c45009409476776b3dbdc1d3d;p=gpl%2Fargeo-slc.git 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 6d07d1c67..28841c869 100644 --- a/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java +++ b/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/model/RepoElem.java @@ -1,17 +1,13 @@ package org.argeo.slc.client.ui.dist.model; import java.security.AccessControlException; -import java.util.HashMap; -import java.util.Map; import javax.jcr.Credentials; import javax.jcr.Node; -import javax.jcr.Property; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; import org.argeo.jcr.ArgeoJcrUtils; import org.argeo.jcr.ArgeoNames; @@ -22,145 +18,217 @@ 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 + * Abstract a repository. It might be persisted by a node in the current user + * home Node or just an URI and a label if user is anonymous */ public class RepoElem extends DistParentElem { // private final static Log log = LogFactory.getLog(RepoElem.class); - private Repository repository; - private Credentials credentials; + private RepositoryFactory repositoryFactory; private Keyring keyring; + private Credentials credentials; + private Session defaultSession = null; // Defines current repo private Node repoNode = null; private String label; private String uri; + private Repository repository; + + /** + * Creates a RepoElement for anonymous user. The {@code RepositoryFactory} + * is used to enable lazy initialisation + */ + public RepoElem(RepositoryFactory repoFactory, String uri, String label) { + super(label); + this.repositoryFactory = repoFactory; + this.uri = uri; + this.label = label; + } + /** - * Creates a RepoElement for an authenticated user. repofactory and keyring - * are used to enable lazy init + * Creates a RepoElement for an authenticated user. The + * {@code RepositoryFactory} and {@code Keyring} are used to enable lazy + * initialisation * */ - public RepoElem(Node repoNode, RepositoryFactory repoFactory, - Keyring keyring) { + public RepoElem(RepositoryFactory repoFactory, Keyring keyring, + Node repoNode, String alias) { + super(alias); + this.label = alias; + // label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode + // .getProperty(Property.JCR_TITLE).getString() : repoNode + // .getName(); this.repoNode = repoNode; this.repositoryFactory = repoFactory; this.keyring = keyring; try { - // initialize this repo informations + // Initialize this repo information setInHome(RepoConstants.DEFAULT_JAVA_REPOSITORY_ALIAS .equals(repoNode.getName())); - if (!inHome()) + if (inHome()) + // Directly log and retrieve children for local repository + login(); + else setReadOnly(!repoNode.hasNode(ArgeoNames.ARGEO_PASSWORD)); uri = JcrUtils.get(repoNode, ArgeoNames.ARGEO_URI); - label = repoNode.isNodeType(NodeType.MIX_TITLE) ? repoNode - .getProperty(Property.JCR_TITLE).getString() : repoNode - .getName(); } catch (RepositoryException e) { throw new SlcException("Unable to " + "initialize repo element", e); } } - /** - * Creates a RepoElement for anonymous user. repofactory is used to enable - * lazy init - * - */ - public RepoElem(RepositoryFactory repoFactory, String uri, String label) { - this.repositoryFactory = repoFactory; - this.uri = uri; - this.label = label; + /** Effective login. Does nothing if the session is already there. */ + public void login() { + if (isConnected()) + return; + + if (repository == null) + if (repoNode == null) + // Anonymous + repository = ArgeoJcrUtils.getRepositoryByUri( + repositoryFactory, uri); + else { + repository = RepoUtils.getRepository(repositoryFactory, + keyring, repoNode); + credentials = RepoUtils.getRepositoryCredentials(keyring, + repoNode); + } + + try { + defaultSession = repository.login(credentials); + refreshChildren(); + } catch (RepositoryException e) { + throw new SlcException("Cannot login repository " + label + + " with credential " + credentials, e); + } } - /** Lazily connects to repository */ - protected void connect() { - if (repository != null) - return; - if (repoNode == null) - // Anonymous - repository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, - uri); - else { - repository = RepoUtils.getRepository(repositoryFactory, keyring, - repoNode); - credentials = RepoUtils.getRepositoryCredentials(keyring, repoNode); + protected void refreshChildren() { + try { + // TODO also remove deleted children (only adds for the time being + String[] workspaceNames = defaultSession.getWorkspace() + .getAccessibleWorkspaceNames(); + buildWksp: for (String workspaceName : workspaceNames) { + if (!isWorkspaceVisible(workspaceName)) + continue buildWksp; + + String prefix = getPrefix(workspaceName); + if (getChildByName(prefix) == null) { + WkspGroupElem wkspGpElem = new WkspGroupElem(RepoElem.this, + prefix); + addChild(wkspGpElem); + } + } + } catch (RepositoryException e) { + throw new SlcException("Cannot list workspaces for " + repoNode, e); } } - public String getLabel() { - return label; + @Override + public synchronized void dispose() { + JcrUtils.logoutQuietly(defaultSession); + super.dispose(); } - public String getUri() { - return uri; + private String getPrefix(String workspaceName) { + // Here is the tricks - we rely on a "hard coded" convention + // Workspace name should be like: name-major.minor + if (workspaceName.lastIndexOf(VERSION_SEP) > 0) + return workspaceName.substring(0, + workspaceName.lastIndexOf(VERSION_SEP)); + else + return workspaceName; } - public String toString() { - return repoNode != null ? repoNode.toString() : label; + /* Exposes this to the children workspace group */ + protected boolean isWorkspaceVisible(String wkspName) { + Boolean result = true; + if (ARGEO_SYSTEM_WKSP.contains(wkspName)) + return false; + // Add a supplementary check to hide workspace that are not + // public to anonymous user + if (repoNode == null) { + Session tmpSession = null; + try { + tmpSession = repository.login(wkspName); + try { + tmpSession.checkPermission("/", "read"); + } catch (AccessControlException e) { + result = false; + } + } catch (RepositoryException e) { + throw new SlcException( + "Cannot list workspaces for anonymous user", e); + } finally { + JcrUtils.logoutQuietly(tmpSession); + } + } + return result; } - public Object[] getChildren() { - connect(); - Session session = null; + /** + * Actual call to the + * {@link Repository#login(javax.jcr.Credentials, String)} method. To be + * overridden. + * + * Creates a new session with correct credentials using the information + * contained in the corresponding repo node. It provides all UI children + * elements an unique entry point to retrieve a new Session. Caller must + * close the session when it is not in use anymore. + * + */ + protected Session repositoryLogin(String workspaceName) { try { - session = repository.login(credentials); - String[] workspaceNames = session.getWorkspace() - .getAccessibleWorkspaceNames(); - Map children = new HashMap(); + return repository.login(credentials, workspaceName); + } catch (RepositoryException e) { + throw new SlcException("Cannot login repository " + label + + " with credential " + credentials, e); + } + } - buildWksp: for (String workspaceName : workspaceNames) { - // Add a supplementary check to hide workspace that are not - // public to anonymous user - - if (repoNode == null) { - Session tmpSession = null; - try { - tmpSession = repository.login(workspaceName); - Boolean res = true; - try { - tmpSession.checkPermission("/", "read"); - } catch (AccessControlException e) { - res = false; - } - if (!res) - continue buildWksp; - } catch (RepositoryException e) { - throw new SlcException( - "Cannot list workspaces for anonymous user", e); - } finally { - JcrUtils.logoutQuietly(tmpSession); - } - } + public Boolean isConnected() { + if (defaultSession != null && defaultSession.isLive()) + return true; + else + return false; + } - // 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 (!children.containsKey(prefix)) { - children.put(prefix, new GroupElem(RepoElem.this, - prefix)); - } - } + /** Exposes URI to the current repository */ + public String getUri() { + return uri; + } + + public String getRepoNodePath() { + if (repoNode == null) + return null; + else + try { + return repoNode.getPath(); + } catch (RepositoryException e) { + throw new SlcException("Cannot get node path for repository " + + label, e); } - return children.values().toArray(); - } catch (RepositoryException e) { - throw new SlcException("Cannot list workspaces for " + repoNode, e); - } finally { - JcrUtils.logoutQuietly(session); - } } - public Repository getRepository() { - connect(); + /** + * Exposes the local repoNode that completely define a connection to a + * repository (including a set of credentials). Might return null in case of + * an anonymous user + */ + protected Node getRepoNode() { + return repoNode; + } + + protected Repository getRepository() { return repository; } - public Credentials getCredentials() { + protected Credentials getCredentials() { return credentials; } + // META INFO public String getDescription() { String desc = label; if (repoNode != null) @@ -168,8 +236,11 @@ public class RepoElem extends DistParentElem { return desc; } - /** Might return null in case of an anonymous user */ - public Node getRepoNode() { - return repoNode; + public String getLabel() { + return label; + } + + public String toString() { + return repoNode != null ? repoNode.toString() : label; } } \ No newline at end of file