Package org.apache.jackrabbit.ocm.manager.impl

Source Code of org.apache.jackrabbit.ocm.manager.impl.ObjectContentManagerImpl

/*
* 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.ocm.manager.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.QueryResult;
import javax.jcr.version.VersionHistory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.ocm.exception.IllegalUnlockException;
import org.apache.jackrabbit.ocm.exception.IncorrectPersistentClassException;
import org.apache.jackrabbit.ocm.exception.JcrMappingException;
import org.apache.jackrabbit.ocm.exception.LockedException;
import org.apache.jackrabbit.ocm.exception.ObjectContentManagerException;
import org.apache.jackrabbit.ocm.exception.VersionException;
import org.apache.jackrabbit.ocm.lock.Lock;
import org.apache.jackrabbit.ocm.manager.ObjectContentManager;
import org.apache.jackrabbit.ocm.manager.atomictypeconverter.impl.DefaultAtomicTypeConverterProvider;
import org.apache.jackrabbit.ocm.manager.cache.ObjectCache;
import org.apache.jackrabbit.ocm.manager.cache.impl.RequestObjectCacheImpl;
import org.apache.jackrabbit.ocm.manager.objectconverter.ObjectConverter;
import org.apache.jackrabbit.ocm.manager.objectconverter.impl.ObjectConverterImpl;
import org.apache.jackrabbit.ocm.manager.objectconverter.impl.ProxyManagerImpl;
import org.apache.jackrabbit.ocm.mapper.Mapper;
import org.apache.jackrabbit.ocm.mapper.impl.digester.DigesterMapperImpl;
import org.apache.jackrabbit.ocm.mapper.model.ClassDescriptor;
import org.apache.jackrabbit.ocm.query.Filter;
import org.apache.jackrabbit.ocm.query.Query;
import org.apache.jackrabbit.ocm.query.QueryManager;
import org.apache.jackrabbit.ocm.query.impl.QueryManagerImpl;
import org.apache.jackrabbit.ocm.repository.NodeUtil;
import org.apache.jackrabbit.ocm.version.Version;
import org.apache.jackrabbit.ocm.version.VersionIterator;

/**
*
* Default implementation for
* {@link org.apache.jackrabbit.ocm.manager.ObjectContentManager}
*
* @author Sandro Boehme
* @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart
*         Christophe</a>
* @author Martin Koci
* @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
*/
public class ObjectContentManagerImpl implements ObjectContentManager {
    /**
     * Logger.
     */
    private final static Log log = LogFactory.getLog(ObjectContentManagerImpl.class);

    /**
     * JCR session.
     */
    protected Session session;

    protected Mapper mapper;

    /**
     * The query manager
     */
    protected QueryManager queryManager;

    /**
     * Object Converter
     */
    protected ObjectConverter objectConverter;

    /**
     * Request Cache manager
     */
    protected ObjectCache requestObjectCache;

    /**
     * Creates a new <code>ObjectContentManager</code> that uses the passed in
     * <code>Mapper</code>, and a <code>Session</code>
     *
     * @param mapper
     *            the Mapper component
     * @param session
     *            The JCR session
     */
    public ObjectContentManagerImpl(Session session, Mapper mapper) {
        try {
            this.session = session;
            this.mapper = mapper;
            // Use default setting for the following dependencies
            DefaultAtomicTypeConverterProvider converterProvider = new DefaultAtomicTypeConverterProvider();
            Map atomicTypeConverters = converterProvider.getAtomicTypeConverters();
            this.queryManager = new QueryManagerImpl(mapper, atomicTypeConverters, session.getValueFactory());
            this.requestObjectCache = new RequestObjectCacheImpl();
            this.objectConverter = new ObjectConverterImpl(mapper, converterProvider, new ProxyManagerImpl(), requestObjectCache);

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to instantiate the object content manager", e);

        }

    }

