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 org.fcrepo.kernel.models.FedoraBinary;
019import org.fcrepo.kernel.exception.RepositoryRuntimeException;
020import org.fcrepo.kernel.exception.ResourceTypeException;
021import org.fcrepo.kernel.impl.FedoraBinaryImpl;
022import org.fcrepo.kernel.services.BinaryService;
023import org.slf4j.Logger;
024import org.springframework.stereotype.Component;
025
026import javax.jcr.Node;
027import javax.jcr.RepositoryException;
028import javax.jcr.Session;
029
030import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_BINARY;
031import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION;
032import static org.fcrepo.kernel.FedoraJcrTypes.FEDORA_RESOURCE;
033import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
034import static org.modeshape.jcr.api.JcrConstants.NT_FILE;
035import static org.modeshape.jcr.api.JcrConstants.NT_RESOURCE;
036import static org.slf4j.LoggerFactory.getLogger;
037
038/**
039 * @author cabeer
040 * @author ajs6f
041 * @since 10/10/14
042 */
043@Component
044public class BinaryServiceImpl extends AbstractService implements BinaryService {
045
046    private static final Logger LOGGER = getLogger(BinaryServiceImpl.class);
047
048    /**
049     * Retrieve or create a Datastream instance by pid and dsid
050     *
051     * @param path jcr path to the datastream
052     * @return datastream
053     * @throws javax.jcr.RepositoryException
054     */
055    @Override
056    public FedoraBinary findOrCreate(final Session session, final String path) {
057        try {
058            final Node dsNode = findOrCreateNode(session, path, NT_FILE);
059
060            if (dsNode.isNew()) {
061                initializeNewDatastreamProperties(dsNode);
062            }
063
064            return cast(dsNode.getNode(JCR_CONTENT));
065        } catch (final RepositoryException e) {
066            throw new RepositoryRuntimeException(e);
067        }
068    }
069
070    /**
071     * Retrieve a Datastream instance by pid and dsid
072     *
073     * @param path jcr path to the datastream
074     * @return datastream
075     * @throws javax.jcr.RepositoryException
076     */
077    @Override
078    public FedoraBinary find(final Session session, final String path) {
079        try {
080            final Node dsNode = findNode(session, path);
081
082            return cast(dsNode.getNode(JCR_CONTENT));
083        } catch (final RepositoryException e) {
084            throw new RepositoryRuntimeException(e);
085        }
086    }
087
088    private static void initializeNewDatastreamProperties(final Node node) {
089        try {
090
091            if (node.canAddMixin(FEDORA_RESOURCE)) {
092                node.addMixin(FEDORA_RESOURCE);
093            }
094
095            if (node.canAddMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION)) {
096                node.addMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION);
097            }
098
099            final Node contentNode = jcrTools.findOrCreateChild(node, JCR_CONTENT, NT_RESOURCE);
100
101            if (contentNode.canAddMixin(FEDORA_BINARY)) {
102                contentNode.addMixin(FEDORA_BINARY);
103            }
104        } catch (final RepositoryException e) {
105            LOGGER.warn("Could not decorate {} with datastream properties: {}", node, e);
106        }
107
108    }
109    /**
110     * Retrieve a Datastream instance by pid and dsid
111     *
112     * @param node datastream node
113     * @return node as datastream
114     */
115    @Override
116    public FedoraBinary cast(final Node node) {
117        assertIsType(node);
118        return new FedoraBinaryImpl(node);
119    }
120
121    private static void assertIsType(final Node node) {
122        if (!FedoraBinaryImpl.hasMixin(node)) {
123            throw new ResourceTypeException(node + " can not be used as a binary");
124        }
125    }
126
127
128}