001/*
002 * Copyright 2015 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.modeshape.services;
017
018import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_TOMBSTONE;
019import static org.fcrepo.kernel.modeshape.utils.NamespaceTools.validatePath;
020import static org.slf4j.LoggerFactory.getLogger;
021
022import java.io.IOException;
023import java.io.InputStream;
024
025import javax.jcr.Node;
026import javax.jcr.RepositoryException;
027import javax.jcr.Session;
028
029import org.fcrepo.kernel.api.exception.InvalidResourceIdentifierException;
030import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
031import org.fcrepo.kernel.api.models.FedoraResource;
032import org.fcrepo.kernel.api.RdfStream;
033import org.fcrepo.kernel.api.services.NodeService;
034import org.fcrepo.kernel.modeshape.FedoraResourceImpl;
035import org.fcrepo.kernel.modeshape.rdf.impl.NodeTypeRdfContext;
036import org.modeshape.jcr.api.nodetype.NodeTypeManager;
037import org.slf4j.Logger;
038import org.springframework.stereotype.Component;
039
040/**
041 * Service for managing access to Fedora 'nodes' (either datastreams or objects, we don't care.)
042 *
043 * @author Chris Beer
044 * @author ajs6f
045 * @since May 9, 2013
046 */
047@Component
048public class NodeServiceImpl extends AbstractService implements NodeService {
049
050    private static final Logger LOGGER = getLogger(NodeServiceImpl.class);
051
052    /* (non-Javadoc)
053     * @see org.fcrepo.kernel.api.services.Service#exists(javax.jcr.Session, java.lang.String)
054     */
055    @Override
056    public boolean exists(final Session session, final String path) {
057        try {
058            validatePath(session, path);
059            return session.nodeExists(path);
060        } catch (final IllegalArgumentException e) {
061            throw new InvalidResourceIdentifierException("Illegal path: " + path);
062        } catch (final RepositoryException e) {
063            throw new RepositoryRuntimeException(e);
064        }
065    }
066
067    /**
068     * Retrieve an existing Fedora resource at the given path
069     *
070     * @param session a JCR session
071     * @param path a JCR path
072     * @return Fedora resource at the given path
073     */
074    @Override
075    public FedoraResource find(final Session session, final String path) {
076        try {
077            return new FedoraResourceImpl(session.getNode(path));
078        } catch (final RepositoryException e) {
079            throw new RepositoryRuntimeException(e);
080        }
081    }
082
083    /**
084     * Copy an existing object from the source path to the destination path
085     *
086     * @param session a JCR session
087     * @param source the source path
088     * @param destination the destination path
089     */
090    @Override
091    public void copyObject(final Session session, final String source, final String destination) {
092        try {
093            session.getWorkspace().copy(source, destination);
094        } catch (final RepositoryException e) {
095            throw new RepositoryRuntimeException(e);
096        }
097    }
098
099    /**
100     * Move an existing object from the source path to the destination path
101     *
102     * @param session the session
103     * @param source the source path
104     * @param destination the destination path
105     */
106    @Override
107    public void moveObject(final Session session, final String source, final String destination) {
108        try {
109            final FedoraResource srcResource = find(session, source);
110            final Node sourceNode = srcResource.getNode();
111            final String name = sourceNode.getName();
112            final Node parent = sourceNode.getDepth() > 0 ? sourceNode.getParent() : null;
113
114            session.getWorkspace().move(source, destination);
115
116            if (parent != null) {
117                createTombstone(parent, name);
118            }
119
120        } catch (final RepositoryException e) {
121            throw new RepositoryRuntimeException(e);
122        }
123    }
124
125    private static void createTombstone(final Node parent, final String path) throws RepositoryException {
126        final FedoraResourceImpl fedoraResource = new FedoraResourceImpl(parent);
127        final Node n  = fedoraResource.findOrCreateChild(parent, path, FEDORA_TOMBSTONE);
128        LOGGER.info("Created tombstone at {} ", n.getPath());
129    }
130
131    /**
132     * @param session the session
133     * @return node types
134     */
135    @Override
136    @Deprecated
137    public RdfStream getNodeTypes(final Session session) {
138        try {
139            return new NodeTypeRdfContext(session.getWorkspace().getNodeTypeManager());
140        } catch (final RepositoryException e) {
141            throw new RepositoryRuntimeException(e);
142        }
143    }
144
145    /**
146     * @param session the session
147     * @param cndStream the cnd stream
148     * @throws IOException if io exception occurred
149     */
150    @Override
151    @Deprecated
152    public void registerNodeTypes(final Session session, final InputStream cndStream) throws IOException {
153        try {
154            final NodeTypeManager nodeTypeManager = (NodeTypeManager) session.getWorkspace().getNodeTypeManager();
155            nodeTypeManager.registerNodeTypes(cndStream, true);
156        } catch (final RepositoryException e) {
157            throw new RepositoryRuntimeException(e);
158        }
159    }
160
161    /**
162     * @param session the session
163     * @param path the path
164     */
165    @Override
166    public FedoraResource findOrCreate(final Session session, final String path) {
167        throw new RepositoryRuntimeException("unimplemented");
168    }
169
170    /**
171     * @param node the node
172     * @return the fedora resource
173     */
174    @Override
175    public FedoraResource cast(final Node node) {
176        return new FedoraResourceImpl(node);
177    }
178
179}