    /**
     * Creates a new <code>ObjectContentManager</code> based on a JCR session
     * and some xml mapping files.
     *
     * @param session
     *            The JCR session
     * @param xmlMappingFiles
     *            the JCR mapping files used mainly to create the
     *            <code>Mapper</code> component
     */
    public ObjectContentManagerImpl(Session session, String[] xmlMappingFiles) {
        try {
            this.session = session;
            this.mapper = new DigesterMapperImpl(xmlMappingFiles);
            DefaultAtomicTypeConverterProvider converterProvider = new DefaultAtomicTypeConverterProvider();
            Map atomicTypeConverters = converterProvider.getAtomicTypeConverters();
            this.queryManager = new QueryManagerImpl(mapper, atomicTypeConverters, session.getValueFactory());
            this.requestObjectCache = new RequestObjectCacheImpl();
            this.objectConverter = new ObjectConverterImpl(mapper, converterProvider, new ProxyManagerImpl(), requestObjectCache);

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to instantiate the object content manager", e);

        }

    }

    /**
     * Creates a new <code>ObjectContentManager</code> based on a JCR session
     * and some xml mapping files.
     *
     * @param session
     *            The JCR session
     * @param xmlMappingFiles
     *            the JCR mapping files used mainly to create the
     *            <code>Mapper</code> component
     */
    public ObjectContentManagerImpl(Session session, InputStream[] xmlMappingFiles) {
        try {
            this.session = session;
            this.mapper = new DigesterMapperImpl(xmlMappingFiles);
            DefaultAtomicTypeConverterProvider converterProvider = new DefaultAtomicTypeConverterProvider();
            Map atomicTypeConverters = converterProvider.getAtomicTypeConverters();
            this.queryManager = new QueryManagerImpl(mapper, atomicTypeConverters, session.getValueFactory());
            this.requestObjectCache = new RequestObjectCacheImpl();
            this.objectConverter = new ObjectConverterImpl(mapper, converterProvider, new ProxyManagerImpl(), requestObjectCache);

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to instantiate the object content manager", e);

        }

    }

    /**
     * Full constructor.
     *
     * @param mapper
     *            the Mapper component
     * @param converter
     *            the <code>ObjectConverter</code> to be used internally
     * @param queryManager
     *            the query manager to used
     * @param session
     *            The JCR session
     */
    public ObjectContentManagerImpl(Mapper mapper, ObjectConverter converter, QueryManager queryManager, ObjectCache requestObjectCache, Session session) {
        this.mapper = mapper;
        this.session = session;
        this.objectConverter = converter;
        this.queryManager = queryManager;
        this.requestObjectCache = requestObjectCache;

    }

    /**
     * Sets the <code>Mapper</code> used by this object content manager.
     *
     * @param mapper
     *            mapping solver
     */
    public void setMapper(Mapper mapper) {
        this.mapper = mapper;
    }

    /**
     * Sets the <code>ObjectConverter</code> that is used internally by this
     * object content manager.
     *
     * @param objectConverter
     *            the internal <code>ObjectConverter</code>
     */
    public void setObjectConverter(ObjectConverter objectConverter) {
        this.objectConverter = objectConverter;
    }

    /**
     * Sets the <code>QueryManager</code> used by the object content manager.
     *
     * @param queryManager
     *            a <code>QueryManager</code>
     */
    public void setQueryManager(QueryManager queryManager) {
        this.queryManager = queryManager;
    }

