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