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