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