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.FedoraSession;
021import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
022import org.fcrepo.kernel.api.exception.TombstoneException;
023import org.fcrepo.kernel.modeshape.TombstoneImpl;
024import org.modeshape.jcr.api.JcrTools;
025
026import javax.jcr.Node;
027import javax.jcr.RepositoryException;
028import javax.jcr.Session;
029
030import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_PAIRTREE;
031import static org.fcrepo.kernel.modeshape.FedoraSessionImpl.getJcrSession;
032import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getClosestExistingAncestor;
033import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER;
034
035
036/**
037 * @author bbpennel
038 * @author ajs6f
039 * @since Feb 20, 2014
040 */
041public class AbstractService {
042    protected final static JcrTools jcrTools = new JcrTools();
043
044    protected Node findOrCreateNode(final FedoraSession session,
045                                    final String path,
046                                    final String finalNodeType) throws RepositoryException {
047
048        final Session jcrSession = getJcrSession(session);
049        final Node preexistingNode = getClosestExistingAncestor(jcrSession, path);
050
051        if (TombstoneImpl.hasMixin(preexistingNode)) {
052            throw new TombstoneException(new TombstoneImpl(preexistingNode));
053        }
054
055        final Node node = jcrTools.findOrCreateNode(jcrSession, path, NT_FOLDER, finalNodeType);
056
057        if (node.isNew()) {
058            tagHierarchyWithPairtreeMixin(preexistingNode, node);
059        }
060
061        return node;
062    }
063
064    protected Node findNode(final FedoraSession session, final String path) {
065        final Session jcrSession = getJcrSession(session);
066        try {
067            return jcrSession.getNode(path);
068        } catch (final RepositoryException e) {
069            throw new RepositoryRuntimeException(e);
070        }
071    }
072
073    /**
074     * Tag a hierarchy with {@link org.fcrepo.kernel.api.FedoraTypes#FEDORA_PAIRTREE}
075     * @param baseNode Top most ancestor that should not be tagged
076     * @param createdNode Node whose parents should be tagged up to but not including {@code baseNode}
077     * @throws RepositoryException if repository exception occurred
078     */
079    public static void tagHierarchyWithPairtreeMixin(final Node baseNode, final Node createdNode)
080            throws RepositoryException {
081        Node parent = createdNode.getParent();
082
083        while (parent.isNew() && !parent.equals(baseNode)) {
084            parent.addMixin(FEDORA_PAIRTREE);
085            parent = parent.getParent();
086        }
087    }
088
089    /** test node existence at path
090     *
091     * @param session the session
092     * @param path the path
093     * @return whether T exists at the given path
094     */
095    public boolean exists(final FedoraSession session, final String path) {
096        final Session jcrSession = getJcrSession(session);
097        try {
098            return jcrSession.nodeExists(path);
099        } catch (final RepositoryException e) {
100            throw new RepositoryRuntimeException(e);
101        }
102    }
103}