Skip to content
Snippets Groups Projects
Verified Commit 40936177 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: file storage refactoring: directory

parent fed9ef86
Branches
No related tags found
1 merge request!74Draft: ENH: file system: directory
Showing
with 129 additions and 48 deletions
...@@ -809,14 +809,13 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa ...@@ -809,14 +809,13 @@ public abstract class Entity extends AbstractObservable implements EntityInterfa
if (tmpIdentifier != null || checksum != null || path != null || size != null) { if (tmpIdentifier != null || checksum != null || path != null || size != null) {
// legacy clients (which use this api) always use sha512. // legacy clients (which use this api) always use sha512.
Hash hash = Hash.create(checksum, 0, Hasher.Default); Hash hash = Hash.create(checksum, 0, Hasher.Default);
if (getRole() == Role.Directory) {
setFSODescriptor(FSODescriptor.createDir(FileSystem.DEFAULT_BACKEND, new Path(path)));
} else {
setFSODescriptor( setFSODescriptor(
new FSODescriptor( new FSODescriptor(
FileSystem.DEFAULT_BACKEND, FileSystem.DEFAULT_BACKEND, null, hash, new Path(path), size, tmpIdentifier));
new Path(path).toString(), }
hash,
new Path(path),
size,
tmpIdentifier));
} }
// Parse flags // Parse flags
......
...@@ -31,11 +31,13 @@ import org.caosdb.server.transaction.Retrieve; ...@@ -31,11 +31,13 @@ import org.caosdb.server.transaction.Retrieve;
public enum MagicTypes { public enum MagicTypes {
UNIT, UNIT,
NAME, NAME,
DESCRIPTION; DESCRIPTION,
ROOT_DIRECTORY;
private static final EntityID UNIT_ID = new EntityID(21); private static final EntityID UNIT_ID = new EntityID(21);
private static final EntityID DESCRIPTION_ID = new EntityID(24); private static final EntityID DESCRIPTION_ID = new EntityID(24);
private static final EntityID NAME_ID = new EntityID(20); private static final EntityID NAME_ID = new EntityID(20);
private static final EntityID ROOT_DIRECTORY_ID = new EntityID(51);
public EntityID getId() { public EntityID getId() {
switch (this) { switch (this) {
...@@ -45,6 +47,8 @@ public enum MagicTypes { ...@@ -45,6 +47,8 @@ public enum MagicTypes {
return NAME_ID; return NAME_ID;
case DESCRIPTION: case DESCRIPTION:
return DESCRIPTION_ID; return DESCRIPTION_ID;
case ROOT_DIRECTORY:
return ROOT_DIRECTORY_ID;
default: default:
return null; return null;
} }
...@@ -58,6 +62,8 @@ public enum MagicTypes { ...@@ -58,6 +62,8 @@ public enum MagicTypes {
return NAME; return NAME;
case 24: case 24:
return DESCRIPTION; return DESCRIPTION;
case 51:
return ROOT_DIRECTORY;
default: default:
return null; return null;
} }
......
...@@ -35,7 +35,6 @@ public enum Role { ...@@ -35,7 +35,6 @@ public enum Role {
Domain, Domain,
File, File,
Directory, Directory,
Link,
Property, Property,
DataType, DataType,
QueryTemplate; QueryTemplate;
...@@ -75,14 +74,12 @@ public enum Role { ...@@ -75,14 +74,12 @@ public enum Role {
return new FileToElementStrategy(toString()); return new FileToElementStrategy(toString());
case Directory: case Directory:
return new FileToElementStrategy(toString()); return new FileToElementStrategy(toString());
case Link:
return new FileToElementStrategy(toString());
default: default:
return new EntityToElementStrategy(toString()); return new EntityToElementStrategy(toString());
} }
} }
public boolean hasFSODescriptor() { public boolean hasFSODescriptor() {
return this == File; // || this == Directory; return this == File || this == Directory;
} }
} }
...@@ -187,8 +187,9 @@ public class FSODescriptor implements VirtualFSODescriptorInterface { ...@@ -187,8 +187,9 @@ public class FSODescriptor implements VirtualFSODescriptorInterface {
this.children = children; this.children = children;
} }
public static FSODescriptor createDir(final Path dirPath) { public static FSODescriptor createDir(String fileStorageId, final Path dirPath) {
final FSODescriptor ret = new FSODescriptor(dirPath); final FSODescriptor ret = new FSODescriptor(dirPath);
ret.fileStorageId = fileStorageId;
ret.type = ObjectType.DIRECTORY; ret.type = ObjectType.DIRECTORY;
return ret; return ret;
} }
...@@ -252,4 +253,9 @@ public class FSODescriptor implements VirtualFSODescriptorInterface { ...@@ -252,4 +253,9 @@ public class FSODescriptor implements VirtualFSODescriptorInterface {
public void setTwin(RealFSODescriptorInterface twin) { public void setTwin(RealFSODescriptorInterface twin) {
this.twin = twin; this.twin = twin;
} }
@Override
public void setKey(String key) {
this.key = key;
}
} }
...@@ -39,7 +39,8 @@ public interface FileStorageInterface { ...@@ -39,7 +39,8 @@ public interface FileStorageInterface {
*/ */
public abstract RealFSODescriptorInterface resolve(String fileKey); public abstract RealFSODescriptorInterface resolve(String fileKey);
public abstract Undoable move(RealFSODescriptorInterface file, String fileKey) throws Message; public abstract Undoable move(
RealFSODescriptorInterface file, VirtualFSODescriptorInterface target) throws Message;
public abstract Undoable delete(String fileKey) throws Message; public abstract Undoable delete(String fileKey) throws Message;
......
...@@ -46,12 +46,6 @@ public class FileSystem implements FileSystemInterface { ...@@ -46,12 +46,6 @@ public class FileSystem implements FileSystemInterface {
return fs.delete(file.getKey()); return fs.delete(file.getKey());
} }
@Override
public Undoable store(final RealFSODescriptorInterface file) throws Message {
final FileStorageInterface fs = getFileStorage(file);
return fs.move(file, file.getKey());
}
public static FileSystem getInstance() { public static FileSystem getInstance() {
return instance; return instance;
} }
...@@ -98,10 +92,10 @@ public class FileSystem implements FileSystemInterface { ...@@ -98,10 +92,10 @@ public class FileSystem implements FileSystemInterface {
return null; return null;
} }
public Undoable move(RealFSODescriptorInterface fso, FSODescriptorInterface target) public Undoable move(RealFSODescriptorInterface fso, VirtualFSODescriptorInterface target)
throws Message { throws Message {
FileStorageInterface fileStorage = getFileStorage(target); FileStorageInterface fileStorage = getFileStorage(target);
return fileStorage.move(fso, target.getKey()); return fileStorage.move(fso, target);
} }
// public static boolean resolve(FSODescriptorInterface fso) { // public static boolean resolve(FSODescriptorInterface fso) {
......
...@@ -10,16 +10,6 @@ import org.caosdb.server.utils.Undoable; ...@@ -10,16 +10,6 @@ import org.caosdb.server.utils.Undoable;
*/ */
public interface FileSystemInterface { public interface FileSystemInterface {
/**
* Store the file described by the FileDescriptorInterface.
*
* @param file
* @return an {@link Undoable} object, which reverts the storage procedure and puts the file back
* to where it was. To be called when failures occured and the transaction needs to roll back.
* @throws Message
*/
public abstract Undoable store(RealFSODescriptorInterface file) throws Message;
/** /**
* Delete the file described by the FileDescriptorInterface. * Delete the file described by the FileDescriptorInterface.
* *
......
...@@ -285,10 +285,17 @@ public abstract class LocalFileStorage implements FileStorageInterface { ...@@ -285,10 +285,17 @@ public abstract class LocalFileStorage implements FileStorageInterface {
} }
@Override @Override
public Undoable move(final RealFSODescriptorInterface file, String key) throws Message { public Undoable move(final RealFSODescriptorInterface file, VirtualFSODescriptorInterface target)
throws Message {
String key = target.getKey();
if (key == null) {
key = target.getPath().toString();
target.setKey(key);
}
final Path targetPath = getRoot().resolve(key); final Path targetPath = getRoot().resolve(key);
if (file.getObjectType() == ObjectType.DIRECTORY) { if (target.getObjectType() == ObjectType.DIRECTORY) {
final File newDirectory = createDirs(targetPath.toFile()); final File newDirectory = createDirs(targetPath.toFile());
return new Undoable() { return new Undoable() {
...@@ -319,7 +326,7 @@ public abstract class LocalFileStorage implements FileStorageInterface { ...@@ -319,7 +326,7 @@ public abstract class LocalFileStorage implements FileStorageInterface {
public Undoable delete(final String fileKey) throws Message { public Undoable delete(final String fileKey) throws Message {
final Path targetPath = getRoot().resolve(fileKey); final Path targetPath = getRoot().resolve(fileKey);
return deleteWithEmptyParentDir(targetPath.toFile(), true); return delete(targetPath.toFile(), true);
} }
public Path getRoot() { public Path getRoot() {
...@@ -613,17 +620,6 @@ public abstract class LocalFileStorage implements FileStorageInterface { ...@@ -613,17 +620,6 @@ public abstract class LocalFileStorage implements FileStorageInterface {
}; };
} }
Undoable deleteWithEmptyParentDir(final File f, final boolean recursive) throws Message {
final File parent = f.getParentFile();
if (!getRoot().toFile().equals(parent)) {
final File[] siblings = parent.listFiles();
if (siblings == null || siblings.length == 1 && siblings[0].equals(f)) {
return deleteWithEmptyParentDir(parent, recursive);
}
}
return delete(f, recursive);
}
public Long getSize(String key) { public Long getSize(String key) {
File file = getFile(key); File file = getFile(key);
if (file == null) { if (file == null) {
......
...@@ -120,4 +120,6 @@ public interface VirtualFSODescriptorInterface extends FSODescriptorInterface { ...@@ -120,4 +120,6 @@ public interface VirtualFSODescriptorInterface extends FSODescriptorInterface {
@Override @Override
public abstract List<? extends VirtualFSODescriptorInterface> listChildren(); public abstract List<? extends VirtualFSODescriptorInterface> listChildren();
public abstract void setKey(String key);
} }
package org.caosdb.server.jobs.core;
import org.caosdb.server.database.backend.transaction.GetFileEntityByPath;
import org.caosdb.server.database.exceptions.EntityDoesNotExistException;
import org.caosdb.server.entity.EntityInterface;
import org.caosdb.server.entity.InsertEntity;
import org.caosdb.server.entity.MagicTypes;
import org.caosdb.server.entity.Role;
import org.caosdb.server.entity.UpdateEntity;
import org.caosdb.server.filesystem.FSODescriptor;
import org.caosdb.server.filesystem.Path;
import org.caosdb.server.filesystem.VirtualFSODescriptorInterface;
import org.caosdb.server.jobs.EntityFlagJob;
import org.caosdb.server.jobs.JobAnnotation;
import org.caosdb.server.permissions.EntityACL;
@JobAnnotation(flag = "autoCreateDirs", defaultValue = "true", loadAlways = true)
public class AutoCreateDirs extends EntityFlagJob {
@Override
protected void job(final String value) {
final boolean createDirs = "true".equalsIgnoreCase(value);
if (createDirs
&& (getEntity() instanceof InsertEntity || getEntity() instanceof UpdateEntity)
&& getEntity().hasFSODescriptor()) {
createDirs(getEntity().getFSODescriptor());
}
}
private void createDirs(final VirtualFSODescriptorInterface fso) {
VirtualFSODescriptorInterface nextFSO = fso;
String fileStorageId = nextFSO.getFileStorageId();
Path parentDir = nextFSO.getPath().getParent();
while (parentDir != null) {
final VirtualFSODescriptorInterface parentFSO = exists(parentDir);
if (parentFSO != null) {
// the parent does exist.
fso.setParentDirectory(parentFSO.getEntityId());
break;
}
nextFSO = createDir(fileStorageId, parentDir, nextFSO);
parentDir = parentDir.getParent();
}
if (parentDir == null) { // root of file system
nextFSO.setParentDirectory(MagicTypes.ROOT_DIRECTORY.getId());
}
}
private VirtualFSODescriptorInterface exists(final Path dirPath) {
for (final EntityInterface e : getContainer()) {
if (e.getRole() == Role.Directory
&& (e instanceof InsertEntity || e instanceof UpdateEntity)
&& e.getFSODescriptor().getPath().equals(dirPath)) {
// Found the directory in the container
return e.getFSODescriptor();
}
}
final GetFileEntityByPath t = new GetFileEntityByPath(dirPath);
try {
execute(t);
return t.getEntity().getFSODescriptor();
} catch (final EntityDoesNotExistException e) {
return null;
}
}
private VirtualFSODescriptorInterface createDir(
final String fileStorageId, final Path dirPath, final VirtualFSODescriptorInterface child) {
final String name = dirPath.getLastSegment();
final VirtualFSODescriptorInterface newFD = FSODescriptor.createDir(fileStorageId, dirPath);
child.setParentDirectory(newFD.getEntityId());
final EntityInterface newDir = new InsertEntity(name, Role.Directory);
newDir.setEntityACL(EntityACL.getOwnerACLFor(getUser()));
newDir.setFSODescriptor(newFD);
getContainer().add(newDir);
return newFD;
}
}
...@@ -38,6 +38,7 @@ import org.caosdb.server.database.exceptions.TransactionException; ...@@ -38,6 +38,7 @@ import org.caosdb.server.database.exceptions.TransactionException;
import org.caosdb.server.entity.Message; import org.caosdb.server.entity.Message;
import org.caosdb.server.entity.Message.MessageType; import org.caosdb.server.entity.Message.MessageType;
import org.caosdb.server.entity.xml.ToElementable; import org.caosdb.server.entity.xml.ToElementable;
import org.caosdb.server.filesystem.FSODescriptor;
import org.caosdb.server.filesystem.FileSystem; import org.caosdb.server.filesystem.FileSystem;
import org.caosdb.server.filesystem.Path; import org.caosdb.server.filesystem.Path;
import org.caosdb.server.filesystem.RealFSODescriptorInterface; import org.caosdb.server.filesystem.RealFSODescriptorInterface;
...@@ -187,7 +188,8 @@ public class CheckFileStorageConsistency extends FlagJob { ...@@ -187,7 +188,8 @@ public class CheckFileStorageConsistency extends FlagJob {
if (f1 == null) { if (f1 == null) {
return; return;
} }
Undoable undo1 = FileSystem.getInstance().getFileStorage(f1).move(f1, "somewhere.else"); FSODescriptor target = new FSODescriptor(new Path("debug/somewhere.else"));
Undoable undo1 = FileSystem.getInstance().getFileStorage(f1).move(f1, target);
getTransaction() getTransaction()
.acceptObserver( .acceptObserver(
......
...@@ -343,6 +343,10 @@ FILE: ...@@ -343,6 +343,10 @@ FILE:
[Ff][Ii][Ll][Ee]([Ss])? WHITE_SPACE_f? [Ff][Ii][Ll][Ee]([Ss])? WHITE_SPACE_f?
; ;
DIRECTORY:
[Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr]([Yy]|[Ii][Ee][Ss]) WHITE_SPACE_f?
;
ENTITY: ENTITY:
[Ee][Nn][Tt][Ii][Tt]([Yy]|[Ii][Ee][Ss]) WHITE_SPACE_f? [Ee][Nn][Tt][Ii][Tt]([Yy]|[Ii][Ee][Ss]) WHITE_SPACE_f?
; ;
......
...@@ -99,6 +99,7 @@ role returns [Query.Role r]: ...@@ -99,6 +99,7 @@ role returns [Query.Role r]:
| RECORD {$r = Query.Role.RECORD;} | RECORD {$r = Query.Role.RECORD;}
| PROPERTY {$r = Query.Role.PROPERTY;} | PROPERTY {$r = Query.Role.PROPERTY;}
| FILE {$r = Query.Role.FILE;} | FILE {$r = Query.Role.FILE;}
| DIRECTORY {$r = Query.Role.DIRECTORY;}
| QUERYTEMPLATE {$r = Query.Role.QUERYTEMPLATE;} | QUERYTEMPLATE {$r = Query.Role.QUERYTEMPLATE;}
| ENTITY {$r = Query.Role.ENTITY;} | ENTITY {$r = Query.Role.ENTITY;}
; ;
......
...@@ -160,6 +160,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac ...@@ -160,6 +160,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
PROPERTY, PROPERTY,
ENTITY, ENTITY,
FILE, FILE,
DIRECTORY,
QUERYTEMPLATE QUERYTEMPLATE
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment