/** * Method called locally to the repository during {@link #rawAccess()}. Only the remoteable fields * should be accessed during this method call since this will be a copy of the object originally * called. * * @param abstractRepositoryI * @param servant * @param __current */ public void local( AbstractRepositoryI abstractRepositoryI, PublicRepositoryI servant, Current __current) throws Exception { if ("touch".equals(command)) { for (String arg : args) { final CheckedPath checked = servant.checkPath(parse(arg), null, __current); if (!checked.exists()) { final CheckedPath parent = checked.parent(); if (!(parent.isDirectory() || checked.parent().mkdirs())) { throw new RepositoryException(null, null, "cannot create directory: " + parent); } final FileBuffer buffer = checked.getFileBuffer("rw"); buffer.write(ByteBuffer.allocate(0)); buffer.close(); } else if (!checked.markModified()) { throw new RepositoryException(null, null, "cannot touch file: " + checked); } } } else if ("mkdir".equals(command)) { boolean parents = false; for (String arg : args) { if ("-p".equals(arg)) { parents = true; continue; } final CheckedPath checked = servant.checkPath(parse(arg), null, __current); if (parents) { checked.mkdirs(); } else { checked.mkdir(); } } } else if ("rm".equals(command)) { if (args.size() == 1) { final CheckedPath checked = servant.checkPath(parse(args.get(0)), null, __current); if (!checked.delete()) { throw new omero.grid.FileDeleteException( null, null, "Delete file failed: " + args.get(0)); } } else { throw new omero.ApiUsageException( null, null, "Command: " + command + " takes just one argument"); } } else if ("checksum".equals(command)) { if (args.size() == 3) { final String checksumType = args.get(0); final ChecksumAlgorithm algo = ChecksumAlgorithmMapper.getChecksumAlgorithm(checksumType); final String expectedHash = args.get(1); final CheckedPath checked = servant.checkPath(parse(args.get(2)), algo, __current); final String currentHash = checked.hash(); if (!currentHash.equals(expectedHash)) { // TODO: ADD ANNOTATION TO DATABASE HERE! throw new omero.ResourceError( null, null, String.format( "Checksum mismatch (%s): expected=%s found=%s", checksumType, expectedHash, currentHash)); } } else { throw new omero.ApiUsageException( null, null, "'checksum' requires HASHER HASH FILEPATH, not: " + args.toString()); } } else { throw new omero.ApiUsageException(null, null, "Unknown command: " + command); } }
/** * Internal method to be used by subclasses to perform any extra checks on the listed of {@link * CheckedPath} instances before allowing the creation of directories. * * @param paths Not null, not empty. (Will be emptied by this method.) * @param parents "mkdir -p" like flag. * @param __current */ protected void makeCheckedDirs( final LinkedList<CheckedPath> paths, boolean parents, Session s, ServiceFactory sf, SqlAction sql, ome.system.EventContext effectiveEventContext) throws ServerError { CheckedPath checked; // Since we now have some number of elements, we start at the most // parent element and work our way down through all the parents. // If the file exists, then we check its permissions. If it doesn't // exist, it gets created. while (paths.size() > 1) { // Only possible if `parents` checked = paths.removeFirst(); if (checked.exists()) { if (!checked.isDirectory()) { throw new omero.ResourceError(null, null, "Path is not a directory."); } else if (!checked.canRead()) { throw new omero.ResourceError(null, null, "Directory is not readable"); } assertFindDir(checked, s, sf, sql); } else { // This will fail if the directory already exists try { repositoryDao.register(repoUuid, checked, DIRECTORY_MIMETYPE, sf, sql); } catch (ValidationException ve) { if (ve.getCause() instanceof PSQLException) { // Could have collided with another thread also creating the directory. // See Trac #11096 regarding originalfile table uniqueness of columns repo, path, name. // So, give the other thread time to complete registration. SleepTimer.sleepFor(1000); if (checked.exists()) { // The path now exists! It did not a moment ago. // We are not going to rethrow the validation exception, // so we otherwise note that something unexpected did occur. log.warn( "retrying after exception in registering directory " + checked + ": " + ve.getCause()); // Another thread may have succeeded where this one failed, // so try this directory again. paths.add(0, checked); continue; } } // We cannot recover from the validation exception. throw ve; } } } // Now we are ready to work on the actual intended path. checked = paths.removeFirst(); // Size is now empty if (checked.exists()) { if (parents) { assertFindDir(checked, s, sf, sql); } else { throw new omero.ResourceError(null, null, "Path exists on disk: " + checked.fsFile); } } repositoryDao.register(repoUuid, checked, DIRECTORY_MIMETYPE, sf, sql); }