package org.dcache.pool.repository.v5; import java.io.IOException; import java.net.URI; import java.util.EnumSet; import java.util.Set; import diskCacheV111.util.CacheException; import diskCacheV111.util.PnfsHandler; import org.dcache.namespace.FileAttribute; import org.dcache.pool.movers.IoMode; import org.dcache.pool.repository.ReplicaRecord; import org.dcache.pool.repository.ReplicaDescriptor; import org.dcache.pool.repository.RepositoryChannel; import org.dcache.util.Checksum; import org.dcache.vehicles.FileAttributes; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.unmodifiableIterable; class ReadHandleImpl implements ReplicaDescriptor { private final PnfsHandler _pnfs; private final ReplicaRecord _entry; private FileAttributes _fileAttributes; private boolean _open; ReadHandleImpl(PnfsHandler pnfs, ReplicaRecord entry, FileAttributes fileAttributes) { _pnfs = checkNotNull(pnfs); _entry = checkNotNull(entry); _fileAttributes = checkNotNull(fileAttributes); _open = true; } /** * Shutdown EntryIODescriptor. All further attempts to use * descriptor will throw IllegalStateException. * @throws IllegalStateException if EntryIODescriptor is closed. */ @Override public synchronized void close() throws IllegalStateException { if (!_open) { throw new IllegalStateException("Handle is closed"); } _entry.decrementLinkCount(); _open = false; } @Override public RepositoryChannel createChannel() throws IOException { return _entry.openChannel(IoMode.READ); } /** * @return disk file * @throws IllegalStateException if EntryIODescriptor is closed. */ @Override public synchronized URI getReplicaFile() throws IllegalStateException { if (!_open) { throw new IllegalStateException("Handle is closed"); } return _entry.getReplicaUri(); } @Override public synchronized FileAttributes getFileAttributes() throws IllegalStateException { return _fileAttributes; } @Override public synchronized Iterable<Checksum> getChecksums() throws CacheException { if (_fileAttributes.isUndefined(FileAttribute.CHECKSUM)) { Set<Checksum> checksums = _pnfs.getFileAttributes( _entry.getPnfsId(), EnumSet.of(FileAttribute.CHECKSUM)).getChecksums(); synchronized (_entry) { _fileAttributes = _entry.getFileAttributes(); if (_fileAttributes.isUndefined(FileAttribute.CHECKSUM)) { _fileAttributes.setChecksums(checksums); _entry.update(r -> r.setFileAttributes(_fileAttributes)); } } } return unmodifiableIterable(_fileAttributes.getChecksums()); } @Override public void addChecksums(Iterable<Checksum> checksums) { throw new IllegalStateException("Read-only handle"); } @Override public void setLastAccessTime(long time) { throw new IllegalStateException("Read-only handle"); } @Override public long getReplicaSize() { return _entry.getReplicaSize(); } @Override public void commit() throws IllegalStateException, InterruptedException, CacheException { // NOP } @Override public void allocate(long size) throws IllegalStateException, IllegalArgumentException, InterruptedException { throw new IllegalStateException("Read-only handle"); } @Override public boolean allocateNow(long size) throws IllegalStateException, IllegalArgumentException, InterruptedException { throw new IllegalStateException("Read-only handle"); } @Override public void free(long size) throws IllegalStateException, IllegalArgumentException { throw new IllegalStateException("Read-only handle"); } }