Package org.apache.jackrabbit.oak.jcr

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

/*
* 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.commons.AbstractSession;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.Connection;
import org.apache.jackrabbit.oak.jcr.state.NodeStateProvider;
import org.apache.jackrabbit.oak.jcr.state.TransientNodeState;
import org.apache.jackrabbit.oak.jcr.state.TransientSpace;
import org.apache.jackrabbit.oak.jcr.util.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;

import javax.jcr.Credentials;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
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.retention.RetentionManager;
import javax.jcr.security.AccessControlManager;
import java.io.IOException;
import java.security.AccessControlException;

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

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

    private final Repository repository;
    private final Workspace workspace;
    private final Connection connection;
    private final ValueFactory valueFactory;

    private final GlobalContext globalContext;
    private final TransientSpace transientSpace;
    private final NodeStateProvider nodeStateProvider;

    private boolean isAlive = true;

    private final SessionContext<SessionImpl> sessionContext = new Context();

    SessionImpl(GlobalContext globalContext, Connection connection) {

        this.globalContext = globalContext;
        this.connection = connection;

        valueFactory = new ValueFactoryImpl();
        repository = new RepositoryAdaptor(globalContext.getInstance(Repository.class), valueFactory);
        workspace = new WorkspaceImpl(sessionContext);

        transientSpace = new TransientSpace(sessionContext.getWorkspaceName(), sessionContext.getMicrokernel());
        nodeStateProvider = new NodeStateProvider(sessionContext, transientSpace);
    }


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

    @Override
    public Repository getRepository() {
        return repository;
    }

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

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

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

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

    /**
     * @see javax.jcr.Session#impersonate(Credentials)
     */
    @Override
    public Session impersonate(Credentials credentials) throws RepositoryException {
        checkIsAlive();

        // TODO
        return null;
    }

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

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

    @Override
    public Node getRootNode() throws RepositoryException {
        checkIsAlive();
        return NodeImpl.create(sessionContext, Path.create(sessionContext.getWorkspaceName()));
    }

    @Override
    public Item getItem(String absPath) throws RepositoryException {
        if (nodeExists(absPath)) {
            return getNode(absPath);
        }
        else {
            return getProperty(absPath);
        }
    }

    @Override
    public boolean itemExists(String absPath) throws RepositoryException {
        return nodeExists(absPath) || propertyExists(absPath);
    }

    @Override
    public Node getNode(String absPath) throws RepositoryException {
        return NodeImpl.create(sessionContext, Path.create(sessionContext.getWorkspaceName(), absPath));
    }

    @Override
    public boolean nodeExists(String absPath) throws RepositoryException {
        Path path = Path.create(sessionContext.getWorkspaceName(), absPath);
        return path.isRoot() || NodeImpl.exist(sessionContext, path);
    }

    @Override
    public Property getProperty(String absPath) throws RepositoryException {
        if ("/".equals(absPath)) {
            throw new ItemNotFoundException(absPath);
        }

        return PropertyImpl.create(sessionContext, Path.create(sessionContext.getWorkspaceName(), absPath));
    }

    @Override
    public boolean propertyExists(String absPath) throws RepositoryException {
        Path path = Path.create(sessionContext.getWorkspaceName(), absPath);
        return !path.isRoot() && PropertyImpl.exist(sessionContext, path);
    }

    @Override
    public Node getNodeByUUID(String uuid) throws RepositoryException {
        checkIsAlive();

        // TODO
        return null;
    }

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

        // TODO
        return null;
    }

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

    @Override
    public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
        checkIsAlive();
        Path sourcePath = Path.create(sessionContext.getWorkspaceName(), srcAbsPath);
        TransientNodeState sourceParent = nodeStateProvider.getNodeState(sourcePath.getParent());
        if (sourceParent == null) {
            throw new PathNotFoundException(srcAbsPath);
        }

        sourceParent.move(sourcePath.getName(), Path.create(sessionContext.getWorkspaceName(), destAbsPath));
    }

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

    @Override
    public void save() throws RepositoryException {
        checkIsAlive();
        try {
            transientSpace.save();
            connection.commit(connection.getCurrentRoot())// todo: need a better way to update a connection to head
            nodeStateProvider.clear();
        }
        catch (CommitFailedException e) {
            throw new RepositoryException(e);
        }
    }

    @Override
    public void refresh(boolean keepChanges) throws RepositoryException {
        checkIsAlive();
        try {
            transientSpace.refresh(keepChanges);
            connection.commit(connection.getCurrentRoot())// todo: need a better way to update a connection to head
            nodeStateProvider.clear();
        }
        catch (CommitFailedException e) {
            throw new RepositoryException(e);
        }
    }

    @Override
    public boolean hasPendingChanges() throws RepositoryException {
        checkIsAlive();
        return transientSpace.isDirty();
    }

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

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


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

        isAlive = false;
        // TODO

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

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

    @Override
    public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws RepositoryException {
        checkIsAlive();

        // TODO
        return null;
    }

    //------------------------------------------------------------< 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 {
        checkIsAlive();

        // 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 {
        checkIsAlive();

        // TODO
        return false;
    }

    @Override
    public AccessControlManager getAccessControlManager() throws RepositoryException {
        checkIsAlive();

        // TODO
        return null;
    }

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

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

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

    /**
     * Performs a sanity check on this session.
     *
     * @throws RepositoryException if this session has been rendered invalid
     * for some reason (e.g. if this session has been closed explicitly by logout)
     */
    void checkIsAlive() 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.
     *
     * @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 checkSupportedOption(String option) throws RepositoryException {
        if (!isSupportedOption(option)) {
            throw new UnsupportedRepositoryOperationException(option + " is not supported by this repository.");
        }
    }

    /**
     * Checks if this session has pending changes.
     *
     * @throws InvalidItemStateException if this nodes session has pending changes
     * @throws RepositoryException
     */
    void checkHasPendingChanges() 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<SessionImpl> {

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

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

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

        @Override
        public Connection getConnection() {
            return connection;
        }

        @Override
        public MicroKernel getMicrokernel() {
            return globalContext.getInstance(MicroKernel.class);
        }

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

        @Override
        public NodeStateProvider getNodeStateProvider() {
            return nodeStateProvider;
        }
    }
}
TOP

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

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.