Skip to content

Commit 6f91842

Browse files
committed
MCR-3126 update OCFL
* update ocfl-java version * support file size * support filekey
1 parent 746cf62 commit 6f91842

23 files changed

+464
-219
lines changed

mycore-ocfl/src/main/java/org/mycore/ocfl/niofs/MCROCFLFileAttributes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.mycore.datamodel.niofs.MCRFileAttributes;
2626
import org.mycore.datamodel.niofs.MCRVersionedPath;
2727

28+
// TODO javadoc
2829
public class MCROCFLFileAttributes implements MCRFileAttributes<Object> {
2930

3031
private final FileTime creationTime;

mycore-ocfl/src/main/java/org/mycore/ocfl/niofs/MCROCFLFileSystemProvider.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.nio.channels.SeekableByteChannel;
2424
import java.nio.file.AccessMode;
2525
import java.nio.file.CopyOption;
26+
import java.nio.file.DirectoryNotEmptyException;
2627
import java.nio.file.DirectoryStream;
2728
import java.nio.file.DirectoryStream.Filter;
2829
import java.nio.file.FileAlreadyExistsException;
@@ -97,7 +98,8 @@ void init() throws IOException {
9798
.getSingleInstanceOfOrThrow(MCROCFLTransactionalTempFileStorage.class, tempFileClassProperty);
9899
Files.createDirectories(this.localStorage.getRoot());
99100
boolean remote = MCRConfiguration2.getBoolean(configurationPrefix + "FS.Remote").orElseThrow();
100-
this.virtualObjectProvider = new MCROCFLVirtualObjectProvider(getRepository(), localStorage, remote);
101+
this.virtualObjectProvider
102+
= new MCROCFLVirtualObjectProvider(getRepository(), localStorage, remote);
101103
} catch (Exception exception) {
102104
throw new IOException("Unable to create MCROCFLFileSystem.", exception);
103105
}
@@ -245,7 +247,7 @@ public void copy(MCRVersionedPath source, MCRVersionedPath target, CopyOption...
245247
throw new NoSuchFileException(source.toString());
246248
}
247249
if (virtualSource.isDirectory(source)) {
248-
createDirectory(target);
250+
copyDirectory(target, options);
249251
} else {
250252
copyFile(source, target, options);
251253
}
@@ -291,9 +293,6 @@ public void move(MCRVersionedPath source, MCRVersionedPath target, CopyOption...
291293
delete(source);
292294
}
293295

294-
/**
295-
* {@inheritDoc}
296-
*/
297296
private void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOption... options) throws IOException {
298297
MCROCFLVirtualObject virtualSource = virtualObjectProvider().get(source);
299298
MCROCFLVirtualObject virtualTarget = virtualObjectProvider().getWritable(target);
@@ -304,11 +303,26 @@ private void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOpti
304303
}
305304
if (virtualSource.equals(virtualTarget)) {
306305
// same virtual object
307-
virtualSource.copyFile(source, target, options);
306+
virtualSource.copy(source, target, options);
308307
} else {
309308
// different virtual object
310-
virtualSource.copyFileToVirtualObject(virtualTarget, source, target, options);
309+
virtualSource.externalCopy(virtualTarget, source, target, options);
310+
}
311+
}
312+
313+
private void copyDirectory(MCRVersionedPath target, CopyOption... options)
314+
throws IOException {
315+
MCROCFLVirtualObject virtualTarget = virtualObjectProvider().getWritable(target);
316+
boolean targetExists = virtualTarget.exists(target);
317+
boolean replaceExisting = Arrays.asList(options).contains(StandardCopyOption.REPLACE_EXISTING);
318+
if (targetExists && replaceExisting) {
319+
boolean targetIsDirectory = virtualTarget.isDirectory(target);
320+
boolean targetDirectoryIsEmpty = virtualTarget.isDirectoryEmpty(target);
321+
if (targetIsDirectory && !targetDirectoryIsEmpty) {
322+
throw new DirectoryNotEmptyException(target.toString());
323+
}
311324
}
325+
createDirectory(target);
312326
}
313327

