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.exception.RepositoryRuntimeException; 021import org.fcrepo.kernel.api.exception.ResourceTypeException; 022import org.fcrepo.kernel.api.models.FedoraBinary; 023import org.fcrepo.kernel.api.services.BinaryService; 024import org.fcrepo.kernel.modeshape.FedoraBinaryImpl; 025import org.slf4j.Logger; 026import org.springframework.stereotype.Component; 027 028import javax.jcr.Node; 029import javax.jcr.RepositoryException; 030import javax.jcr.Session; 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 * Retrieve or create a Datastream instance by pid and dsid 055 * 056 * @param path jcr path to the datastream 057 * @return datastream 058 */ 059 @Override 060 public FedoraBinary findOrCreate(final Session session, final String path) { 061 try { 062 final Node dsNode = findOrCreateNode(session, path, NT_FILE); 063 064 if (dsNode.isNew()) { 065 initializeNewDatastreamProperties(dsNode); 066 067 getContainingNode(dsNode).ifPresent(parent -> { 068 touch(parent); 069 touchLdpMembershipResource(dsNode); 070 }); 071 } 072 073 final FedoraBinaryImpl binary = new FedoraBinaryImpl(dsNode.getNode(JCR_CONTENT)); 074 075 if (dsNode.isNew()) { 076 binary.touch(); 077 } 078 079 return binary; 080 } catch (final RepositoryException e) { 081 throw new RepositoryRuntimeException(e); 082 } 083 } 084 085 /** 086 * Retrieve a Datastream instance by pid and dsid 087 * 088 * @param path jcr path to the datastream 089 * @return datastream 090 */ 091 @Override 092 public FedoraBinary find(final Session session, final String path) { 093 try { 094 final Node dsNode = findNode(session, path); 095 096 return cast(dsNode.getNode(JCR_CONTENT)); 097 } catch (final RepositoryException e) { 098 throw new RepositoryRuntimeException(e); 099 } 100 } 101 102 private static void initializeNewDatastreamProperties(final Node node) { 103 try { 104 105 if (node.canAddMixin(FEDORA_RESOURCE)) { 106 node.addMixin(FEDORA_RESOURCE); 107 } 108 109 if (node.canAddMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION)) { 110 node.addMixin(FEDORA_NON_RDF_SOURCE_DESCRIPTION); 111 } 112 113 final Node contentNode = jcrTools.findOrCreateChild(node, JCR_CONTENT, NT_RESOURCE); 114 115 if (contentNode.canAddMixin(FEDORA_BINARY)) { 116 contentNode.addMixin(FEDORA_BINARY); 117 } 118 } catch (final RepositoryException e) { 119 LOGGER.warn("Could not decorate {} with datastream properties: {}", node, e); 120 } 121 122 } 123 /** 124 * Retrieve a Datastream instance by pid and dsid 125 * 126 * @param node datastream node 127 * @return node as datastream 128 */ 129 private FedoraBinary cast(final Node node) { 130 assertIsType(node); 131 return new FedoraBinaryImpl(node); 132 } 133 134 private static void assertIsType(final Node node) { 135 if (!FedoraBinaryImpl.hasMixin(node)) { 136 throw new ResourceTypeException(node + " can not be used as a binary"); 137 } 138 } 139 140 141}