001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.kernel.modeshape.services; 019 020import org.fcrepo.kernel.api.FedoraSession; 021import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 022import org.fcrepo.kernel.api.exception.ResourceTypeException; 023import org.fcrepo.kernel.api.models.FedoraBinary; 024import org.fcrepo.kernel.api.services.BinaryService; 025import org.fcrepo.kernel.modeshape.FedoraBinaryImpl; 026import org.slf4j.Logger; 027import org.springframework.stereotype.Component; 028 029import javax.jcr.Node; 030import javax.jcr.RepositoryException; 031 032import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_BINARY; 033import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION; 034import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_RESOURCE; 035import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getContainingNode; 036import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touch; 037import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touchLdpMembershipResource; 038import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT; 039import static org.modeshape.jcr.api.JcrConstants.NT_FILE; 040import static org.modeshape.jcr.api.JcrConstants.NT_RESOURCE; 041import static org.slf4j.LoggerFactory.getLogger; 042 043/** 044 * @author cabeer 045 * @author ajs6f 046 * @since 10/10/14 047 */ 048@Component 049public class BinaryServiceImpl extends AbstractService implements BinaryService { 050 051 private static final Logger LOGGER = getLogger(BinaryServiceImpl.class); 052 053 /** 054 * {@inheritDoc} 055 */ 056 @Override 057 public FedoraBinary findOrCreate(final FedoraSession session, final String path) { 058 try { 059 final Node dsNode = findOrCreateNode(session, path, NT_FILE); 060 061 if (dsNode.isNew()) { 062 initializeNewDatastreamProperties(dsNode); 063 064 getContainingNode(dsNode).ifPresent(parent -> { 065 touch(parent); 066 touchLdpMembershipResource(dsNode); 067 }); 068 } 069 070 final FedoraBinaryImpl binary = new FedoraBinaryImpl(dsNode.getNode(JCR_CONTENT)); 071 072 if (dsNode.isNew()) { 073 touch(binary.getNode()); 074 } 075 076 return binary; 077 } catch (final RepositoryException e) { 078 throw new RepositoryRuntimeException(e); 079 } 080 } 081 082 /** 083 * Retrieve a Datastream instance by pid and dsid 084 * 085 * @param path jcr path to the datastream 086 * @return datastream 087 */ 088 @Override 089 public FedoraBinary find(final FedoraSession session, final String path) { 090 try { 091 final Node dsNode = findNode(session, path); 092 093 return cast(dsNode.getNode(JCR_CONTENT)); 094 } catch (final RepositoryException e) { 095 throw new RepositoryRuntimeException(e); 096 } 097 } 098 099 private static void initializeNewDatastreamProperties(final Node node) { 100 try { 101 102 if (node.canAddMixin(FEDORA_RESOURCE)) { 103 node.addMixin(FEDORA_RESOURCE); 104 } 105 106 if (node.canAddMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION)) { 107 node.addMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION); 108 } 109 110 final Node contentNode = jcrTools.findOrCreateChild(node, JCR_CONTENT, NT_RESOURCE); 111 112 if (contentNode.canAddMixin(FEDORA_BINARY)) { 113 contentNode.addMixin(FEDORA_BINARY); 114 } 115 } catch (final RepositoryException e) { 116 LOGGER.warn("Could not decorate {} with datastream properties: {}", node, e); 117 } 118 119 } 120 /** 121 * Retrieve a Datastream instance by pid and dsid 122 * 123 * @param node datastream node 124 * @return node as datastream 125 */ 126 private FedoraBinary cast(final Node node) { 127 assertIsType(node); 128 return new FedoraBinaryImpl(node); 129 } 130 131 private static void assertIsType(final Node node) { 132 if (!FedoraBinaryImpl.hasMixin(node)) { 133 throw new ResourceTypeException(node + " can not be used as a binary"); 134 } 135 } 136 137 138}