Package org.apache.jackrabbit.oak.jcr

Source Code of org.apache.jackrabbit.oak.jcr.SessionImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.jackrabbit.oak.jcr;

import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.commons.AbstractSession;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.jcr.namespace.NamespaceRegistryImpl;
import org.apache.jackrabbit.oak.jcr.value.ValueFactoryImpl;
import org.apache.jackrabbit.oak.namepath.AbstractNameMapper;
import org.apache.jackrabbit.oak.namepath.NameMapper;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;

import javax.jcr.Credentials;
import javax.jcr.InvalidItemStateException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.lock.LockManager;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.retention.RetentionManager;
import javax.jcr.security.AccessControlManager;
import javax.jcr.version.VersionManager;
import java.io.IOException;
import java.security.AccessControlException;

/**
* {@code SessionImpl}...
*/
public class SessionImpl extends AbstractSession implements JackrabbitSession {

    /**
     * logger instance
     */
    private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);

    private final GlobalContext globalContext;
    private final ContentSession contentSession;
    private final ValueFactoryImpl valueFactory;
    private final Workspace workspace;
    private final NamespaceRegistry nsreg;
    private final SessionContext sessionContext = new Context();
    private final NameMapper nameMapper = new SessionNameMapper();
    private final NamePathMapper namePathMapper = new NamePathMapperImpl(nameMapper);

    private boolean isAlive = true;
    private Root root;

    SessionImpl(GlobalContext globalContext, ContentSession contentSession)
            throws RepositoryException {
        this.globalContext = globalContext;
        this.contentSession = contentSession;
        this.valueFactory = new ValueFactoryImpl(contentSession.getCoreValueFactory(), namePathMapper);
        this.nsreg = new NamespaceRegistryImpl(contentSession);
        this.workspace = new WorkspaceImpl(sessionContext, this.nsreg);
        this.root = contentSession.getCurrentRoot();
    }


    //------------------------------------------------------------< Session >---

    @Override
    public Repository getRepository() {
        return globalContext.getInstance(Repository.class);
    }

    @Override
    public String getUserID() {
        return contentSession.getAuthInfo().getUserID();
    }

    @Override
    public String[] getAttributeNames() {
        return contentSession.getAuthInfo().getAttributeNames();
    }

    @Override
    public Object getAttribute(String name) {
        return contentSession.getAuthInfo().getAttribute(name);
    }

    @Override
    public Workspace getWorkspace() {
        return workspace;
    }

    /**
     * @see javax.jcr.Session#impersonate(Credentials)
     */
    @Override
    public Session impersonate(Credentials credentials) throws RepositoryException {
        ensureIsAlive();
        throw new UnsupportedRepositoryOperationException("TODO: Session.impersonate");
    }

    @Override
    public ValueFactory getValueFactory() throws RepositoryException {
        ensureIsAlive();
        return sessionContext.getValueFactory();
    }

    //------------------------------------------------------------< Reading >---

    @Override
    public Node getRootNode() throws RepositoryException {
        ensureIsAlive();
        return new NodeImpl(new NodeDelegate(sessionContext, root.getTree("/")));
    }

    @Override
    public Node getNodeByUUID(String uuid) throws RepositoryException {
        ensureIsAlive();
        throw new UnsupportedRepositoryOperationException("TODO: Session.getNodeByUUID");
    }

    @Override
    public Node getNodeByIdentifier(String id) throws RepositoryException {
        ensureIsAlive();

        if (id.charAt(0) == '/') {
            return getNode(id);
        } else {
            // TODO
            throw new UnsupportedRepositoryOperationException("TODO: Session.getNodeByIdentifier");
        }
    }

    //------------------------------------------------------------< Writing >---

    @Override
    public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
        internalMove(sessionContext.getNamePathMapper().toOakPath(srcAbsPath), sessionContext.getNamePathMapper().toOakPath(destAbsPath));
    }

    private void internalMove(String srcAbsPath, String destAbsPath) throws RepositoryException {
        ensureIsAlive();

        String srcPath = PathUtils.relativize("/", srcAbsPath);
        String destPath = PathUtils.relativize("/", destAbsPath);
        root.move(srcPath, destPath);
    }

    //------------------------------------------------------------< state >---

    @Override
    public void save() throws RepositoryException {
        ensureIsAlive();
        try {
            root.commit();
            root = contentSession.getCurrentRoot();
        } catch (CommitFailedException e) {
            throw new RepositoryException(e);
        }
    }

    @Override
    public void refresh(boolean keepChanges) throws RepositoryException {
        ensureIsAlive();
        if (keepChanges) {
            root.rebase();
        }
        else {
            root = contentSession.getCurrentRoot();
        }
    }

    @Override
    public boolean hasPendingChanges() throws RepositoryException {
        ensureIsAlive();

        return root.hasPendingChanges();
    }

    //----------------------------------------------------------< Lifecycle >---

    @Override
    public boolean isLive() {
        return isAlive;
    }


    @Override
    public void logout() {
        if (!isAlive) {
            // ignore
            return;
        }

        isAlive = false;
        // TODO

        try {
            contentSession.close();
        } catch (IOException e) {
            log.warn("Error while closing connection", e);
        }
    }

    //----------------------------------------------------< Import / Export >---

    @Override
    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
        return internalGetImportContentHandler(sessionContext.getNamePathMapper().toOakPath(parentAbsPath), uuidBehavior);
    }

    private ContentHandler internalGetImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
        ensureIsAlive();
        throw new UnsupportedRepositoryOperationException("TODO: Session.getImportContentHandler");
    }

    //------------------------------------------------------------< Locking >---

    /**
     * @see javax.jcr.Session#addLockToken(String)
     */
    @Override
    public void addLockToken(String lt) {
        try {
            getWorkspace().getLockManager().addLockToken(lt);
        } catch (RepositoryException e) {
            log.warn("Unable to add lock token '{}' to this session: {}", lt, e.getMessage());
        }
    }

    /**
     * @see javax.jcr.Session#getLockTokens()
     */
    @Override
    public String[] getLockTokens() {
        try {
            return getWorkspace().getLockManager().getLockTokens();
        } catch (RepositoryException e) {
            log.warn("Unable to retrieve lock tokens for this session: {}", e.getMessage());
            return new String[0];        }
    }

    /**
     * @see javax.jcr.Session#removeLockToken(String)
     */
    @Override
    public void removeLockToken(String lt) {
        try {
            getWorkspace().getLockManager().addLockToken(lt);
        } catch (RepositoryException e) {
            log.warn("Unable to add lock token '{}' to this session: {}", lt, e.getMessage());
        }
    }

    //------------------------------------------------------< AccessControl >---

    @Override
    public boolean hasPermission(String absPath, String actions) throws RepositoryException {
        return internalHasPermission(sessionContext.getNamePathMapper().toOakPath(absPath), actions);
    }

    private boolean internalHasPermission(String absPath, String actions) throws RepositoryException {
        ensureIsAlive();

        // TODO
        return false;
    }

    /**
     * @see javax.jcr.Session#checkPermission(String, String)
     */
    @Override
    public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException {
        if (!hasPermission(absPath, actions)) {
            throw new AccessControlException("Access control violation: path = " + absPath + ", actions = " + actions);
        }
    }

    @Override
    public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
        ensureIsAlive();

        // TODO
        return false;
    }

    @Override
    public AccessControlManager getAccessControlManager() throws RepositoryException {
        ensureIsAlive();
        throw new UnsupportedRepositoryOperationException("TODO: Session.getAccessControlManager");
    }

    //----------------------------------------------------------< Retention >---

    @Override
    public RetentionManager getRetentionManager() throws RepositoryException {
        throw new UnsupportedRepositoryOperationException("Retention Management is not supported.");
    }

    //--------------------------------------------------< JackrabbitSession >---

    @Override
    public PrincipalManager getPrincipalManager() throws RepositoryException {
        // TODO
        throw new UnsupportedOperationException("Implementation missing");
    }

    @Override
    public UserManager getUserManager() throws RepositoryException {
        // TODO
        throw new UnsupportedOperationException("Implementation missing");
    }

    //-------------------------------------------< SessionNamespaceResolver >---
   
    private class SessionNameMapper extends AbstractNameMapper {

        @Override
        protected String getJcrPrefix(String oakPrefix) {
            try {
                String ns = nsreg.getURI(oakPrefix);
                return getNamespacePrefix(ns);
            } catch (RepositoryException e) {
                // TODO
                return null;
            }
        }

        @Override
        protected String getOakPrefix(String jcrPrefix) {
            try {
                String ns = getNamespaceURI(jcrPrefix);
                return nsreg.getPrefix(ns);
            } catch (RepositoryException e) {
                // TODO
                return null;
            }
        }

        @Override
        protected String getOakPrefixFromURI(String uri) {
            try {
                return nsreg.getPrefix(uri);
            } catch (RepositoryException e) {
                // TODO
                return null;
            }
        }
    }

    //--------------------------------------------------------------------------

    /**
     * Ensure that this session is alive and throw an exception otherwise.
     *
     * @throws RepositoryException if this session has been rendered invalid
     * for some reason (e.g. if this session has been closed explicitly by logout)
     */
    void ensureIsAlive() throws RepositoryException {
        // check session status
        if (!isAlive) {
            throw new RepositoryException("This session has been closed.");
        }
    }

    /**
     * Returns true if the repository supports the given option. False otherwise.
     *
     * @param option Any of the option constants defined by {@link Repository}
     * that either returns 'true' or 'false'. I.e.
     * <ul>
     * <li>{@link Repository#LEVEL_1_SUPPORTED}</li>
     * <li>{@link Repository#LEVEL_2_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_ACCESS_CONTROL_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_ACTIVITIES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_BASELINES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_JOURNALED_OBSERVATION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_LIFECYCLE_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_LOCKING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_OBSERVATION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_QUERY_SQL_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_RETENTION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_SHAREABLE_NODES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_SIMPLE_VERSIONING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_TRANSACTIONS_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UNFILED_CONTENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_VERSIONING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_WORKSPACE_MANAGEMENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_XML_EXPORT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_XML_IMPORT_SUPPORTED}</li>
     * <li>{@link Repository#WRITE_SUPPORTED}</li>
     * </ul>
     * @return true if the repository supports the given option. False otherwise.
     */
    boolean isSupportedOption(String option) {
        String desc = getRepository().getDescriptor(option);
        // if the descriptors are not available return true. the missing
        // functionality of the given SPI impl will in this case be detected
        // upon the corresponding SPI call (see JCR-3143).
        return (desc == null) ? true : Boolean.valueOf(desc);
    }

    /**
     * Make sure the repository supports the option indicated by the given string
     * and throw an exception otherwise.
     *
     * @param option Any of the option constants defined by {@link Repository}
     * that either returns 'true' or 'false'. I.e.
     * <ul>
     * <li>{@link Repository#LEVEL_1_SUPPORTED}</li>
     * <li>{@link Repository#LEVEL_2_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_ACCESS_CONTROL_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_ACTIVITIES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_BASELINES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_JOURNALED_OBSERVATION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_LIFECYCLE_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_LOCKING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_NODE_AND_PROPERTY_WITH_SAME_NAME_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_NODE_TYPE_MANAGEMENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_OBSERVATION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_QUERY_SQL_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_RETENTION_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_SHAREABLE_NODES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_SIMPLE_VERSIONING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_TRANSACTIONS_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UNFILED_CONTENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UPDATE_MIXIN_NODE_TYPES_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_UPDATE_PRIMARY_NODE_TYPE_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_VERSIONING_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_WORKSPACE_MANAGEMENT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_XML_EXPORT_SUPPORTED}</li>
     * <li>{@link Repository#OPTION_XML_IMPORT_SUPPORTED}</li>
     * <li>{@link Repository#WRITE_SUPPORTED}</li>
     * </ul>
     * @throws UnsupportedRepositoryOperationException If the given option is
     * not supported.
     * @throws RepositoryException If another error occurs.
     * @see javax.jcr.Repository#getDescriptorKeys()
     */
    void ensureSupportsOption(String option) throws RepositoryException {
        if (!isSupportedOption(option)) {
            throw new UnsupportedRepositoryOperationException(option + " is not supported by this repository.");
        }
    }

    /**
     * Ensure that this session has no pending changes and throw an exception
     * otherwise.
     *
     * @throws InvalidItemStateException if this nodes session has pending changes
     * @throws RepositoryException
     */
    void ensureNoPendingChanges() throws RepositoryException {
        // check for pending changes
        if (hasPendingChanges()) {
            String msg = "Unable to perform operation. Session has pending changes.";
            log.debug(msg);
            throw new InvalidItemStateException(msg);
        }
    }

    //--------------------------------------------------------------------------

    private class Context implements SessionContext {

        @Override
        public SessionImpl getSession() {
            return SessionImpl.this;
        }

        @Override
        public GlobalContext getGlobalContext() {
            return globalContext;
        }

        @Override
        public String getWorkspaceName() {
            return contentSession.getWorkspaceName();
        }

        @Override
        public ContentSession getContentSession() {
            return contentSession;
        }

        @Override
        public ValueFactoryImpl getValueFactory() {
            return valueFactory;
        }

        @Override
        public LockManager getLockManager() throws RepositoryException {
            return getWorkspace().getLockManager();
        }

        @Override
        public VersionManager getVersionManager() throws RepositoryException {
            return getWorkspace().getVersionManager();
        }

        @Override
        public Root getRoot() {
            return root;
        }

        @Override
        public Tree getTree(String oakPath) {
            return root.getTree(oakPath);
        }

        @Override
        public NamePathMapper getNamePathMapper() {
            return namePathMapper;
        }

        @Override
        public NodeTypeManager getNodeTypeManager() throws RepositoryException {
            return getWorkspace().getNodeTypeManager();
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.oak.jcr.SessionImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.