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.impl.services;
017
018import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_TOMBSTONE;
019import static org.fcrepo.kernel.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.models.FedoraResource;
030import org.fcrepo.kernel.exception.RepositoryRuntimeException;
031import org.fcrepo.kernel.impl.FedoraResourceImpl;
032import org.fcrepo.kernel.impl.rdf.impl.NodeTypeRdfContext;
033import org.fcrepo.kernel.services.NodeService;
034import org.fcrepo.kernel.utils.iterators.RdfStream;
035import org.modeshape.jcr.api.nodetype.NodeTypeManager;
036import org.slf4j.Logger;
037import org.springframework.stereotype.Component;
038
039/**
040 * Service for managing access to Fedora 'nodes' (either datastreams or objects, we don't care.)
041 *
042 * @author Chris Beer
043 * @author ajs6f
044 * @since May 9, 2013
045 */
046@Component
047public class NodeServiceImpl extends AbstractService implements NodeService {
048
049    private static final Logger LOGGER = getLogger(NodeServiceImpl.class);
050
051    /* (non-Javadoc)
052     * @see org.fcrepo.kernel.services.Service#exists(javax.jcr.Session, java.lang.String)
053     */
054    @Override
055    public boolean exists(final Session session, final String path) {
056        try {
057            validatePath(session, path);
058            return session.nodeExists(path);
059        } catch (final RepositoryException e) {
060            throw new RepositoryRuntimeException(e);
061        }
062    }
063
064    /**
065     * Retrieve an existing Fedora resource at the given path
066     *
067     * @param session a JCR session
068     * @param path a JCR path
069     * @return Fedora resource at the given path
070     * @throws RepositoryException
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
085     * @param source
086     * @param destination
087     * @throws RepositoryException
088     */
089    @Override
090    public void copyObject(final Session session, final String source, final String destination) {
091        try {
092            session.getWorkspace().copy(source, 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
102     * @param source
103     * @param destination
104     * @throws RepositoryException
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
133     * @return node types
134     * @throws RepositoryException
135     */
136    @Override
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
147     * @param cndStream
148     * @throws RepositoryException
149     * @throws IOException
150     */
151    @Override
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
163     * @param 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
172     */
173    @Override
174    public FedoraResource cast(final Node node) {
175        return new FedoraResourceImpl(node);
176    }
177
178}