package no.ntnu.item.csv.filemanager; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Iterator; import java.util.Set; import java.util.Stack; import no.ntnu.item.csv.capability.Capability; import no.ntnu.item.csv.capability.CapabilityType; import no.ntnu.item.csv.communication.Communication; import no.ntnu.item.csv.csvobject.CSVFile; import no.ntnu.item.csv.csvobject.CSVFolder; import no.ntnu.item.csv.csvobject.CSVObject; import no.ntnu.item.csv.exception.DuplicateAliasException; import no.ntnu.item.csv.exception.FailedToVerifySignatureException; import no.ntnu.item.csv.exception.IllegalFileNameException; import no.ntnu.item.csv.exception.ImmutableFileExistsException; import no.ntnu.item.csv.exception.InsufficientPermissionException; import no.ntnu.item.csv.exception.InvalidWriteEnablerException; import no.ntnu.item.csv.exception.NoSuchAliasException; import no.ntnu.item.csv.exception.RemoteFileDoesNotExistException; import no.ntnu.item.csv.exception.ServerCommunicationException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; /** * @author pal * */ public class CSVFileManager { public static final String SHARE_FOLDER = "SHARE_FOLDER"; private final Communication connection; private Stack<CSVFolder> location; private CSVFolder sharedfolder; public CSVFileManager(Communication connection) { this.connection = connection; this.location = new Stack<CSVFolder>(); } public CSVFileManager(Capability capability, Communication connection) { this.connection = connection; this.location = new Stack<CSVFolder>(); this.setRootCapability(capability); } public void setRootCapability(Capability capability) { CSVFolder root; try { root = downloadFolder(capability); this.location = new Stack<CSVFolder>(); this.location.push(root); if (!root.getContents().containsKey(SHARE_FOLDER)) { CSVFolder shareFolder = new CSVFolder(); putObjectIntoFolder(shareFolder, this.location.get(0), SHARE_FOLDER); this.sharedfolder = shareFolder; } else { this.sharedfolder = downloadFolder(SHARE_FOLDER, this.location.get(0)); } } catch (ServerCommunicationException e) { e.printStackTrace(); } catch (RemoteFileDoesNotExistException e) { e.printStackTrace(); } catch (InvalidWriteEnablerException e) { } catch (ImmutableFileExistsException e) { } catch (DuplicateAliasException e) { } catch (IllegalFileNameException e) { } catch (InsufficientPermissionException e) { } catch (FailedToVerifySignatureException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public CSVObject putObjectIntoFolder(CSVObject object, CSVFolder folder, String alias) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, DuplicateAliasException, IllegalFileNameException, InsufficientPermissionException { if (alias.equals("") || alias.equals("..")) { throw new IllegalFileNameException(); } if (folder.getContents().containsKey(alias)) { throw new DuplicateAliasException(); } if (folder.getCapability().getType() != CapabilityType.RW) { throw new InsufficientPermissionException(); } CSVObject tmpObject = uploadObject(object); folder.addContent(alias, object.getCapability()); uploadFolder(folder); return tmpObject; } public CSVObject putObjectIntoCurrentFolder(CSVObject object, String alias) throws IllegalFileNameException, DuplicateAliasException, ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, InsufficientPermissionException { CSVFolder currentFolder = this.location.peek(); return putObjectIntoFolder(object, currentFolder, alias); } public CSVFile uploadFile(CSVFile file) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException { return (CSVFile) uploadObject(file); } public CSVFolder uploadFolder(CSVFolder folder) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException { return (CSVFolder) uploadObject(folder); } private CSVObject uploadObject(CSVObject object) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException { int code; if (object instanceof CSVFolder) { CSVFolder folder = (CSVFolder) object; code = this.connection .putByteArray(folder.getCapability().getStorageIndex() + "/" + folder.getCapability().getWriteEnabler(), folder.upload()); } else { CSVFile file = (CSVFile) object; code = this.connection.putInputStream(file.getCapability() .getStorageIndex(), file.upload(), file.getContentLength()); file.finishedUpload(); } try { parseStatuscode(code); } catch (RemoteFileDoesNotExistException e) { } return object; } private void parseStatuscode(int code) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, RemoteFileDoesNotExistException { switch (code) { case 200: return; case 201: return; case 401: // Wrong write enabler throw new InvalidWriteEnablerException(); case 403: // Immutable file already exist throw new ImmutableFileExistsException(); case 404: throw new RemoteFileDoesNotExistException(); default: throw new ServerCommunicationException(code); } } public CSVFile downloadFile(CSVFile file) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { return (CSVFile) downloadObject(file); } public CSVFolder downloadFolder(CSVFolder folder) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { return (CSVFolder) downloadObject(folder); } public CSVFolder downloadFolder(String alias, CSVFolder fromFolder) throws ServerCommunicationException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { Capability cap = fromFolder.getContents().get(alias); return downloadFolder(cap); } public CSVObject downloadObject(CSVObject object) throws ServerCommunicationException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { HttpResponse response = this.connection.get(object.getCapability() .getStorageIndex()); try { parseStatuscode(response.getStatusLine().getStatusCode()); } catch (InvalidWriteEnablerException e1) { } catch (ImmutableFileExistsException e1) { } HttpEntity entity = response.getEntity(); byte[] bytes; try { if (object instanceof CSVFolder) { InputStream is; is = entity.getContent(); int len = Integer.parseInt(response.getFirstHeader( "Content-Length").getValue()); bytes = new byte[len]; int nb; for (int i = 0; (nb = is.read()) != -1; i++) { bytes[i] = (byte) nb; } CSVFolder folder = (CSVFolder) object; folder.download(bytes); object = folder; } else if (object instanceof CSVFile) { CSVFile file = (CSVFile) object; if (entity != null) { OutputStream os = file.download(); entity.writeTo(os); os.flush(); os.close(); file.finishedDownload(); object = file; } } } catch (IOException e) { throw new ServerCommunicationException(); } if (object.getCapability().getVerificationKey() != null && !object.isValid()) { throw new FailedToVerifySignatureException(); } return object; } public CSVFolder downloadFolder(Capability capability) throws ServerCommunicationException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { CSVFolder folder = new CSVFolder(capability); try { folder = this.downloadFolder(folder); } catch (InvalidWriteEnablerException e) { } catch (ImmutableFileExistsException e) { } return folder; } public CSVFolder cd(String alias) throws ServerCommunicationException, RemoteFileDoesNotExistException, NoSuchAliasException, FailedToVerifySignatureException { if (alias.equals("..")) { this.location.pop(); return this.location.peek(); } if (!this.location.peek().getContents().containsKey(alias)) { throw new NoSuchAliasException(alias); } Capability capability = this.location.peek().getContents().get(alias); CSVFolder folder = downloadFolder(capability); this.location.push(folder); return folder; } public CSVFolder getShareFolder() { return this.sharedfolder; } public CSVFolder getCurrentFolder() { return this.location.peek(); } public CSVFolder getParentFolder() { if (this.location == null || this.location.size() < 2) { return null; } return this.location.get(this.location.size() - 2); } public CSVFolder replaceCurrentFolder() throws ServerCommunicationException, InvalidWriteEnablerException, InsufficientPermissionException { try { CSVFolder folder = new CSVFolder(); CSVFolder current = this.getCurrentFolder(); folder.getContents().putAll(current.getContents()); current.getContents().clear(); uploadFolder(current); String currentAlias = this.getAliasOfCurrentFolder(); CSVFolder parent = this.getParentFolder(); if (parent != null) { parent.getContents().remove(currentAlias); uploadFolder(parent); putObjectIntoFolder(folder, parent, currentAlias); this.location.pop(); } else { uploadFolder(folder); } this.location.pop(); if (parent != null) { this.location.push(parent); } this.location.push(folder); return folder; } catch (ImmutableFileExistsException e) { } catch (DuplicateAliasException e) { } catch (IllegalFileNameException e) { } return null; } protected String getAliasOfCurrentFolder() { if (this.location == null || this.location.size() < 2) { return null; } CSVFolder parent = this.getParentFolder(); Set<String> aliases = parent.getContents().keySet(); String compareTo = this.getCurrentFolder().getCapability() .getStorageIndex(); for (Iterator<String> iterator = aliases.iterator(); iterator.hasNext();) { String key = iterator.next(); if (parent.getContents().get(key).getStorageIndex() .equals(compareTo)) { return key; } } return null; } public CSVFolder getRootFolder() { if (this.location.size() > 0) { return this.location.get(0); } return null; } public void unlinkAliasFromCurrentFolder(String alias) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { unLinkAliasFromFolder(alias, this.getCurrentFolder()); } public void unLinkAliasFromFolder(String alias, CSVFolder folder) throws ServerCommunicationException, InvalidWriteEnablerException, ImmutableFileExistsException, RemoteFileDoesNotExistException, FailedToVerifySignatureException { if (folder.getContents() == null) { this.downloadFolder(folder); } folder.getContents().remove(alias); this.uploadFolder(folder); if (folder.getCapability().getStorageIndex() .equals(this.sharedfolder.getCapability().getStorageIndex())) { this.sharedfolder = folder; } } }