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 static org.fcrepo.kernel.api.FedoraTypes.FEDORA_TOMBSTONE;
021import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode;
022import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touchLdpMembershipResource;
023import static org.fcrepo.kernel.modeshape.utils.NamespaceTools.validatePath;
024import static org.slf4j.LoggerFactory.getLogger;
025
026import javax.jcr.Node;
027import javax.jcr.RepositoryException;
028import javax.jcr.Session;
029
030import org.fcrepo.kernel.api.exception.InvalidResourceIdentifierException;
031import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
032import org.fcrepo.kernel.api.models.FedoraResource;
033import org.fcrepo.kernel.api.services.NodeService;
034import org.fcrepo.kernel.modeshape.FedoraResourceImpl;
035import org.slf4j.Logger;
036import org.springframework.stereotype.Component;
037
038/**
039 * Service for managing access to Fedora 'nodes' (either datastreams or objects, we don't care.)
040 *
041 * @author Chris Beer
042 * @author ajs6f
043 * @since May 9, 2013
044 */
045@Component
046public class NodeServiceImpl extends AbstractService implements NodeService {
047
048    private static final Logger LOGGER = getLogger(NodeServiceImpl.class);
049
050    /* (non-Javadoc)
051     * @see org.fcrepo.kernel.api.services.Service#exists(javax.jcr.Session, java.lang.String)
052     */
053    @Override
054    public boolean exists(final Session session, final String path) {
055        try {
056            validatePath(session, path);
057            return session.nodeExists(path);
058        } catch (final IllegalArgumentException e) {
059            throw new InvalidResourceIdentifierException("Illegal path: " + path);
060        } catch (final RepositoryException e) {
061            throw new RepositoryRuntimeException(e);
062        }
063    }
064
065    /**
066     * Retrieve an existing Fedora resource at the given path
067     *
068     * @param session a JCR session
069     * @param path a JCR path
070     * @return Fedora resource at the given path
071     */
072    @Override
073    public FedoraResource find(final Session session, final String path) {
074        try {
075            return new FedoraResourceImpl(session.getNode(path));
076        } catch (final RepositoryException e) {
077            throw new RepositoryRuntimeException(e);
078        }
079    }
080
081    /**
082     * Copy an existing object from the source path to the destination path
083     *
084     * @param session a JCR session
085     * @param source the source path
086     * @param destination the destination path
087     */
088    @Override
089    public void copyObject(final Session session, final String source, final String destination) {
090        try {
091            session.getWorkspace().copy(source, destination);
092            touchLdpMembershipResource(getJcrNode(find(session, destination)));
093        } catch (final RepositoryException e) {
094            throw new RepositoryRuntimeException(e);
095        }
096    }
097
098    /**
099     * Move an existing object from the source path to the destination path
100     *
101     * @param session the session
102     * @param source the source path
103     * @param destination the destination path
104     */
105    @Override
106    public void moveObject(final Session session, final String source, final String destination) {
107        try {
108            final FedoraResource srcResource = find(session, source);
109            final Node sourceNode = getJcrNode(srcResource);
110            final String name = sourceNode.getName();
111            final Node parent = sourceNode.getDepth() > 0 ? sourceNode.getParent() : null;
112
113            session.getWorkspace().move(source, destination);
114
115            if (parent != null) {
116                createTombstone(parent, name);
117            }
118
119            touchLdpMembershipResource(getJcrNode(find(session, source)));
120            touchLdpMembershipResource(getJcrNode(find(session, destination)));
121
122        } catch (final RepositoryException e) {
123            throw new RepositoryRuntimeException(e);
124        }
125    }
126
127    private static void createTombstone(final Node parent, final String path) throws RepositoryException {
128        final FedoraResourceImpl fedoraResource = new FedoraResourceImpl(parent);
129        final Node n  = fedoraResource.findOrCreateChild(parent, path, FEDORA_TOMBSTONE);
130        LOGGER.info("Created tombstone at {} ", n.getPath());
131    }
132
133    /**
134     * @param session the session
135     * @param path the path
136     */
137    @Override
138    public FedoraResource findOrCreate(final Session session, final String path) {
139        throw new RepositoryRuntimeException("unimplemented");
140    }
141}