Skip to content

Commit ccae480

Browse files
committed
iRODS: Clean up and adjust implementation
1 parent 5820ee1 commit ccae480

15 files changed

+385
-391
lines changed

irods/src/main/java/ch/cyberduck/core/irods/IRODSAttributesFinderFeature.java

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
import org.apache.commons.io.FilenameUtils;
2828
import org.apache.commons.lang3.StringUtils;
29-
import org.irods.irods4j.common.Versioning;
3029
import org.irods.irods4j.high_level.catalog.IRODSQuery;
3130
import org.irods.irods4j.high_level.catalog.IRODSQuery.GenQuery1QueryArgs;
3231
import org.irods.irods4j.high_level.connection.IRODSConnection;
@@ -48,46 +47,42 @@ public IRODSAttributesFinderFeature(final IRODSSession session) {
4847
@Override
4948
public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
5049
try {
51-
final PathAttributes[] attributes = new PathAttributes[1];
5250
final IRODSConnection conn = session.getClient();
53-
if(!IRODSFilesystem.exists(this.session.getClient().getRcComm(), file.getAbsolute())) {
51+
final String logicalPath = file.getAbsolute();
52+
if(!IRODSFilesystem.exists(session.getClient().getRcComm(), logicalPath)) {
5453
throw new NotfoundException(file.getAbsolute());
5554
}
56-
String logicalPath = file.getAbsolute();
57-
String parentPath = FilenameUtils.getFullPathNoEndSeparator(logicalPath);
58-
String fileName = FilenameUtils.getName(logicalPath);
59-
if(Versioning.compareVersions(conn.getRcComm().relVersion.substring(4), "4.3.4") > 0) {
60-
String query = String.format("select DATA_MODIFY_TIME, DATA_CREATE_TIME, DATA_SIZE, DATA_CHECKSUM, DATA_OWNER_NAME, DATA_OWNER_ZONE where COLL_NAME = '%s' and DATA_NAME = '%s'", parentPath, fileName);
61-
List<List<String>> rows = IRODSQuery.executeGenQuery2(conn.getRcComm(), query);
62-
List<String> row = rows.get(0);
63-
attributes[0] = toAttributes(row);
64-
}
65-
else {
66-
GenQuery1QueryArgs input = new GenQuery1QueryArgs();
67-
68-
// select COLL_NAME, DATA_NAME, DATA_ACCESS_TIME
69-
input.addColumnToSelectClause(GenQuery1Columns.COL_D_MODIFY_TIME);
70-
input.addColumnToSelectClause(GenQuery1Columns.COL_D_CREATE_TIME);
71-
input.addColumnToSelectClause(GenQuery1Columns.COL_DATA_SIZE);
72-
input.addColumnToSelectClause(GenQuery1Columns.COL_D_DATA_CHECKSUM);
73-
input.addColumnToSelectClause(GenQuery1Columns.COL_D_OWNER_NAME);
74-
input.addColumnToSelectClause(GenQuery1Columns.COL_D_OWNER_ZONE);
75-
76-
77-
// where COLL_NAME like '/tempZone/home/rods and DATA_NAME = 'atime.txt'
78-
String collNameCondStr = String.format("= '%s'", parentPath);
79-
String dataNameCondStr = String.format("= '%s'", fileName);
80-
input.addConditionToWhereClause(GenQuery1Columns.COL_COLL_NAME, collNameCondStr);
81-
input.addConditionToWhereClause(GenQuery1Columns.COL_DATA_NAME, dataNameCondStr);
82-
83-
StringBuilder output = new StringBuilder();
84-
85-
IRODSQuery.executeGenQuery1(conn.getRcComm(), input, row -> {
86-
attributes[0] = toAttributes(row);
87-
return false;
88-
});
89-
}
90-
return attributes[0];
55+
56+
GenQuery1QueryArgs input = new GenQuery1QueryArgs();
57+
58+
// select DATA_MODIFY_TIME, DATA_CREATE_TIME, DATA_SIZE, DATA_CHECKSUM ...
59+
input.addColumnToSelectClause(GenQuery1Columns.COL_D_MODIFY_TIME);
60+
input.addColumnToSelectClause(GenQuery1Columns.COL_D_CREATE_TIME);
61+
input.addColumnToSelectClause(GenQuery1Columns.COL_DATA_SIZE);
62+
input.addColumnToSelectClause(GenQuery1Columns.COL_D_DATA_CHECKSUM);
63+
64+
// where COLL_NAME = '<parent_path>' and DATA_NAME = '<filename>'
65+
String collNameCondStr = String.format("= '%s'", FilenameUtils.getFullPathNoEndSeparator(logicalPath));
66+
String dataNameCondStr = String.format("= '%s'", FilenameUtils.getName(logicalPath));
67+
input.addConditionToWhereClause(GenQuery1Columns.COL_COLL_NAME, collNameCondStr);
68+
input.addConditionToWhereClause(GenQuery1Columns.COL_DATA_NAME, dataNameCondStr);
69+
70+
final PathAttributes attrs = new PathAttributes();
71+
72+
IRODSQuery.executeGenQuery1(conn.getRcComm(), input, row -> {
73+
attrs.setModificationDate(Long.parseLong(row.get(0)) * 1000); // seconds to ms
74+
attrs.setCreationDate(Long.parseLong(row.get(1)) * 1000);
75+
attrs.setSize(Long.parseLong(row.get(2)));
76+
77+
String checksum = row.get(3);
78+
if(!StringUtils.isEmpty(checksum)) {
79+
attrs.setChecksum(Checksum.parse(checksum));
80+
}
81+
82+
return false;
83+
});
84+
85+
return attrs;
9186
}
9287
catch(IOException | IRODSException e) {
9388
throw new IRODSExceptionMappingService().map("Failure to read attributes of {0}", e, file);
@@ -98,16 +93,16 @@ public PathAttributes find(final Path file, final ListProgressListener listener)
9893
public PathAttributes toAttributes(final List<String> row) {
9994
final IRODSConnection conn = session.getClient();
10095
final PathAttributes attributes = new PathAttributes();
96+
10197
attributes.setModificationDate(Long.parseLong(row.get(0)) * 1000); // seconds to ms
10298
attributes.setCreationDate(Long.parseLong(row.get(1)) * 1000);
10399
attributes.setSize(Long.parseLong(row.get(2)));
100+
104101
String checksum = row.get(3);
105102
if(!StringUtils.isEmpty(checksum)) {
106103
attributes.setChecksum(Checksum.parse(checksum));
107104
}
108105

109-
attributes.setOwner(conn.getRcComm().relVersion);
110-
attributes.setGroup(row.get(5));
111106
return attributes;
112107
}
113108
}

irods/src/main/java/ch/cyberduck/core/irods/IRODSChunkWorker.java

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,85 +15,105 @@
1515
* GNU General Public License for more details.
1616
*/
1717

18+
import org.irods.irods4j.high_level.connection.IRODSConnectionPool;
1819
import org.irods.irods4j.high_level.io.IRODSDataObjectInputStream;
1920
import org.irods.irods4j.high_level.io.IRODSDataObjectOutputStream;
20-
import org.irods.irods4j.high_level.io.IRODSDataObjectStream.SeekDirection;
21+
import org.irods.irods4j.high_level.io.IRODSDataObjectStream;
2122
import org.irods.irods4j.low_level.api.IRODSException;
2223

24+
import java.io.FileInputStream;
25+
import java.io.FileOutputStream;
2326
import java.io.IOException;
24-
import java.io.RandomAccessFile;
27+
import java.io.InputStream;
28+
import java.io.OutputStream;
2529

2630
public class IRODSChunkWorker implements Runnable {
27-
private final Object stream;
28-
private final RandomAccessFile file;
31+
32+
private final IRODSConnectionPool.PoolConnection conn;
33+
private final InputStream in;
34+
private final OutputStream out;
2935
private final long offset;
3036
private final long chunkSize;
3137
private final byte[] buffer;
3238

33-
public IRODSChunkWorker(Object stream, String localfilePath, long offset, long chunkSize, int bufferSize) throws IOException, IRODSException {
34-
this.stream = stream;
35-
this.file = new RandomAccessFile(localfilePath, "rw");
39+
public IRODSChunkWorker(IRODSConnectionPool.PoolConnection conn, InputStream in, OutputStream out, long offset, long chunkSize, int bufferSize) throws IOException, IRODSException {
40+
this.conn = conn;
41+
this.in = in;
42+
this.out = out;
3643
this.offset = offset;
3744
this.chunkSize = chunkSize;
3845
this.buffer = new byte[bufferSize];
39-
40-
41-
file.seek(offset);
4246
}
4347

4448
@Override
4549
public void run() {
4650
try {
47-
if(stream instanceof IRODSDataObjectInputStream) {
48-
IRODSDataObjectInputStream in = (IRODSDataObjectInputStream) (stream);
49-
in.seek((int) offset, SeekDirection.CURRENT);
50-
long remaining = chunkSize;
51-
while(remaining > 0) {
52-
int readLength = (int) Math.min(buffer.length, remaining);
53-
int read = in.read(buffer, 0, readLength);
54-
file.write(buffer, 0, read);
55-
remaining -= read;
56-
}
51+
seek(in);
52+
seek(out);
5753

58-
}
59-
else if(stream instanceof IRODSDataObjectOutputStream) {
60-
IRODSDataObjectOutputStream out = (IRODSDataObjectOutputStream) (stream);
61-
out.seek((int) offset, SeekDirection.CURRENT);
62-
long remaining = chunkSize;
63-
while(remaining > 0) {
64-
int writeLength = (int) Math.min(buffer.length, remaining);
65-
int read = file.read(buffer, 0, writeLength);
66-
if(read == -1) {
67-
break;
68-
}
69-
out.write(buffer, 0, read);
70-
remaining -= read;
54+
long remaining = chunkSize;
55+
while(remaining > 0) {
56+
int count = (int) Math.min(buffer.length, remaining);
57+
58+
int bytesRead = in.read(buffer, 0, count);
59+
if(-1 == bytesRead) {
60+
break;
7161
}
72-
}
73-
else {
74-
throw new IllegalArgumentException("Unsupported stream type");
62+
63+
out.write(buffer, 0, bytesRead);
64+
remaining -= bytesRead;
7565
}
7666
}
7767
catch(IOException | IRODSException e) {
78-
e.printStackTrace();
68+
// TODO Log error
7969
}
80-
try {
81-
close();
70+
finally {
71+
try {
72+
in.close();
73+
}
74+
catch(Exception e) { /* Ignored */ }
75+
try {
76+
out.close();
77+
}
78+
catch(Exception e) { /* Ignored */ }
79+
}
80+
}
81+
82+
private void seek(InputStream in) throws IRODSException, IOException {
83+
if(in instanceof IRODSDataObjectInputStream) {
84+
IRODSDataObjectInputStream stream = (IRODSDataObjectInputStream) in;
85+
long totalOffset = offset;
86+
while(totalOffset > 0) {
87+
if(totalOffset >= Integer.MAX_VALUE) {
88+
totalOffset -= Integer.MAX_VALUE;
89+
stream.seek(Integer.MAX_VALUE, IRODSDataObjectStream.SeekDirection.CURRENT);
90+
}
91+
else {
92+
stream.seek((int) totalOffset, IRODSDataObjectStream.SeekDirection.CURRENT);
93+
}
94+
}
8295
}
83-
catch(IOException e) {
84-
e.printStackTrace();
96+
else if(in instanceof FileInputStream) {
97+
((FileInputStream) in).getChannel().position(offset);
8598
}
8699
}
87100

88-
public void close() throws IOException {
89-
file.close();
90-
if(stream instanceof IRODSDataObjectInputStream) {
91-
IRODSDataObjectInputStream in = (IRODSDataObjectInputStream) (stream);
92-
in.close();
101+
private void seek(OutputStream out) throws IRODSException, IOException {
102+
if(out instanceof IRODSDataObjectOutputStream) {
103+
IRODSDataObjectOutputStream stream = (IRODSDataObjectOutputStream) out;
104+
long totalOffset = offset;
105+
while(totalOffset > 0) {
106+
if(totalOffset >= Integer.MAX_VALUE) {
107+
totalOffset -= Integer.MAX_VALUE;
108+
stream.seek(Integer.MAX_VALUE, IRODSDataObjectStream.SeekDirection.CURRENT);
109+
}
110+
else {
111+
stream.seek((int) totalOffset, IRODSDataObjectStream.SeekDirection.CURRENT);
112+
}
113+
}
93114
}
94-
else if(stream instanceof IRODSDataObjectOutputStream) {
95-
IRODSDataObjectOutputStream out = (IRODSDataObjectOutputStream) (stream);
96-
out.close();
115+
else if(out instanceof FileOutputStream) {
116+
((FileOutputStream) out).getChannel().position(offset);
97117
}
98118
}
99119
}

irods/src/main/java/ch/cyberduck/core/irods/IRODSCopyFeature.java

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@
2222
import ch.cyberduck.core.io.StreamListener;
2323

2424
import org.irods.irods4j.high_level.connection.IRODSConnection;
25-
import org.irods.irods4j.high_level.vfs.CollectionEntry;
26-
import org.irods.irods4j.high_level.vfs.IRODSCollectionIterator;
2725
import org.irods.irods4j.high_level.vfs.IRODSFilesystem;
28-
import org.irods.irods4j.high_level.vfs.ObjectStatus;
29-
import org.irods.irods4j.low_level.api.IRODSApi.RcComm;
3026
import org.irods.irods4j.low_level.api.IRODSException;
3127

3228
import java.io.IOException;
@@ -46,47 +42,18 @@ public Path copy(final Path source, final Path target, final ch.cyberduck.core.t
4642
final IRODSConnection conn = session.getClient();
4743
final String from = source.getAbsolute();
4844
final String to = target.getAbsolute();
49-
if(source.isFile()) {
50-
IRODSFilesystem.copyDataObject(conn.getRcComm(), from, to);
5145

52-
if(listener != null && status.getLength() > 0) {
53-
listener.sent(status.getLength());
54-
}
55-
}
56-
if(source.isDirectory()) {
57-
this.copyDirectoryRecursively(conn.getRcComm(), from, to);
58-
}
46+
// TODO If we're dealing with a collection, should existing data objects sharing
47+
// the same name be overwritten? This should probably be a configurable option.
48+
IRODSFilesystem.copy(conn.getRcComm(), from, to, IRODSFilesystem.CopyOptions.RECURSIVE);
49+
5950
return target;
6051
}
6152
catch(IOException | IRODSException e) {
6253
throw new IRODSExceptionMappingService().map("Cannot copy {0}", e, source);
6354
}
6455
}
6556

66-
public static void copyDirectoryRecursively(RcComm rcComm, String source, String target) throws IOException, IRODSException {
67-
// First, create the root of the target directory
68-
if(!IRODSFilesystem.exists(rcComm, target)) {
69-
IRODSFilesystem.createCollection(rcComm, target);
70-
}
71-
72-
// Recursively iterate through the source collection
73-
for(CollectionEntry entry : new IRODSCollectionIterator(rcComm, source)) {
74-
String relative = entry.path().substring(source.length()); // relative path from source
75-
String targetPath = target + relative;
76-
77-
ObjectStatus status = entry.status();
78-
79-
if(status.getType() == ObjectStatus.ObjectType.COLLECTION) {
80-
// Create directory in target
81-
IRODSFilesystem.createCollection(rcComm, targetPath);
82-
}
83-
else if(status.getType() == ObjectStatus.ObjectType.DATA_OBJECT) {
84-
// Copy file
85-
IRODSFilesystem.copyDataObject(rcComm, entry.path(), targetPath);
86-
}
87-
}
88-
}
89-
9057
@Override
9158
public EnumSet<Flags> features(final Path source, final Path target) {
9259
return EnumSet.of(Flags.recursive);

irods/src/main/java/ch/cyberduck/core/irods/IRODSDeleteFeature.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,27 @@ public void delete(final Map<Path, TransferStatus> files, final PasswordCallback
5353
break;
5454
}
5555
}
56+
5657
if(skip) {
5758
continue;
5859
}
60+
61+
// TODO Shouldn't these be updated after the operation?
5962
deleted.add(file);
6063
callback.delete(file);
61-
final String absolute = file.getAbsolute();
64+
6265
try {
63-
if(!IRODSFilesystem.exists(this.session.getClient().getRcComm(), absolute)) {
66+
String absolute = file.getAbsolute();
67+
ObjectStatus status = IRODSFilesystem.status(this.session.getClient().getRcComm(), absolute);
68+
69+
if(!IRODSFilesystem.exists(status)) {
6470
throw new NotfoundException(String.format("%s doesn't exist", absolute));
6571
}
66-
ObjectStatus status = IRODSFilesystem.status(this.session.getClient().getRcComm(), absolute);
67-
if(status.equals(ObjectType.DATA_OBJECT)) {
72+
73+
if(status.getType() == ObjectType.DATA_OBJECT) {
6874
IRODSFilesystem.remove(this.session.getClient().getRcComm(), absolute, RemoveOptions.NO_TRASH);
6975
}
70-
else if(status.equals(ObjectType.COLLECTION)) {
76+
else if(status.getType() == ObjectType.COLLECTION) {
7177
IRODSFilesystem.removeAll(this.session.getClient().getRcComm(), absolute, RemoveOptions.NO_TRASH);
7278
}
7379
}

irods/src/main/java/ch/cyberduck/core/irods/IRODSDirectoryFeature.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,7 @@ public Path mkdir(final Path folder, final TransferStatus status) throws Backgro
3939
try {
4040
final IRODSConnection conn = session.getClient();
4141
String path = folder.getAbsolute();
42-
boolean created = IRODSFilesystem.createCollection(conn.getRcComm(), path);
43-
if(!created) {
44-
throw new IOException("Failed to create collection: " + path);
45-
}
42+
IRODSFilesystem.createCollection(conn.getRcComm(), path);
4643
return folder;
4744
}
4845
catch(IOException | IRODSFilesystemException e) {

0 commit comments

Comments
 (0)