    public void setRequestObjectCache(ObjectCache requestObjectCache) {
        this.requestObjectCache = requestObjectCache;
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(java.lang.Class,
     *      java.lang.String)
     * @throws org.apache.jackrabbit.ocm.exception.RepositoryException
     *             if the underlying repository has thrown a
     *             javax.jcr.RepositoryException
     * @throws JcrMappingException
     *             if the mapping for the class is not correct
     * @throws ObjectContentManagerException
     *             if the object cannot be retrieved from the path
     */
    public Object getObject(String path) {
        try {
            if (!session.itemExists(path)) {
                return null;
            }
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object at " + path, e);
        }

        Object object = objectConverter.getObject(session, path);
        requestObjectCache.clear();
        return object;

    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(java.lang.Class,
     *      java.lang.String)
     * @throws org.apache.jackrabbit.ocm.exception.RepositoryException
     *             if the underlying repository has thrown a
     *             javax.jcr.RepositoryException
     * @throws JcrMappingException
     *             if the mapping for the class is not correct
     * @throws ObjectContentManagerException
     *             if the object cannot be retrieved from the path
     */
    public Object getObjectByUuid(String uuid) {

        try {
            Node node = session.getNodeByUUID(uuid);
            Object object = objectConverter.getObject(session, node.getPath());
            requestObjectCache.clear();
            return object;

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object with uuid : " + uuid, e);
        }

    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(java.lang.Class,
     *      java.lang.String, java.lang.String)
     */
    public Object getObject(String path, String versionName) {
        String pathVersion = null;
        try {
            if (!session.itemExists(path)) {
                return null;
            }

            Version version = this.getVersion(path, versionName);
            pathVersion = version.getPath() + "/jcr:frozenNode";

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object at " + path + " - version :" + versionName, e);
        }

        Object object = objectConverter.getObject(session, pathVersion);
        requestObjectCache.clear();
        return object;
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(java.lang.Class,
     *      java.lang.String)
     * @throws org.apache.jackrabbit.ocm.exception.RepositoryException
     *             if the underlying repository has thrown a
     *             javax.jcr.RepositoryException
     * @throws JcrMappingException
     *             if the mapping for the class is not correct
     * @throws ObjectContentManagerException
     *             if the object cannot be retrieved from the path
     */
    public Object getObject(Class objectClass, String path) {
        try {
            if (!session.itemExists(path)) {
                return null;
            }
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object at " + path, e);
        }

        Object object = objectConverter.getObject(session, objectClass, path);
        requestObjectCache.clear();
        return object;

    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(java.lang.Class,
     *      java.lang.String, java.lang.String)
     */
    public Object getObject(Class objectClass, String path, String versionName) {
        String pathVersion = null;
        try {
            if (!session.itemExists(path)) {
                return null;
            }

            Version version = this.getVersion(path, versionName);
            pathVersion = version.getPath() + "/jcr:frozenNode";

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object at " + path + " - version :" + versionName, e);
        }

        Object object = objectConverter.getObject(session, objectClass, pathVersion);
        requestObjectCache.clear();
        return object;
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#retrieveAllMappedAttributes(Object)
     */
    public void retrieveAllMappedAttributes(Object object) {
        objectConverter.retrieveAllMappedAttributes(session, object);

    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#retrieveMappedAttribute(Object,
     *      String)
     */
    public void retrieveMappedAttribute(Object object, String attributeName) {
        objectConverter.retrieveMappedAttribute(session, object, attributeName);

    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#insert(java.lang.Object)
     */
    public void insert(Object object) {
        String path = objectConverter.getPath(session, object);

        try {
            if (session.itemExists(path)) {
                Item item = session.getItem(path);
                if (item.isNode()) {
                    if (!((Node) item).getDefinition().allowsSameNameSiblings()) {
                        throw new ObjectContentManagerException("Path already exists and it is not supporting the same name sibling : " + path);
                    }
                } else {
                    throw new ObjectContentManagerException("Path already exists and it is a property : " + path);
                }

            }
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to insert the object at " + path, e);
        }

        objectConverter.insert(session, object);
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#update(java.lang.Object)
     */
    public void update(Object object) {
        String path = objectConverter.getPath(session, object);
        try {
            if (!session.itemExists(path)) {
                throw new ObjectContentManagerException("Path is not existing : " + path);
            } else {
                checkIfNodeLocked(path);
            }
        } catch (javax.jcr.RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to update", e);
        }

        objectConverter.update(session, object);
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#remove(java.lang.String)
     */
    public void remove(String path) {
        try {
            if (!session.itemExists(path)) {
                throw new ObjectContentManagerException("Path does not exist : " + path);
            } else {
                checkIfNodeLocked(path);
            }

            Item item = session.getItem(path);
            item.remove();

        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to remove the object at " + path);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#remove(java.lang.Object)
     */
    public void remove(Object object) {
        this.remove(objectConverter.getPath(session, object));
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#remove(org.apache.jackrabbit.ocm.query.Query)
     */
    public void remove(Query query) {
        try {
            String jcrExpression = this.queryManager.buildJCRExpression(query);
            log.debug("Remove Objects with expression : " + jcrExpression);

            // Since only nodes are sufficient for us to remove,
            // getObjects(query, language) method is not called here.
            NodeIterator nodeIterator = getNodeIterator(jcrExpression, javax.jcr.query.Query.XPATH);
            List nodes = new ArrayList();

            while (nodeIterator.hasNext()) {
                Node node = nodeIterator.nextNode();
                log.debug("Remove node : " + node.getPath());

                // it is not possible to remove nodes from an NodeIterator
                // So, we add the node found in a collection to remove them
                // after
                nodes.add(node);
            }

            // Remove all collection nodes
            for (int i = 0; i < nodes.size(); i++) {
                Node node = (Node) nodes.get(i);
                checkIfNodeLocked(node.getPath());
                try {
                    node.remove();
                } catch (javax.jcr.RepositoryException re) {
                    throw new ObjectContentManagerException("Cannot remove node at path " + node.getPath() + " returned from query " + jcrExpression, re);
                }
            }

        } catch (InvalidQueryException iqe) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Invalid query expression", iqe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object collection", e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#objectExists(java.lang.String)
     */
    public boolean objectExists(String path) {
        try {
            // TODO : Check also if it is an object
            return session.itemExists(path);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to check if the object exist", e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#isPersistent(java.lang.Class)
     */
    public boolean isPersistent(final Class clazz) {

        try {
            ClassDescriptor classDescriptor = mapper.getClassDescriptorByClass(clazz);
            return true;
        } catch (IncorrectPersistentClassException e) {
            return false;
        }

    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObject(org.apache.jackrabbit.ocm.query.Query)
     */
    public Object getObject(Query query) {
        String jcrExpression = this.queryManager.buildJCRExpression(query);
        Collection result = getObjects(jcrExpression, javax.jcr.query.Query.XPATH);

        if (result.size() > 1) {
            throw new ObjectContentManagerException("Impossible to get the object - the query returns more than one object");
        }

        return result.isEmpty() ? null : result.iterator().next();
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObjects(org.apache.jackrabbit.ocm.query.Query)
     */
    public Collection getObjects(Query query) {
        String jcrExpression = this.queryManager.buildJCRExpression(query);
        return getObjects(jcrExpression, javax.jcr.query.Query.XPATH);
    }

    /**
     * Returns a list of objects of that particular class which are directly
     * under that path. This would not return the objects anywhere below the
     * denoted path.
     *
     * @param objectClass
     * @param path
     * @return
     */
    public Collection getObjects(Class objectClass, String path) throws ObjectContentManagerException {
        try {
            if (!session.itemExists(path)) {
                return null;
            }
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the objects at " + path, e);
        }
       
       
        String parentPath = NodeUtil.getParentPath(path);
        if (! parentPath.equals("/")) {
          parentPath = parentPath + "/";
        }
       
        String nodeName = NodeUtil.getNodeName(path);
        // If nodeName is missing then include *.
        if (nodeName == null || nodeName.length() == 0) {
            nodeName = "*";
        }
        Filter filter = queryManager.createFilter(objectClass);
        filter.setScope(parentPath);
        filter.setNodeName(nodeName);
        Query query = queryManager.createQuery(filter);
        return getObjects(query);
            
       
    }
  
    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObjectIterator(org.apache.jackrabbit.ocm.query.Query)
     */
    public Iterator getObjectIterator(Query query) {
        String jcrExpression = this.queryManager.buildJCRExpression(query);
        log.debug("Get Object with expression : " + jcrExpression);
        NodeIterator nodeIterator = getNodeIterator(jcrExpression, javax.jcr.query.Query.XPATH);

        return new ObjectIterator(nodeIterator, this.objectConverter, this.session);

    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getObjectIterator(String,
     *      String)
     */
    public Iterator getObjectIterator(String query, String language) {
        log.debug("Get Object with expression : " + query);
        NodeIterator nodeIterator = getNodeIterator(query, language);

        return new ObjectIterator(nodeIterator, this.objectConverter, this.session);
    }

    public Collection getObjects(String query, String language) {
        try {
            log.debug("Get Objects with expression : " + query + " and language " + language);

            NodeIterator nodeIterator = getNodeIterator(query, language);

            List result = new ArrayList();
            while (nodeIterator.hasNext()) {
                Node node = nodeIterator.nextNode();
                log.debug("Node found : " + node.getPath());
                result.add(objectConverter.getObject(session, node.getPath()));
            }
            requestObjectCache.clear();
            return result;
        } catch (InvalidQueryException iqe) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Invalid query expression", iqe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the object collection", e);
        }
    }

    private NodeIterator getNodeIterator(String query, String language) {
        if (log.isDebugEnabled()) {
            log.debug("Get Node Iterator with expression " + query + " and language " + language);
        }
        javax.jcr.query.Query jcrQuery;
        try {
            jcrQuery = session.getWorkspace().getQueryManager().createQuery(query, language);
            QueryResult queryResult = jcrQuery.execute();
            NodeIterator nodeIterator = queryResult.getNodes();
            return nodeIterator;
        } catch (InvalidQueryException iqe) {
            throw new org.apache.jackrabbit.ocm.exception.InvalidQueryException(iqe);
        } catch (RepositoryException re) {
            throw new ObjectContentManagerException(re.getMessage(), re);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#checkin(java.lang.String)
     */
    public void checkin(String path) {
        this.checkin(path, null);
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#checkin(java.lang.String,
     *      java.lang.String[])
     */
    public void checkin(String path, String[] versionLabels) {
        try {
            Node node = (Node) session.getItem(path);
            checkIfNodeLocked(node.getPath());
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }
            javax.jcr.version.Version newVersion = node.checkin();

            if (versionLabels != null) {
                VersionHistory versionHistory = node.getVersionHistory();
                for (int i = 0; i < versionLabels.length; i++) {
                    versionHistory.addVersionLabel(newVersion.getName(), versionLabels[i], false);
                }
            }
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (InvalidItemStateException iise) {
            throw new ObjectContentManagerException("Cannot checking modified object at path " + path, iise);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Impossible to checkin the object " + path, ve);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Cannot checkin unversionable node at path " + path, uroe);
        } catch (LockException le) {
            throw new VersionException("Cannot checkin locked node at path " + path, le);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to checkin the object " + path, e);
        }

    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#checkout(java.lang.String)
     */
    public void checkout(String path) {
        Node node = null;
        try {
            node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            node.checkout();
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Cannot checkout unversionable node at path " + path, uroe);
        } catch (LockException le) {
            throw new VersionException("Cannot checkout locked node at path " + path, le);
        } catch (javax.jcr.RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to checkout the object " + path, e);
        }

    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#addVersionLabel(java.lang.String,
     *      java.lang.String, java.lang.String)
     */
    public void addVersionLabel(String path, String versionName, String versionLabel) {
        try {
            Node node = (Node) session.getItem(path);
            checkIfNodeLocked(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();
            history.addVersionLabel(versionName, versionLabel, false);
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Impossible to add a new version label to  " + path + " - version name : " + versionName, ve);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to add a new version label to  " + path + " - version name : " + versionName, uroe);
        } catch (javax.jcr.RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getVersion(java.lang.String,
     *      java.lang.String)
     */
    public Version getVersion(String path, String versionName) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();

            return new Version(history.getVersion(versionName));
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("The version name " + versionName + "does not exist", ve);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to retrieve versions for path " + path, uroe);
        } catch (javax.jcr.RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getVersionLabels(java.lang.String,
     *      java.lang.String)
     */
    public String[] getVersionLabels(String path, String versionName) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();
            javax.jcr.version.Version version = history.getVersion(versionName);

            return history.getVersionLabels(version);
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Impossible to get the version labels : " + path + " - version name : " + versionName, ve);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to retrieve versions for path " + path, uroe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getAllVersionLabels(java.lang.String)
     */
    public String[] getAllVersionLabels(String path) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();

            return history.getVersionLabels();
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to retrieve version history for path " + path, uroe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getAllVersions(java.lang.String)
     */
    public VersionIterator getAllVersions(String path) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();

            return new VersionIterator(history.getAllVersions());
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to retrieve version history for path " + path, uroe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getRootVersion(java.lang.String)
     */
    public Version getRootVersion(String path) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            VersionHistory history = node.getVersionHistory();

            return new Version(history.getRootVersion());
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to get the root version  for the object " + path, uroe);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getBaseVersion(java.lang.String)
     */
    public Version getBaseVersion(String path) {
        try {
            Node node = (Node) session.getItem(path);
            if (!node.isNodeType("mix:versionable")) {
                throw new VersionException("The object " + path + "is not versionable");
            }

            return new Version(node.getBaseVersion());
        } catch (ClassCastException cce) {
            throw new ObjectContentManagerException("Cannot retrieve an object from a property path " + path);
        } catch (PathNotFoundException pnfe) {
            throw new ObjectContentManagerException("Cannot retrieve an object at path " + path, pnfe);
        } catch (UnsupportedRepositoryOperationException uroe) {
            throw new VersionException("Impossible to get the base version for the object " + path, uroe);
        } catch (javax.jcr.RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#lock(java.lang.String,
     *      java.lang.Object, boolean, boolean)
     */
    public Lock lock(final String absPath, final boolean isDeep, final boolean isSessionScoped) throws LockedException {
        try {

            // Calling this method will throw exception if node is locked
            // and this operation cant be done (exception translation)
            checkIfNodeLocked(absPath);

            Node node = getNode(absPath);
            javax.jcr.lock.Lock lock = node.lock(isDeep, isSessionScoped);

            return new Lock(lock);
        } catch (LockException e) {
            // Only one case with LockException remains: if node is not
            // mix:lockable, propably error in custom node types definitions
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Node of type is not type mix:lockable", e);
        } catch (RepositoryException e) {
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e.getMessage(), e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#unlock(java.lang.String,
     *      java.lang.Object, java.lang.String)
     */
    public void unlock(final String absPath, final String lockToken) throws IllegalUnlockException {
        String lockOwner = null;
        try {
            maybeAddLockToken(lockToken);

            Node node = getNode(absPath);
            if (node.isLocked() == false) {
                // Safe - if not locked return
                return;
            }

            javax.jcr.lock.Lock lock = node.getLock();
            lockOwner = lock.getLockOwner();

            node.unlock();
        } catch (LockException e) {
            // LockException if this node does not currently hold a lock (see
            // upper code)
            // or holds a lock for which this Session does not have the correct
            // lock token
            log.error("Cannot unlock path: " + absPath + " Jcr user: " + session.getUserID() + " has no lock token to do this. Lock was placed with user: " + lockOwner);
            throw new IllegalUnlockException(lockOwner, absPath);
        } catch (RepositoryException e) {
            // This also catch UnsupportedRepositoryOperationException - we
            // assume that implementation supports it (jackrabbit does)
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException(e.getMessage(), e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#isLocked(java.lang.String)
     */
    public boolean isLocked(final String absPath) {
        try {
            final Node node = getNode(absPath);

            return node.isLocked();
        } catch (RepositoryException e) {
            // node.isLocked() RepositoryException if an error occurs.
            throw new org.apache.jackrabbit.ocm.exception.RepositoryException("An exception was thrown while checking the lock at path : " + absPath, e);
        }
    }

    /**
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#getQueryManager()
     */
    public QueryManager getQueryManager() {
        return this.queryManager;
    }

    /**
     * Throws {@link LockedException} id node is locked so alter nopde cannot be
     * done
     *
     * @param absPath
     *            abs path to node
     * @throws RepositoryException
     * @throws LockedException
     *             if node is locked
     */
    protected void checkIfNodeLocked(final String absPath) throws RepositoryException, LockedException {
        Node node = getNode(absPath);

        // Node can hold nock or can be locked with precedencor
        if (node.isLocked()) {
            javax.jcr.lock.Lock lock = node.getLock();
            String lockOwner = lock.getLockOwner();

            if (!session.getUserID().equals(lockOwner)) {
                final String path = lock.getNode().getPath();
                throw new LockedException(lockOwner, path);
            }
        }
    }

    protected void maybeAddLockToken(final String lockToken) {
        if (lockToken != null) {
            // This user (this instance of PM) potentionally placed lock so
            // session already has lock token
            final String[] lockTokens = getSession().getLockTokens();
            if (lockTokens != null) {
                for (int i = 0; i < lockTokens.length; i++) {
                    if (lockTokens[i].equals(lockToken)) {
                        // we are already holding a lock
                        break;
                    }
                }
            } else {
                getSession().addLockToken(lockToken);
            }
        }
    }

    protected Node getNode(final String absPath) throws PathNotFoundException, RepositoryException {
        if (!getSession().itemExists(absPath)) {
            throw new ObjectContentManagerException("No object stored on path: " + absPath);
        }
        Item item = getSession().getItem(absPath);
        if (!item.isNode()) {
            throw new ObjectContentManagerException("No object stored on path: " + absPath + " on absPath is item (leaf)");
        }

        return (Node) item;
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#logout()
     */
    public void logout() {
        try {
            log.debug("Logout. Persisting current session changes.");
            this.session.save();
            this.session.logout();
            log.debug("Session closed");
        } catch (NoSuchNodeTypeException nsnte) {
            throw new JcrMappingException("Cannot persist current session changes. An unknown node type was used.", nsnte);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Cannot persist current session changes. Attempt to overwrite checked-in node", ve);
        } catch (LockException le) {
            throw new ObjectContentManagerException("Cannot persist current session changes. Violation of a lock detected", le);
        } catch (javax.jcr.RepositoryException e) {
            throw new ObjectContentManagerException("Cannot persist current session changes.", e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#save()
     */
    public void save() {
        try {
            this.session.save();
        } catch (NoSuchNodeTypeException nsnte) {
            throw new JcrMappingException("Cannot persist current session changes. An unknown node type was used.", nsnte);
        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Cannot persist current session changes. Attempt to overwrite checked-in node", ve);
        } catch (LockException le) {
            throw new ObjectContentManagerException("Cannot persist current session changes. Violation of a lock detected", le);
        } catch (RepositoryException e) {
            throw new ObjectContentManagerException("Cannot persist current session changes.", e);
        }
    }

    /**
     * @return The JCR Session
     */
    public Session getSession() {
        return this.session;
    }

    public void refresh(boolean keepChanges) {
        try {
            session.refresh(keepChanges);
        } catch (RepositoryException e) {
            throw new ObjectContentManagerException("Cannot refresh current session ", e);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#move(java.lang.String,
     *      java.lang.String)
     */
    public void move(String srcPath, String destPath) {
        Workspace workspace = session.getWorkspace();
        try {

            workspace.move(srcPath, destPath);

        } catch (javax.jcr.nodetype.ConstraintViolationException cve) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + "."
                    + " Violation of a nodetype or attempt to move under a property detected", cve);

        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Cannot move the object from " + srcPath + " to " + destPath + "." + " Parent node of source or destination is versionable and checked in ",
                    ve);

        } catch (javax.jcr.AccessDeniedException ade) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + "." + " Session does not have access permissions", ade);

        } catch (javax.jcr.PathNotFoundException pnf) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + "." + " Node at source or destination does not exist ", pnf);

        } catch (javax.jcr.ItemExistsException ie) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + "." + " It might already exist at destination path.", ie);

        } catch (javax.jcr.lock.LockException le) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + "." + "Violation of a lock detected", le);

        } catch (javax.jcr.RepositoryException re) {
            throw new ObjectContentManagerException("Cannot move the object from " + srcPath + " to " + destPath + ".", re);
        }
    }

    /**
     *
     * @see org.apache.jackrabbit.ocm.manager.ObjectContentManager#copy(java.lang.String,
     *      java.lang.String)
     */
    public void copy(String srcPath, String destPath) {
        Workspace workspace = session.getWorkspace();
        try {
            workspace.copy(srcPath, destPath);

        } catch (javax.jcr.nodetype.ConstraintViolationException cve) {
            throw new ObjectContentManagerException("Cannot copy the object from " + srcPath + " to " + destPath + "."
                    + "Violation of a nodetype or attempt to copy under property detected ", cve);

        } catch (javax.jcr.version.VersionException ve) {
            throw new VersionException("Cannot copy the object from " + srcPath + " to " + destPath + "." + "Parent node of source or destination is versionable and checked in ",
                    ve);

        } catch (javax.jcr.AccessDeniedException ade) {
            throw new ObjectContentManagerException("Cannot copy the object from " + srcPath + " to " + destPath + "." + " Session does not have access permissions", ade);

        } catch (javax.jcr.PathNotFoundException pnf) {
            throw new ObjectContentManagerException("Cannot copy the object from " + srcPath + " to " + destPath + "." + "Node at source or destination does not exist ", pnf);

        } catch (javax.jcr.ItemExistsException ie) {
            throw new ObjectContentManagerException("Cannot copy the object from " + srcPath + " to " + destPath + "." + "It might already exist at destination path.", ie);

        } catch (javax.jcr.lock.LockException le) {
            throw new ObjectContentManagerException("Cannot copy the object from " + srcPath + " to " + destPath + "." + "Violation of a lock detected", le);

        } catch (javax.jcr.RepositoryException re) {
            throw new ObjectContentManagerException("Cannot copy the node from " + srcPath + " to " + destPath + ".", re);
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.ocm.manager.impl.ObjectContentManagerImpl

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.