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_CONTAINER;
019import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_RESOURCE;
020import static org.fcrepo.kernel.impl.ContainerImpl.hasMixin;
021import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
022import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER;
023import static org.slf4j.LoggerFactory.getLogger;
024
025import javax.jcr.Node;
026import javax.jcr.RepositoryException;
027import javax.jcr.Session;
028
029import org.fcrepo.kernel.models.Container;
030import org.fcrepo.kernel.exception.RepositoryRuntimeException;
031import org.fcrepo.kernel.exception.ResourceTypeException;
032import org.fcrepo.kernel.impl.ContainerImpl;
033import org.fcrepo.kernel.services.ContainerService;
034
035import org.slf4j.Logger;
036import org.springframework.stereotype.Component;
037
038/**
039 * Service for creating and retrieving {@link org.fcrepo.kernel.models.Container} without using the JCR API.
040 *
041 * @author cbeer
042 * @author ajs6f
043 * @since Feb 11, 2013
044 */
045@Component
046public class ContainerServiceImpl extends AbstractService implements ContainerService {
047
048    private static final Logger LOGGER = getLogger(ContainerServiceImpl.class);
049
050    /**
051     * @param path the path
052     * @param session the session
053     * @return A {@link org.fcrepo.kernel.models.Container} with the proffered PID
054     */
055    @Override
056    public Container findOrCreate(final Session session, final String path) {
057        LOGGER.trace("Executing findOrCreateObject() with path: {}", path);
058
059        try {
060            final Node node = findOrCreateNode(session, path, NT_FOLDER);
061
062            if (node.isNew()) {
063                initializeNewObjectProperties(node);
064            }
065
066            return new ContainerImpl(node);
067        } catch (final RepositoryException e) {
068            throw new RepositoryRuntimeException(e);
069        }
070    }
071
072    /**
073     * Retrieve a {@link org.fcrepo.kernel.models.Container} instance by pid and dsid
074     *
075     * @param path the path
076     * @param session the session
077     * @return A {@link org.fcrepo.kernel.models.Container} with the proffered PID
078     */
079    @Override
080    public Container find(final Session session, final String path) {
081        final Node node = findNode(session, path);
082
083        return cast(node);
084    }
085
086    private static void initializeNewObjectProperties(final Node node) {
087        try {
088            LOGGER.debug("Setting object properties on node {}...", node.getPath());
089
090            if (node.canAddMixin(FEDORA_RESOURCE)) {
091                node.addMixin(FEDORA_RESOURCE);
092            }
093
094            if (node.canAddMixin(FEDORA_CONTAINER)) {
095                node.addMixin(FEDORA_CONTAINER);
096            }
097
098        } catch (final RepositoryException e) {
099            LOGGER.warn("Could not decorate {} with {} properties: {} ",
100                    JCR_CONTENT, FEDORA_CONTAINER, e);
101        }
102    }
103
104    @Override
105    public Container cast(final Node node) {
106        assertIsType(node);
107        return new ContainerImpl(node);
108    }
109
110    private static void assertIsType(final Node node) {
111        if (!hasMixin(node)) {
112            throw new ResourceTypeException(node + " can not be used as a object");
113        }
114    }
115
116}