314328
/**

mycore-ocfl/src/main/java/org/mycore/ocfl/niofs/MCROCFLLocalVirtualObject.java

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,21 @@
3232
import java.util.HashSet;
3333
import java.util.Set;
3434

35+
import org.mycore.common.config.MCRConfiguration2;
3536
import org.mycore.common.digest.MCRDigest;
3637
import org.mycore.common.events.MCREvent;
3738
import org.mycore.datamodel.niofs.MCRVersionedPath;
3839
import org.mycore.ocfl.niofs.storage.MCROCFLTempFileStorage;
3940
import org.mycore.ocfl.repository.MCROCFLRepository;
4041

42+
import io.ocfl.api.model.FileChangeHistory;
4143
import io.ocfl.api.model.ObjectVersionId;
4244
import io.ocfl.api.model.OcflObjectVersion;
4345

4446
/**
45-
* Represents a virtual object stored locally in an OCFL repository.
47+
* Represents a virtual object that is stored on the same drive as the OCFL repository. This provides the implementation
48+
* direct access to the files of the OCFL repository when needed. For example a file can be accessed directly for read
49+
* operations without copying it first to the local storage.
4650
* <p>
4751
* This class extends {@link MCROCFLVirtualObject} and provides implementations specific to local storage.
4852
* It handles file operations such as copying, moving, and deleting files within the local file system,
@@ -90,7 +94,8 @@ public MCROCFLLocalVirtualObject(MCROCFLRepository repository, OcflObjectVersion
9094
* @param directoryTracker the directory tracker.
9195
*/
9296
protected MCROCFLLocalVirtualObject(MCROCFLRepository repository, ObjectVersionId versionId,
93-
OcflObjectVersion objectVersion, MCROCFLTempFileStorage localStorage, boolean readonly,
97+
OcflObjectVersion objectVersion, MCROCFLTempFileStorage localStorage,
98+
boolean readonly,
9499
MCROCFLFileTracker<MCRVersionedPath, MCRDigest> fileTracker,
95100
MCROCFLEmptyDirectoryTracker directoryTracker) {
96101
super(repository, versionId, objectVersion, localStorage, readonly, fileTracker, directoryTracker);
@@ -100,7 +105,7 @@ protected MCROCFLLocalVirtualObject(MCROCFLRepository repository, ObjectVersionI
100105
* {@inheritDoc}
101106
*/
102107
@Override
103-
public void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOption... options) throws IOException {
108+
public void copy(MCRVersionedPath source, MCRVersionedPath target, CopyOption... options) throws IOException {
104109
checkPurged(source);
105110
checkReadOnly();
106111
boolean targetExists = exists(target);
@@ -119,7 +124,7 @@ public void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOptio
119124
* {@inheritDoc}
120125
*/
121126
@Override
122-
public void copyFileToVirtualObject(MCROCFLVirtualObject virtualTarget, MCRVersionedPath source,
127+
public void externalCopy(MCROCFLVirtualObject virtualTarget, MCRVersionedPath source,
123128
MCRVersionedPath target, CopyOption... options) throws IOException {
124129
checkPurged(source);
125130
virtualTarget.checkReadOnly();
@@ -172,39 +177,40 @@ protected SeekableByteChannel readOrWriteByteChannel(MCRVersionedPath path, Set<
172177

173178
@Override
174179
public FileTime getModifiedTime(MCRVersionedPath path) throws IOException {
175-
checkPurged(path);
176180
checkExists(path);
177181
Path physicalPath = toPhysicalPath(path);
178182
return Files.readAttributes(physicalPath, BasicFileAttributes.class).lastModifiedTime();
179183
}
180184

181185
@Override
182186
public FileTime getAccessTime(MCRVersionedPath path) throws IOException {
183-
checkPurged(path);
184187
checkExists(path);
185188
Path physicalPath = toPhysicalPath(path);
186189
return Files.readAttributes(physicalPath, BasicFileAttributes.class).lastAccessTime();
187190
}
188191

189-
@Override
190-
public long getSize(MCRVersionedPath path) throws IOException {
191-
checkPurged(path);
192+
/**
193+
* {@inheritDoc}
194+
*/
195+
public Path toPhysicalPath(MCRVersionedPath path) throws IOException {
192196
checkExists(path);
193-
if (isDirectory(path)) {
194-
return 0;
197+
if (this.localStorage.exists(path)) {
198+
return this.localStorage.toPhysicalPath(path);
195199
}
196-
Path physicalPath = toPhysicalPath(path);
197-
return Files.size(physicalPath);
200+
FileChangeHistory changeHistory = getChangeHistory(path);
201+
String storageRelativePath = changeHistory.getMostRecent().getStorageRelativePath();
202+
return getLocalRepositoryPath().resolve(storageRelativePath);
198203
}
199204

200-
@Override
201-
public Object getFileKey(MCRVersionedPath path) throws IOException {
202-
checkPurged(path);
203-
checkExists(path);
204-
// TODO the fileKey between the localstorage and the ocfl repository should always be the same
205-
// this implementation is just a hack for testing
206-
Path physicalPath = toPhysicalPath(path);
207-
return Files.readAttributes(physicalPath, BasicFileAttributes.class).fileKey();
205+
/**
206+
* Returns the local OCFL repository path.
207+
*
208+
* @return the local repository path.
209+
*/
210+
protected Path getLocalRepositoryPath() {
211+
return Path.of(MCRConfiguration2
212+
.getString("MCR.OCFL.Repository." + repository.getId() + ".RepositoryRoot")
213+
.orElseThrow());
208214
}
209215

210216
/**

mycore-ocfl/src/main/java/org/mycore/ocfl/niofs/MCROCFLRemoteVirtualObject.java

Lines changed: 10 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ protected SeekableByteChannel readOrWriteByteChannel(MCRVersionedPath path, Set<
118118
return seekableByteChannel;
119119
}
120120

121+
/**
122+
* {@inheritDoc}
123+
*/
121124
@Override
122125
public FileTime getModifiedTime(MCRVersionedPath path) throws IOException {
123126
checkExists(path);
@@ -129,9 +132,13 @@ public FileTime getModifiedTime(MCRVersionedPath path) throws IOException {
129132
return FileTime.from(changeHistory.getMostRecent().getTimestamp().toInstant());
130133
}
131134

135+
/**
136+
* {@inheritDoc}
137+
*/
132138
@Override
133139
public FileTime getAccessTime(MCRVersionedPath path) throws IOException {
134140
checkExists(path);
141+
// TODO is the localStorage check required? Or does the localVirtualObject take care of that
135142
if (this.localStorage.exists(path)) {
136143
Path physicalPath = this.localStorage.toPhysicalPath(path);
137144
return Files.readAttributes(physicalPath, BasicFileAttributes.class).lastAccessTime();
@@ -140,37 +147,11 @@ public FileTime getAccessTime(MCRVersionedPath path) throws IOException {
140147
return FileTime.from(changeHistory.getMostRecent().getTimestamp().toInstant());
141148
}
142149

143-
@Override
144-
public long getSize(MCRVersionedPath path) throws IOException {
145-
checkExists(path);
146-
if (isDirectory(path)) {
147-
return 0;
148-
}
149-
// TODO right now we just copy and deliver from local storage
150-
// in future versions we should use the database to get the size
151-
localCopy(path);
152-
//if(this.localStorage.exists(path)) {
153-
Path physicalPath = this.localStorage.toPhysicalPath(path);
154-
return Files.size(physicalPath);
155-
//}
156-
}
157-
158-
@Override
159-
public Object getFileKey(MCRVersionedPath path) throws IOException {
160-
checkExists(path);
161-
// TODO rm this
162-
localCopy(path);
163-
// TODO the fileKey between the localstorage and the ocfl repository should always be the same
164-
// this implementation is just a hack for testing
165-
Path physicalPath = toPhysicalPath(path);
166-
return Files.readAttributes(physicalPath, BasicFileAttributes.class).fileKey();
167-
}
168-
169150
/**
170151
* {@inheritDoc}
171152
*/
172153
@Override
173-
public void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOption... options) throws IOException {
154+
public void copy(MCRVersionedPath source, MCRVersionedPath target, CopyOption... options) throws IOException {
174155
checkPurged(source);
175156
checkReadOnly();
176157
boolean targetExists = exists(target);
@@ -183,7 +164,7 @@ public void copyFile(MCRVersionedPath source, MCRVersionedPath target, CopyOptio
183164
* {@inheritDoc}
184165
*/
185166
@Override
186-
public void copyFileToVirtualObject(MCROCFLVirtualObject virtualTarget, MCRVersionedPath source,
167+
public void externalCopy(MCROCFLVirtualObject virtualTarget, MCRVersionedPath source,
187168
MCRVersionedPath target, CopyOption... options) throws IOException {
188169
checkPurged(source);
189170
virtualTarget.checkReadOnly();
@@ -202,7 +183,7 @@ public void copyFileToVirtualObject(MCROCFLVirtualObject virtualTarget, MCRVersi
202183
public Path toPhysicalPath(MCRVersionedPath path) throws IOException {
203184
checkExists(path);
204185
localCopy(path);
205-
return super.toPhysicalPath(path);
186+
return this.localStorage.toPhysicalPath(path);
206187
}
207188

208189
/**

0 commit comments

Comments
 (0)