| /* |
| * 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.Collections; |
| 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.lock.LockManager; |
| import javax.jcr.nodetype.NoSuchNodeTypeException; |
| import javax.jcr.query.InvalidQueryException; |
| import javax.jcr.query.QueryResult; |
| import javax.jcr.version.VersionHistory; |
| import javax.jcr.version.VersionManager; |
| |
| import org.apache.commons.lang.StringUtils; |
| 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.ManagerConstant; |
| 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; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * |
| * 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 { |
| |
| private final static Logger log = LoggerFactory.getLogger(ObjectContentManagerImpl.class); |
| |
| protected Session session; |
| |
| protected Mapper mapper; |
| |
| protected QueryManager queryManager; |
| |
| protected ObjectConverter objectConverter; |
| |
| 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.nodeExists(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; |
| |
| } |
| |
| /** |
| * @param uuid the <code>uuid</code> of the backing jcr node |
| * @return the Object for <code>uuid</code> |
| * @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 |
| * @throws IllegalArgumentException when the <code>uuid</code> is <code>null</code> or not a valid UUID |
| */ |
| public Object getObjectByUuid(String uuid) { |
| |
| try { |
| Node node = session.getNodeByIdentifier(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); |
| } |
| |
| } |
| |
| /** |
| * |
| * @param path the object's absolute jcr path |
| * @param versionName the version that needs to be fetched |
| * @return the Object for <code>path</code> and version <code>versionName</code> or <code>null</code> if there is no jcr node for the specified |
| * path and versionName |
| * @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 and versionName |
| */ |
| public Object getObject(String path, String versionName) { |
| String pathVersion; |
| try { |
| if (!session.nodeExists(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; |
| } |
| |
| /** |
| * |
| * @param objectClass the object mapping class |
| * @param path the object's absolute jcr path |
| * @return the Object for <code>path</code> pr <code>null</code> if there is no jcr node at <code>path</code> |
| * @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.nodeExists(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; |
| |
| } |
| |
| public Object getObject(Class objectClass, String path, String versionName) { |
| String pathVersion = null; |
| try { |
| if (!session.nodeExists(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; |
| } |
| |
| public void retrieveAllMappedAttributes(Object object) { |
| objectConverter.retrieveAllMappedAttributes(session, object); |
| requestObjectCache.clear(); |
| |
| } |
| |
| public void retrieveMappedAttribute(Object object, String attributeName) { |
| objectConverter.retrieveMappedAttribute(session, object, attributeName); |
| requestObjectCache.clear(); |
| |
| } |
| |
| public void insert(Object object) { |
| String path = objectConverter.getPath(session, object); |
| |
| try { |
| if (session.nodeExists(path)) { |
| Node node = session.getNode(path); |
| if (!node.getDefinition().allowsSameNameSiblings()) { |
| throw new ObjectContentManagerException("Path already exists and it is not supporting the same name sibling : " + path); |
| } |
| } |
| } catch (RepositoryException e) { |
| throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to insert the object at " + path, e); |
| } |
| |
| objectConverter.insert(session, object); |
| } |
| |
| public void update(Object object) { |
| String path = objectConverter.getPath(session, object); |
| try { |
| if (!session.nodeExists(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); |
| } |
| |
| public void remove(String path) { |
| try { |
| if (!session.nodeExists(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); |
| } |
| } |
| |
| public void remove(Object object) { |
| this.remove(objectConverter.getPath(session, object)); |
| } |
| |
| |
| 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. |
| @SuppressWarnings("deprecation") |
| NodeIterator nodeIterator = getNodeIterator(jcrExpression, javax.jcr.query.Query.XPATH); |
| List nodes = new ArrayList(); |
| |
| while (nodeIterator.hasNext()) { |
| Node node = nodeIterator.nextNode(); |
| if (node == null) { |
| // node has been removed possibly by another thread during iterating through the results |
| continue; |
| } |
| 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); |
| } |
| } |
| |
| public boolean objectExists(String path) { |
| try { |
| return session.nodeExists(path); |
| } catch (RepositoryException e) { |
| throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to check if the object exist", e); |
| } |
| } |
| |
| public boolean isPersistent(final Class clazz) { |
| |
| try { |
| ClassDescriptor classDescriptor = mapper.getClassDescriptorByClass(clazz); |
| if (classDescriptor == null) { |
| return false; |
| } |
| return true; |
| } catch (IncorrectPersistentClassException e) { |
| return false; |
| } |
| |
| } |
| |
| public Object getObject(Query query) { |
| String jcrExpression = this.queryManager.buildJCRExpression(query); |
| @SuppressWarnings("deprecation") |
| 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(); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public Collection getObjects(Query query) { |
| String jcrExpression = this.queryManager.buildJCRExpression(query); |
| return getObjects(jcrExpression, javax.jcr.query.Query.XPATH); |
| } |
| |
| public Collection getObjects(Class objectClass, String path) throws ObjectContentManagerException { |
| final ClassDescriptor classDescriptorByClass = mapper.getClassDescriptorByClass(objectClass); |
| if (classDescriptorByClass == null) { |
| log.debug("Cannot get objects because no descriptor class exists for '{}'", objectClass.getClass().getName()); |
| return Collections.emptyList(); |
| } |
| try { |
| if (!session.nodeExists(path)) { |
| log.debug("Cannot get objects '{}' because no node exists at '{}'", objectClass.getClass().getName(), path); |
| return Collections.emptyList(); |
| } |
| Node parentNode = session.getNode(path).getParent(); |
| String nodeName = NodeUtil.getNodeName(path); |
| if (StringUtils.isBlank(nodeName)) { |
| nodeName = null; |
| } |
| NodeIterator candidates = parentNode.getNodes(); |
| List<Node> validated = new ArrayList<Node>(); |
| while (candidates.hasNext()) { |
| Node child = candidates.nextNode(); |
| if (nodeName != null && !child.getName().equals(nodeName)) { |
| continue; |
| } |
| if (child.hasProperty(ManagerConstant.DISCRIMINATOR_CLASS_NAME_PROPERTY)) { |
| if (child.getProperty(ManagerConstant.DISCRIMINATOR_CLASS_NAME_PROPERTY).getString().equals(classDescriptorByClass.getClassName())) { |
| // the discriminator class name matches. This is an object we need |
| validated.add(child); |
| } |
| } else { |
| if (child.getPrimaryNodeType().getName().equals(classDescriptorByClass.getJcrType())) { |
| // nodetype matches |
| validated.add(child); |
| } |
| } |
| } |
| Collection result = new ArrayList(); |
| for (Node n : validated) { |
| Object object = objectConverter.getObject(session, n.getPath()); |
| if (object == null) { |
| log.debug("Could not get object for '{}'", n.getPath()); |
| continue; |
| } |
| // double check whether object is the same or a subclass of objectClass |
| if (objectClass.isAssignableFrom(object.getClass())) { |
| result.add(object); |
| } |
| } |
| return result; |
| } catch (RepositoryException e) { |
| throw new org.apache.jackrabbit.ocm.exception.RepositoryException("Impossible to get the objects at " + path, e); |
| } |
| |
| } |
| |
| public Iterator getObjectIterator(Query query) { |
| String jcrExpression = this.queryManager.buildJCRExpression(query); |
| log.debug("Get Object with expression : " + jcrExpression); |
| @SuppressWarnings("deprecation") |
| NodeIterator nodeIterator = getNodeIterator(jcrExpression, javax.jcr.query.Query.XPATH); |
| |
| return new ObjectIterator(nodeIterator, this.objectConverter, this.session); |
| |
| } |
| |
| 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); |
| } |
| } |
| |
| public void checkin(String path) { |
| this.checkin(path, null); |
| } |
| |
| 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 = getVersionManager().checkin(path); |
| |
| if (versionLabels != null) { |
| VersionHistory versionHistory = getVersionManager().getVersionHistory(path); |
| 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); |
| } |
| |
| } |
| |
| public void checkout(String path) { |
| Node node; |
| try { |
| node = (Node) session.getItem(path); |
| if (!node.isNodeType("mix:versionable")) { |
| throw new VersionException("The object " + path + "is not versionable"); |
| } |
| |
| getVersionManager().checkout(path); |
| } 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); |
| } |
| |
| } |
| |
| 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 = getVersionManager().getVersionHistory(path); |
| 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); |
| } |
| } |
| |
| 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 = getVersionManager().getVersionHistory(path); |
| |
| 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); |
| } |
| } |
| |
| 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 = getVersionManager().getVersionHistory(path); |
| 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); |
| } |
| } |
| |
| public String[] getAllVersionLabels(String path) { |
| try { |
| Node node = session.getNode(path); |
| if (!node.isNodeType("mix:versionable")) { |
| throw new VersionException("The object " + path + "is not versionable"); |
| } |
| |
| VersionHistory history = getVersionManager().getVersionHistory(path); |
| |
| 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); |
| } |
| } |
| |
| public VersionIterator getAllVersions(String path) { |
| try { |
| Node node = session.getNode(path); |
| if (!node.isNodeType("mix:versionable")) { |
| throw new VersionException("The object " + path + "is not versionable"); |
| } |
| |
| VersionHistory history = getVersionManager().getVersionHistory(path); |
| |
| 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); |
| } |
| } |
| |
| public Version getRootVersion(String path) { |
| try { |
| Node node = session.getNode(path); |
| if (!node.isNodeType("mix:versionable")) { |
| throw new VersionException("The object " + path + "is not versionable"); |
| } |
| |
| VersionHistory history = getVersionManager().getVersionHistory(path); |
| |
| 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); |
| } |
| } |
| |
| public Version getBaseVersion(String path) { |
| try { |
| Node node = session.getNode(path); |
| if (!node.isNodeType("mix:versionable")) { |
| throw new VersionException("The object " + path + "is not versionable"); |
| } |
| |
| return new Version(getVersionManager().getBaseVersion(path)); |
| } 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); |
| } |
| } |
| |
| 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); |
| |
| javax.jcr.lock.Lock lock = getLockManager().lock(absPath, isDeep, isSessionScoped, 0L, session.getUserID()); |
| |
| 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); |
| } |
| } |
| |
| public void unlock(final String absPath, final String lockToken) throws IllegalUnlockException { |
| String lockOwner = null; |
| try { |
| maybeAddLockToken(lockToken, absPath); |
| |
| Node node = getNode(absPath); |
| if (node.isLocked() == false) { |
| // Safe - if not locked return |
| return; |
| } |
| |
| javax.jcr.lock.Lock lock = getLockManager().getLock(absPath); |
| lockOwner = lock.getLockOwner(); |
| |
| getLockManager().unlock(absPath); |
| } 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); |
| } |
| } |
| |
| 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); |
| } |
| } |
| |
| 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 lock or can be locked with precedencor |
| if (node.isLocked()) { |
| javax.jcr.lock.Lock lock = getLockManager().getLock(absPath); |
| 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, final String path) { |
| if (lockToken != null) { |
| // This user (this instance of PM) potentionally placed lock so |
| // session already has lock token |
| String[] lockTokens = null; |
| try { |
| lockTokens = getLockManager().getLockTokens(); |
| } catch (UnsupportedRepositoryOperationException ex) { |
| throw new LockedException(session.getUserID(), path); |
| } catch (RepositoryException ex) { |
| throw new org.apache.jackrabbit.ocm.exception.RepositoryException(ex.getMessage(), ex); |
| } |
| if (lockTokens != null) { |
| for (int i = 0; i < lockTokens.length; i++) { |
| if (lockTokens[i].equals(lockToken)) { |
| // we are already holding a lock |
| break; |
| } |
| } |
| } else { |
| try { |
| getLockManager().addLockToken(lockToken); |
| } catch (UnsupportedRepositoryOperationException ex) { |
| throw new LockedException(session.getUserID(), path); |
| } catch (RepositoryException ex) { |
| throw new org.apache.jackrabbit.ocm.exception.RepositoryException(ex.getMessage(), ex); |
| } |
| } |
| } |
| } |
| |
| protected Node getNode(final String absPath) throws PathNotFoundException, RepositoryException { |
| if (!session.nodeExists(absPath)) { |
| throw new ObjectContentManagerException("No object stored on path: " + absPath); |
| } |
| return session.getNode(absPath); |
| } |
| |
| 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); |
| } |
| } |
| |
| 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); |
| } finally { |
| requestObjectCache.clear(); |
| } |
| } |
| |
| 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); |
| } |
| } |
| |
| public void move(String srcPath, String destPath) { |
| try { |
| session.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); |
| } |
| } |
| |
| 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); |
| } |
| } |
| |
| private LockManager getLockManager() throws UnsupportedRepositoryOperationException, RepositoryException { |
| return session.getWorkspace().getLockManager(); |
| } |
| |
| private VersionManager getVersionManager() throws UnsupportedRepositoryOperationException, RepositoryException { |
| return session.getWorkspace().getVersionManager(); |
| } |
| |
| } |