001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.kernel.modeshape.services;
019
020import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
021import org.fcrepo.kernel.api.exception.TombstoneException;
022import org.fcrepo.kernel.modeshape.TombstoneImpl;
023import org.modeshape.jcr.api.JcrTools;
024
025import javax.jcr.Node;
026import javax.jcr.RepositoryException;
027import javax.jcr.Session;
028
029import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_PAIRTREE;
030import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getClosestExistingAncestor;
031import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER;
032
033
034/**
035 * @author bbpennel
036 * @author ajs6f
037 * @since Feb 20, 2014
038 */
039public class AbstractService {
040    protected final static JcrTools jcrTools = new JcrTools();
041
042    protected Node findOrCreateNode(final Session session,
043                                    final String path,
044                                    final String finalNodeType) throws RepositoryException {
045
046        final Node preexistingNode = getClosestExistingAncestor(session, path);
047
048        if (TombstoneImpl.hasMixin(preexistingNode)) {
049            throw new TombstoneException(new TombstoneImpl(preexistingNode));
050        }
051
052        final Node node = jcrTools.findOrCreateNode(session, path, NT_FOLDER, finalNodeType);
053
054        if (node.isNew()) {
055            tagHierarchyWithPairtreeMixin(preexistingNode, node);
056        }
057
058        return node;
059    }
060
061    protected Node findNode(final Session session, final String path) {
062        try {
063            return session.getNode(path);
064        } catch (final RepositoryException e) {
065            throw new RepositoryRuntimeException(e);
066        }
067    }
068
069    /**
070     * Tag a hierarchy with {@link org.fcrepo.kernel.api.FedoraTypes#FEDORA_PAIRTREE}
071     * @param baseNode Top most ancestor that should not be tagged
072     * @param createdNode Node whose parents should be tagged up to but not including {@code baseNode}
073     * @throws RepositoryException if repository exception occurred
074     */
075    public static void tagHierarchyWithPairtreeMixin(final Node baseNode, final Node createdNode)
076            throws RepositoryException {
077        Node parent = createdNode.getParent();
078
079        while (parent.isNew() && !parent.equals(baseNode)) {
080            parent.addMixin(FEDORA_PAIRTREE);
081            parent = parent.getParent();
082        }
083    }
084
085    /** test node existence at path
086     *
087     * @param session the session
088     * @param path the path
089     * @return whether T exists at the given path
090     */
091    public boolean exists(final Session session, final String path) {
092        try {
093            return session.nodeExists(path);
094        } catch (final RepositoryException e) {
095            throw new RepositoryRuntimeException(e);
096        }
097    }
098}