Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 9 additions & 21 deletions irods/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.irods</groupId>
<artifactId>irods4j</artifactId>
<version>0.5.0-java8</version>
</dependency>
<dependency>
<groupId>ch.cyberduck</groupId>
<artifactId>core</artifactId>
Expand All @@ -37,27 +42,10 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ch.iterate.jargon</groupId>
<artifactId>jargon-core</artifactId>
<version>4.2.0.1</version>
<exclusions>
<exclusion>
<groupId>com.claymoresystems</groupId>
<artifactId>puretls</artifactId>
</exclusion>
<exclusion>
<groupId>org.globus.jglobus</groupId>
<artifactId>cog-jglobus</artifactId>
</exclusion>
<exclusion>
<groupId>org.perf4j</groupId>
<artifactId>perf4j</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
<artifactId>testcontainers</artifactId>
<groupId>org.testcontainers</groupId>
<version>1.21.3</version>
<scope>test</scope>
</dependency>
</dependencies>

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ch.cyberduck.core.irods;

/*
* Copyright (c) 2002-2016 iterate GmbH. All rights reserved.
* Copyright (c) 2002-2025 iterate GmbH. All rights reserved.
* https://cyberduck.io/
*
* This program is free software; you can redistribute it and/or modify
Expand All @@ -22,16 +22,22 @@
import ch.cyberduck.core.exception.NotfoundException;
import ch.cyberduck.core.features.AttributesAdapter;
import ch.cyberduck.core.features.AttributesFinder;
import ch.cyberduck.core.io.Checksum;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.irods.jargon.core.exception.JargonException;
import org.irods.jargon.core.pub.IRODSFileSystemAO;
import org.irods.jargon.core.pub.domain.ObjStat;
import org.irods.jargon.core.pub.io.IRODSFile;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.irods.irods4j.high_level.catalog.IRODSQuery;
import org.irods.irods4j.high_level.connection.IRODSConnection;
import org.irods.irods4j.high_level.vfs.IRODSFilesystem;
import org.irods.irods4j.high_level.vfs.LogicalPath;
import org.irods.irods4j.high_level.vfs.ObjectStatus;
import org.irods.irods4j.low_level.api.IRODSException;

public class IRODSAttributesFinderFeature implements AttributesFinder, AttributesAdapter<ObjStat> {
import java.io.IOException;
import java.util.List;

public class IRODSAttributesFinderFeature implements AttributesFinder, AttributesAdapter<List<String>> {

private static final Logger log = LogManager.getLogger(IRODSAttributesFinderFeature.class);

private final IRODSSession session;

Expand All @@ -42,28 +48,76 @@ public IRODSAttributesFinderFeature(final IRODSSession session) {
@Override
public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
try {
final IRODSFileSystemAO fs = session.getClient();
final IRODSFile f = fs.getIRODSFileFactory().instanceIRODSFile(file.getAbsolute());
if(!f.exists()) {
throw new NotfoundException(file.getAbsolute());
log.debug("looking up path attributes.");

final String logicalPath = file.getAbsolute();
final IRODSConnection conn = session.getClient();

ObjectStatus status = IRODSFilesystem.status(conn.getRcComm(), logicalPath);

if(IRODSFilesystem.isDataObject(status)) {
log.debug("data object exists in iRODS. fetching data using GenQuery2.");
String query = String.format(
"select DATA_CREATE_TIME, DATA_MODIFY_TIME, DATA_SIZE, DATA_CHECKSUM, DATA_REPL_STATUS where COLL_NAME = '%s' and DATA_NAME = '%s' order by DATA_REPL_STATUS desc, DATA_MODIFY_TIME desc",
LogicalPath.parentPath(logicalPath),
LogicalPath.objectName(logicalPath));
log.debug("query = [{}]", query);
List<List<String>> rows = IRODSQuery.executeGenQuery2(conn.getRcComm(), query);

PathAttributes attrs = new PathAttributes();

if(!rows.isEmpty()) {
List<String> row = rows.get(0);
if("0".equals(row.get(4)) || "1".equals(row.get(4))) {
setAttributes(attrs, row);
}
}

return attrs;
}
final ObjStat stats = fs.getObjStat(f.getAbsolutePath());
return this.toAttributes(stats);

if(IRODSFilesystem.isCollection(status)) {
log.debug("collection exists in iRODS. fetching data using GenQuery2.");
String query = String.format("select COLL_CREATE_TIME, COLL_MODIFY_TIME where COLL_NAME = '%s'", logicalPath);
log.debug("query = [{}]", query);
List<List<String>> rows = IRODSQuery.executeGenQuery2(conn.getRcComm(), query);

PathAttributes attrs = new PathAttributes();

if(!rows.isEmpty()) {
// Collections do not have the same properties as data objects
// so fill in the gaps to satisfy requirements of setAttributes.
List<String> row = rows.get(0);
row.add("0"); // Data size
row.add(""); // Checksum
row.add(""); // Replica status
setAttributes(attrs, row);
}

return attrs;
}

throw new NotfoundException(logicalPath);
}
catch(JargonException e) {
catch(IOException | IRODSException e) {
throw new IRODSExceptionMappingService().map("Failure to read attributes of {0}", e, file);
}
}

@Override
public PathAttributes toAttributes(final ObjStat stats) {
final PathAttributes attributes = new PathAttributes();
attributes.setModificationDate(stats.getModifiedAt().getTime());
attributes.setCreationDate(stats.getCreatedAt().getTime());
attributes.setSize(stats.getObjSize());
attributes.setChecksum(Checksum.parse(Hex.encodeHexString(Base64.decodeBase64(stats.getChecksum()))));
attributes.setOwner(stats.getOwnerName());
attributes.setGroup(stats.getOwnerZone());
return attributes;
public PathAttributes toAttributes(final List<String> row) {
PathAttributes attrs = new PathAttributes();
setAttributes(attrs, row);
return attrs;
}

private static void setAttributes(final PathAttributes attrs, final List<String> row) {
log.debug("path attribute info: created at [{}], modified at [{}], data size = [{}], checksum = [{}]",
row.get(0), row.get(1), row.get(2), row.get(3));
attrs.setCreationDate(Long.parseLong(row.get(0)) * 1000); // seconds to ms
attrs.setModificationDate(Long.parseLong(row.get(1)) * 1000);
attrs.setSize(Long.parseLong(row.get(2)));
attrs.setChecksum(IRODSChecksumUtils.toChecksum(row.get(3)));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ch.cyberduck.core.irods;

/*
* Copyright (c) 2002-2025 iterate GmbH. All rights reserved.
* https://cyberduck.io/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

import ch.cyberduck.core.io.Checksum;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public final class IRODSChecksumUtils {

private static final Logger log = LogManager.getLogger(IRODSChecksumUtils.class);

public static Checksum toChecksum(String irodsChecksum) {
if(StringUtils.isBlank(irodsChecksum)) {
return Checksum.NONE;
}

int colon = irodsChecksum.indexOf(':');
if(-1 == colon) {
log.debug("no hash algorithm prefix found in iRODS checksum. ignoring checksum.");
return Checksum.NONE;
}

if(colon + 1 >= irodsChecksum.length()) {
log.debug("iRODS checksum may be corrupted. ignoring checksum.");
return Checksum.NONE;
}

log.debug("checksum from iRODS server is [{}].", irodsChecksum);
String checksum = irodsChecksum.substring(colon + 1);
checksum = Hex.encodeHexString(Base64.decodeBase64(checksum));
log.debug("base64-decoded, hex-encoded checksum is [{}].", checksum);
return Checksum.parse(checksum);
}
}
Loading
Loading