001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.kernel.impl.models; 007 008import org.fcrepo.kernel.api.RdfStream; 009import org.fcrepo.kernel.api.Transaction; 010import org.fcrepo.kernel.api.cache.UserTypesCache; 011import org.fcrepo.kernel.api.exception.ItemNotFoundException; 012import org.fcrepo.kernel.api.exception.PathNotFoundException; 013import org.fcrepo.kernel.api.exception.PathNotFoundRuntimeException; 014import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 015import org.fcrepo.kernel.api.identifiers.FedoraId; 016import org.fcrepo.kernel.api.models.Binary; 017import org.fcrepo.kernel.api.models.ExternalContent; 018import org.fcrepo.kernel.api.models.FedoraResource; 019import org.fcrepo.kernel.api.models.ResourceFactory; 020import org.fcrepo.persistence.api.PersistentStorageSessionManager; 021import org.fcrepo.persistence.api.exceptions.PersistentItemNotFoundException; 022import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 023 024import java.io.BufferedInputStream; 025import java.io.IOException; 026import java.io.InputStream; 027import java.net.URI; 028import java.util.Collection; 029import java.util.List; 030 031import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_BINARY; 032import static org.fcrepo.kernel.api.models.ExternalContent.PROXY; 033 034 035/** 036 * Implementation of a Non-RDF resource. 037 * 038 * @author bbpennel 039 */ 040public class BinaryImpl extends FedoraResourceImpl implements Binary { 041 042 private static final URI FEDORA_BINARY_URI = URI.create(FEDORA_BINARY.getURI()); 043 044 private String externalHandling; 045 046 private String externalUrl; 047 048 private Long contentSize; 049 050 private String filename; 051 052 private String mimeType; 053 054 private Collection<URI> digests; 055 056 /** 057 * Construct the binary 058 * 059 * @param fedoraID fedora identifier 060 * @param transaction transaction 061 * @param pSessionManager session manager 062 * @param resourceFactory resource factory 063 * @param userTypesCache the user types cache 064 */ 065 public BinaryImpl(final FedoraId fedoraID, 066 final Transaction transaction, 067 final PersistentStorageSessionManager pSessionManager, 068 final ResourceFactory resourceFactory, 069 final UserTypesCache userTypesCache) { 070 super(fedoraID, transaction, pSessionManager, resourceFactory, userTypesCache); 071 } 072 073 @Override 074 public InputStream getContent() { 075 try { 076 if (isProxy() || isRedirect()) { 077 // non-external streams are already buffered 078 return new BufferedInputStream(URI.create(getExternalURL()).toURL().openStream()); 079 } else { 080 return getSession().getBinaryContent(getFedoraId().asResourceId(), getMementoDatetime()); 081 } 082 } catch (final PersistentItemNotFoundException e) { 083 throw new ItemNotFoundException("Unable to find content for " + getId() 084 + " version " + getMementoDatetime(), e); 085 } catch (final PersistentStorageException | IOException e) { 086 throw new RepositoryRuntimeException(e.getMessage(), e); 087 } 088 } 089 090 @Override 091 public long getContentSize() { 092 return contentSize; 093 } 094 095 @Override 096 public Collection<URI> getContentDigests() { 097 if (digests == null) { 098 return null; 099 } 100 return digests; 101 } 102 103 @Override 104 public Boolean isProxy() { 105 return PROXY.equals(externalHandling); 106 } 107 108 @Override 109 public Boolean isRedirect() { 110 return ExternalContent.REDIRECT.equals(externalHandling); 111 } 112 113 @Override 114 public String getExternalURL() { 115 return externalUrl; 116 } 117 118 @Override 119 public String getMimeType() { 120 return mimeType; 121 } 122 123 @Override 124 public String getFilename() { 125 return filename; 126 } 127 128 @Override 129 public FedoraResource getDescription() { 130 try { 131 final FedoraId descId = getFedoraId().asDescription(); 132 if (this.isMemento()) { 133 final var descIdAsMemento = descId.asMemento(getMementoDatetime()); 134 return resourceFactory.getResource(transaction, descIdAsMemento); 135 } 136 return resourceFactory.getResource(transaction, descId); 137 } catch (final PathNotFoundException e) { 138 throw new PathNotFoundRuntimeException(e.getMessage(), e); 139 } 140 } 141 142 /** 143 * @param externalHandling the externalHandling to set 144 */ 145 protected void setExternalHandling(final String externalHandling) { 146 this.externalHandling = externalHandling; 147 } 148 149 /** 150 * @param externalUrl the externalUrl to set 151 */ 152 protected void setExternalUrl(final String externalUrl) { 153 this.externalUrl = externalUrl; 154 } 155 156 /** 157 * @param contentSize the contentSize to set 158 */ 159 protected void setContentSize(final Long contentSize) { 160 this.contentSize = contentSize; 161 } 162 163 /** 164 * @param filename the filename to set 165 */ 166 protected void setFilename(final String filename) { 167 this.filename = filename; 168 } 169 170 /** 171 * @param mimeType the mimeType to set 172 */ 173 protected void setMimeType(final String mimeType) { 174 this.mimeType = mimeType; 175 } 176 177 /** 178 * @param digests the digests to set 179 */ 180 protected void setDigests(final Collection<URI> digests) { 181 this.digests = digests; 182 } 183 184 @Override 185 public List<URI> getSystemTypes(final boolean forRdf) { 186 var types = resolveSystemTypes(forRdf); 187 188 if (types == null) { 189 types = super.getSystemTypes(forRdf); 190 // Add fedora:Binary type. 191 types.add(FEDORA_BINARY_URI); 192 } 193 194 return types; 195 } 196 197 @Override 198 public RdfStream getTriples() { 199 return getDescription().getTriples(); 200 } 201}