package service.filestore;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import javax.jcr.ItemExistsException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import models.User;
import service.EventManager;
import service.EventManager.Event;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
public interface FileStore {
public enum Permission {
NONE, RO, RW;
private static BiMap<Permission, jackrabbit.Permission> jackrabbitPermMap =
ImmutableBiMap.<Permission, jackrabbit.Permission>builder()
.put(Permission.NONE, jackrabbit.Permission.NONE)
.put(Permission.RO, jackrabbit.Permission.RO)
.put(Permission.RW, jackrabbit.Permission.RW)
.build();
public boolean isAtLeast(Permission other) {
return this.compareTo(other) >= 0;
}
public jackrabbit.Permission toJackrabbitPermission() {
return jackrabbitPermMap.get(this);
}
public static Permission fromJackrabbitPermission(jackrabbit.Permission o) {
return jackrabbitPermMap.inverse().get(o);
}
}
Manager getManager(Session session);
EventManager getEventManager();
static interface Manager {
Folder getRoot() throws RepositoryException;
FileOrFolder getByIdentifier(final String id) throws RepositoryException;
FileOrFolder getFileOrFolder(final String absPath) throws RepositoryException;
Set<Folder> getFolders() throws RepositoryException;
}
static interface FileOrFolder {
String getIdentifier(); /* Globally unique */
String getName(); /* Unique only inside parent folder */
int getDepth();
String getPath(); /* Globally unique */
Folder getParent() throws RepositoryException;
void delete() throws RepositoryException;
/**
* Rename this file/folder.
*
* @param newName Name following rename
* @throws ItemExistsException if another file/folder exists
* @throws RepositoryException
*/
void rename(String newName)
throws ItemExistsException, RepositoryException;
/**
* Determine access level to this item. Note that this may vary from the
* access to the node, as permissions based soley on ancestory to a child
* node should be excluded.
*
* @return
* @throws RepositoryException
*/
Permission getAccessLevel() throws RepositoryException;
void move(Folder destination) throws ItemExistsException, RepositoryException;
}
static interface Folder extends FileOrFolder {
Folder createFolder(String name) throws RepositoryException;
File createFile(String name, String mime, InputStream data)
throws RepositoryException;
FileOrFolder getFileOrFolder(String name) throws RepositoryException;
Set<File> getFiles() throws RepositoryException;
Set<Folder> getFolders() throws RepositoryException;
Map<String, Permission> getGroupPermissions()
throws RepositoryException;
void grantAccess(String groupName, Permission permission)
throws RepositoryException;
void revokeAccess(String groupName)
throws RepositoryException;
void reload();
}
static interface File extends FileOrFolder {
InputStream getData();
String getMimeType();
String getDigest();
SortedSet<File> getVersions() throws RepositoryException;
File update(String mime, InputStream data) throws RepositoryException;
User getAuthor();
Calendar getModificationTime();
}
public static class Events {
public static Event create(FileStore.File file, String ownerId)
throws RepositoryException {
return new Event("file:create", nodeInfo(file.getIdentifier(), ownerId));
}
public static Event create(FileStore.Folder folder, String ownerId)
throws RepositoryException {
return new Event("folder:create", nodeInfo(folder.getIdentifier(), ownerId));
}
public static Event update(FileStore.File file, String ownerId)
throws RepositoryException {
return new Event("file:update", nodeInfo(file.getIdentifier(), ownerId));
}
public static Event update(FileStore.Folder folder, String ownerId)
throws RepositoryException {
return new Event("folder:update", nodeInfo(folder.getIdentifier(), ownerId));
}
public static Event delete(FileStore.File file, String ownerId)
throws RepositoryException {
return new EventManager.Event("file:delete", nodeInfo(file.getIdentifier(), ownerId));
}
public static Event delete(FileStore.Folder folder, String ownerId)
throws RepositoryException {
return new EventManager.Event("folder:delete", nodeInfo(folder.getIdentifier(), ownerId));
}
public static Event move(FileStore.File file,
FileStore.Folder formerParent,
FileStore.Folder newParent,
String ownerId)
throws RepositoryException {
return move("file", file, formerParent, newParent, ownerId);
}
public static Event move(FileStore.Folder folder,
FileStore.Folder formerParent,
FileStore.Folder newParent,
String ownerId)
throws RepositoryException {
return move("folder", folder, formerParent, newParent, ownerId);
}
private static Event move(String type,
FileStore.FileOrFolder f,
FileStore.Folder formerParent,
FileStore.Folder newParent,
String ownerId) throws RepositoryException {
return new EventManager.Event(type+":move", ImmutableMap.of("id", f.getIdentifier(),
"formerParent", formerParent.getIdentifier(),
"newParent", newParent.getIdentifier(),
"owner:id", ownerId));
}
private static Map<String, String> nodeInfo(String id, String ownerId) {
return ImmutableMap.of("id", id, "owner:id", ownerId);
}
}
}