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     */
071    @Override
072    public FedoraResource find(final Session session, final String path) {
073        try {
074            return new FedoraResourceImpl(session.getNode(path));
075        } catch (final RepositoryException e) {
076            throw new RepositoryRuntimeException(e);
077        }
078    }
079
080    /**
081     * Copy an existing object from the source path to the destination path
082     *
083     * @param session a JCR session
084     * @param source the source path
085     * @param destination the destination path
086     */
087    @Override
088    public void copyObject(final Session session, final String source, final String destination) {
089        try {
090            session.getWorkspace().copy(source, destination);
091        } catch (final RepositoryException e) {
092            throw new RepositoryRuntimeException(e);
093        }
094    }
095
096    /**
097     * Move an existing object from the source path to the destination path
098     *
099     * @param session the session
100     * @param source the source path
101     * @param destination the destination path
102     */
103    @Override
104    public void moveObject(final Session session, final String source, final String destination) {
105        try {
106            final FedoraResource srcResource = find(session, source);
107            final Node sourceNode = srcResource.getNode();
108            final String name = sourceNode.getName();
109            final Node parent = sourceNode.getDepth() > 0 ? sourceNode.getParent() : null;
110
111            session.getWorkspace().move(source, destination);
112
113            if (parent != null) {
114                createTombstone(parent, name);
115            }
116
117        } catch (final RepositoryException e) {
118            throw new RepositoryRuntimeException(e);
119        }
120    }
121
122    private static void createTombstone(final Node parent, final String path) throws RepositoryException {
123        final FedoraResourceImpl fedoraResource = new FedoraResourceImpl(parent);
124        final Node n  = fedoraResource.findOrCreateChild(parent, path, FEDORA_TOMBSTONE);
125        LOGGER.info("Created tombstone at {} ", n.getPath());
126    }
127
128    /**
129     * @param session the session
130     * @return node types
131     */
132    @Override
133    public RdfStream getNodeTypes(final Session session) {
134        try {
135            return new NodeTypeRdfContext(session.getWorkspace().getNodeTypeManager());
136        } catch (final RepositoryException e) {
137            throw new RepositoryRuntimeException(e);
138        }
139    }
140
141    /**
142     * @param session the session
143     * @param cndStream the cnd stream
144     * @throws IOException if io exception occurred
145     */
146    @Override
147    public void registerNodeTypes(final Session session, final InputStream cndStream) throws IOException {
148        try {
149            final NodeTypeManager nodeTypeManager = (NodeTypeManager) session.getWorkspace().getNodeTypeManager();
150            nodeTypeManager.registerNodeTypes(cndStream, true);
151        } catch (final RepositoryException e) {
152            throw new RepositoryRuntimeException(e);
153        }
154    }
155
156    /**
157     * @param session the session
158     * @param path the path
159     */
160    @Override
161    public FedoraResource findOrCreate(final Session session, final String path) {
162        throw new RepositoryRuntimeException("unimplemented");
163    }
164
165    /**
166     * @param node the node
167     * @return the fedora resource
168     */
169    @Override
170    public FedoraResource cast(final Node node) {
171        return new FedoraResourceImpl(node);
172    }
173
174}