diff --git a/Main.java b/Main.java index 3b8673a..fe6aaea 100644 --- a/Main.java +++ b/Main.java @@ -1,5 +1,8 @@ import filesys.IFileSystem; +import filesys.Usuario; +import java.util.ArrayList; +import java.util.List; import java.util.Scanner; import java.io.FileNotFoundException; @@ -7,7 +10,9 @@ import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; + import filesys.FileSystem; +import filesys.Dir; // MENU INTERATIVO PARA O SISTEMA DE ARQUIVOS // SINTA-SE LIVRE PARA ALTERAR A CLASSE MAIN @@ -29,6 +34,9 @@ public class Main { // Usuário que está executando o programa private static String user; + // Lista de usuários + private static List usuarios = new ArrayList<>(); + // O sistema de arquivos é inteiramente virtual, ou seja, será reiniciado a cada execução do programa. // Logo, não é necessário salvar os arquivos em disco. O sistema será uma simulação em memória. public static void main(String[] args) { @@ -68,7 +76,8 @@ public static void main(String[] args) { */ System.out.println(userListed + " " + dir + " " + dirPermission); // Somente imprime o usuário, diretório e permissão - + // Adicionar usuário à lista + usuarios.add(new Usuario(userListed, dir, dirPermission)); } else { System.out.println("Formato ruim no arquivo de usuários. Linha: " + line); } @@ -80,19 +89,28 @@ public static void main(String[] args) { return; } - + + /* REMOVER ISSO PQ NÃO PRECISA + System.out.println("Usuários carregados:"); + for (Usuario user : usuarios) { + System.out.println(user); + } + */ + // Finalmente cria o Sistema de Arquivos // Lista de usuários é imutável durante a execução do programa // Obs: Como passar a lista de usuários para o FileSystem? - fileSystem = new FileSystem(/*usuários?*/); + fileSystem = new FileSystem(usuarios); // // DESCOMENTE O BLOCO ABAIXO PARA CRIAR O DIRETÓRIO RAIZ ANTES DE RODAR O MENU - // // Cria o diretório raiz do sistema. Root sempre tem permissão total "rwx" - // try { - // fileSystem.mkdir(ROOT_DIR, ROOT_USER); - // } catch (CaminhoJaExistenteException | PermissaoException e) { - // System.out.println(e.getMessage()); - // } + // Cria o diretório raiz do sistema. Root sempre tem permissão total "rwx" + /* + try { + fileSystem.mkdir(ROOT_DIR, ROOT_USER); + } catch (CaminhoJaExistenteException | PermissaoException e) { + System.out.println(e.getMessage()); + } + */ // Menu interativo. menu(); @@ -153,7 +171,7 @@ public static void menu() { default: System.out.println("Comando inválido!"); } - } catch (CaminhoNaoEncontradoException | CaminhoJaExistenteException | PermissaoException e) { + } catch (CaminhoNaoEncontradoException | CaminhoJaExistenteException | PermissaoException | IllegalArgumentException e) { System.out.println("Erro: " + e.getMessage()); } @@ -185,13 +203,15 @@ public static void mkdir() throws CaminhoJaExistenteException, PermissaoExceptio public static void rm() throws CaminhoNaoEncontradoException, PermissaoException { System.out.println("Insira o caminho do diretório a ser removido:"); String caminho = scanner.nextLine(); + System.out.println("Remover recursivamente? (true/false):"); boolean recursivo = Boolean.parseBoolean(scanner.nextLine()); fileSystem.rm(caminho, user, recursivo); } - public static void touch() throws CaminhoJaExistenteException, PermissaoException { + + public static void touch() throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException { System.out.println("Insira o caminho do arquivo a ser criado:"); String caminho = scanner.nextLine(); @@ -210,12 +230,32 @@ public static void write() throws CaminhoNaoEncontradoException, PermissaoExcept fileSystem.write(caminho, user, anexar, buffer); } + // Read foi modificado public static void read() throws CaminhoNaoEncontradoException, PermissaoException { System.out.println("Insira o caminho do arquivo a ser lido:"); String caminho = scanner.nextLine(); byte[] buffer = new byte[READ_BUFFER_SIZE]; // Exemplo de tamanho de buffer por load/leitura . O que acontece se o Buffer for menor que o conteúdo a ser lido? - - fileSystem.read(caminho, user, buffer); // Lógica para ler arquivos maiores que o buffer deve ser implementada. + + int offset = 0; // Offset para leitura + int offsetAntes; + int leitura; + + System.out.println("Lendo arquivo: " + caminho + "\n"); + + do { + offsetAntes = offset; // Salva o offset antes da leitura + offset += fileSystem.read(caminho, user, buffer, offset); // Lê o arquivo no caminho especificado + leitura = offset - offsetAntes; // Calcula a quantidade de bytes lidos nesta iteração + + if (leitura > 0) { + System.out.write(buffer, 0, leitura); // Escreve os bytes lidos no console + } else { + break; // Se não houver mais bytes para ler, sai do loop + } + } while (leitura > 0); // Garante que o offset seja não negativo + + System.out.flush(); // Garante que todos os bytes sejam escritos no console + System.out.println("\n\nLeitura concluída."); } public static void mv() throws CaminhoNaoEncontradoException, PermissaoException { @@ -228,9 +268,9 @@ public static void mv() throws CaminhoNaoEncontradoException, PermissaoException } public static void ls() throws CaminhoNaoEncontradoException, PermissaoException { - System.out.println("Insira o caminho do diretório a ser listado:"); + System.out.print("Insira o caminho do diretório a ser listado: "); String caminho = scanner.nextLine(); - System.out.println("Listar recursivamente? (true/false):"); + System.out.print("Listar recursivamente? (true/false): "); boolean recursivo = Boolean.parseBoolean(scanner.nextLine()); fileSystem.ls(caminho, user, recursivo); diff --git a/filesys/BlocoDeDados.java b/filesys/BlocoDeDados.java new file mode 100644 index 0000000..88205c3 --- /dev/null +++ b/filesys/BlocoDeDados.java @@ -0,0 +1,29 @@ +package filesys; + +public class BlocoDeDados { + private byte[] dados; // Dados do bloco + + // Construtores + public BlocoDeDados() { + this.dados = new byte[File.TAMANHO_BYTES_BLOCO]; // Inicializa o bloco com o tamanho especificado + } + + public BlocoDeDados(byte[] dados) { + setDados(dados); + } + + + // Dados + public byte[] getDados() { + return dados; + } + + public void setDados(byte[] dados) { + if (dados.length <= File.TAMANHO_BYTES_BLOCO) { + this.dados = new byte[dados.length]; + System.arraycopy(dados, 0, this.dados, 0, dados.length); // Copia os novos dados para o bloco + } else { + throw new IllegalArgumentException("Dados excedem o tamanho do bloco."); + } + } +} diff --git a/filesys/Dir.java b/filesys/Dir.java new file mode 100644 index 0000000..6fdd8c4 --- /dev/null +++ b/filesys/Dir.java @@ -0,0 +1,214 @@ +package filesys; + +import java.util.HashMap; +import java.util.Map; + +public class Dir { + // Atributos + private String nome; + private String dono; + private String permissoes; + + // Relacionamentos + protected Dir pai; + protected Map filhos; + private Map permissoesUsuarios; + + // Construtor + public Dir(String nome, String dono, String permissoes) { + this.nome = nome; + this.dono = dono; + this.permissoes = permissoes; + + this.pai = null; // Inicialmente, o diretório não tem pai + this.filhos = new HashMap<>(); + this.permissoesUsuarios = new HashMap<>(); + + // Define as permissões iniciais para o dono do diretório + this.permissoesUsuarios.put(dono, "rwx"); // O dono tem permissão total + } + + // Nome + public String getNome() { + return nome; + } + + public void setNome(String nome) { + this.nome = nome; + } + + + // Dono + public String getDono() { + return dono; + } + + public void setDono(String dono) { + this.dono = dono; + } + + + // Permissões + public String getPermissoes() { + return permissoes; + } + + public void setPermissoes(String permissoes) { + this.permissoes = permissoes; + } + + + // Pai + public Dir getPai() { + return pai; + } + + public void setPai(Dir pai) { + this.pai = pai; + } + + + // Filhos + public Map getFilhos() { + return filhos; + } + + public Dir getFilho(String nome) { + return filhos.get(nome); + } + + public void setFilhos(Map filhos) { + this.filhos = filhos; + for (Dir filho : filhos.values()) { + filho.setPai(this); // Define o pai de cada filho + } + } + + public void addFilho(Dir filho) { + filhos.put(filho.getNome(), filho); + filho.setPai(this); // Define o pai do filho + } + + public void removeFilho(String nome) { + filhos.remove(nome); + } + + + // Permissões dos usuários + public Map getPermissoesUsuarios() { + return permissoesUsuarios; + } + + public String getPermissoesUsuario(String usuario) { + if ("root".equals(usuario)) return "rwx"; // O usuário root sempre tem permissão total + + // Verifica se o usuário é nulo ou vazio + if (usuario == null || usuario.isEmpty()) { + throw new IllegalArgumentException("Usuário não pode ser nulo ou vazio"); + } + + // Verifica se o usuário tem permissões definidas + if (!permissoesUsuarios.containsKey(usuario)) { + throw new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (dono.equals(usuario)) return permissoes; // O dono do diretório tem as permissões do diretório + + return permissoesUsuarios.getOrDefault(usuario, "---"); // Retorna as permissões do usuário ou um padrão se não tiver + } + + public void setPermissoesUsuario(String usuario, String permissoes) { + if (permissoes == null || permissoes.length() != 3) { + throw new IllegalArgumentException("As permissões precisam ter 3 caracteres"); + } + + this.permissoesUsuarios.put(usuario, permissoes); + } + + + // Verifica se o usuário tem permissão para acessar o diretório + public boolean temPerm(String usuario, String permissao) { + // Verifica se o usuário é nulo ou vazio + if (usuario == null || usuario.isEmpty()) { + throw new IllegalArgumentException("Usuário não pode ser nulo ou vazio"); + } + + if ("root".equals(usuario)) { + return true; // O dono do diretório sempre tem permissão total + } + + if (usuario.equals(dono)) { + return true; // O dono do diretório sempre tem permissão total + } + + // Verifica se a permissão é nula ou vazia + if (permissao == null || permissao.isEmpty()) { + throw new IllegalArgumentException("Permissão não pode ser nula ou vazia"); + } + + // Verifica se o usuário tem permissões definidas + if (!permissoesUsuarios.containsKey(usuario)) { + throw new IllegalArgumentException("Usuário não encontrado nas permissões: " + usuario); + } + + String permissoesUsuario = getPermissoesUsuario(usuario); + + // Verifica se o usuário tem a permissão solicitada + if (permissoesUsuario.contains(permissao)) { + return true; // O usuário tem a permissão solicitada + } + + // Se não tiver a permissão solicitada, verifica permissões do diretório pai + if (pai != null) { + return pai.temPerm(usuario, permissao); // Verifica no diretório pai + } + + // Se não, o usuário não tem permissão + return false; + } + + + // É um arquivo? + public boolean isArquivo() { + return false; // Esta classe representa um diretório, não um arquivo + } + + public String getCaminhoCompleto(){ + if(this.getPai() == null){ + return "/" + this.getNome(); + } + else{ + String caminhoPai = this.getPai().getCaminhoCompleto(); + if(caminhoPai.endsWith("/")){ + return caminhoPai + this.getNome(); + } else { + return caminhoPai + "/" + this.getNome(); + } + } + } + + + public boolean temSubdiretorios() { + for (Dir filho : getFilhos().values()) { + if (!filho.isArquivo()) { + return true; + } + } + return false; +} + + + // Transformando em string + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append(" Diretório: ").append(nome).append("\n") + .append(" - Dono: ").append(dono).append("\n") + .append(" - Permissões: ").append(permissoes).append("\n") + .append(" - Pai: ").append(pai != null ? pai.getNome() : "Nenhum").append("\n") + .append(" - Filhos: ").append(getFilhos().isEmpty() ? "Nenhum" : getFilhos().keySet()).append("\n") + .append(" - Permissões dos usuários: ").append(permissoesUsuarios).append("\n"); + return sb.toString(); + } +} diff --git a/filesys/File.java b/filesys/File.java new file mode 100644 index 0000000..b2abcde --- /dev/null +++ b/filesys/File.java @@ -0,0 +1,119 @@ +package filesys; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class File extends Dir { + public static final int TAMANHO_BYTES_BLOCO = 1024; // Tamanho do arquivo em bytes + + // Atributos específicos de um arquivo + private List blocos; // Lista de blocos de dados que compõem o arquivo + private long tamanho; // Tamanho atual do arquivo em bytes + + // Construtor + public File(String nome, String dono, String permissoes) { + super(nome, dono, permissoes); + + this.blocos = new ArrayList<>(); + this.tamanho = 0; + + this.pai = null; + this.filhos = null; // Um arquivo não pode ter filhos, então setamos como null + } + + // Blocos + public List getBlocos() { + return blocos; + } + + public void setBlocos(List blocos) { + this.blocos = blocos; + this.tamanho = blocos.stream().mapToLong(bloco -> bloco.getDados().length).sum(); // Atualiza o tamanho do arquivo + } + + public void addBloco(BlocoDeDados bloco) { + this.blocos.add(bloco); + this.tamanho += bloco.getDados().length; // Atualiza o tamanho do arquivo + } + + public void removeBloco(BlocoDeDados bloco) { + if (this.blocos.remove(bloco)) { + this.tamanho -= bloco.getDados().length; // Atualiza o tamanho do arquivo + } + } + + public void limparBlocos() { + this.blocos.clear(); + this.tamanho = 0; // Reseta o tamanho do arquivo + } + + + // Tamanho + public long getTamanho() { + return tamanho; + } + + public void setTamanho(long tamanho) { + this.tamanho = tamanho; + } + + public void addTamanho(long tamanho) { + this.tamanho += tamanho; + } + + public void removeTamanho(long tamanho) { + this.tamanho -= tamanho; + if (this.tamanho < 0) { + this.tamanho = 0; // Garante que o tamanho não fique negativo + } + } + + + // É um arquivo? + @Override + public boolean isArquivo() { + return true; // Essa classe representa um diretório do tipo arquivo + } + + + // Filhos + @Override + public Dir getFilho(String nome) { + throw new UnsupportedOperationException("Um arquivo não tem filhos."); + } + + @Override + public Map getFilhos() { + throw new UnsupportedOperationException("Um arquivo não tem filhos."); + } + + @Override + public void setFilhos(Map filhos) { + throw new UnsupportedOperationException("Um arquivo não pode ter filhos."); + } + + @Override + public void addFilho(Dir filho) { + throw new UnsupportedOperationException("Um arquivo não pode ter filhos."); + } + + @Override + public void removeFilho(String nome) { + throw new UnsupportedOperationException("Um arquivo não tem filhos."); + } + + + // Transformando em string + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append(" Arquivo: ").append(getNome()).append("\n") + .append(" - Dono: ").append(getDono()).append("\n") + .append(" - Permissões: ").append(getPermissoes()).append("\n") + .append(" - Tamanho: ").append(tamanho).append(" bytes\n") + .append(" - Blocos: ").append(blocos.size()).append("\n"); + return sb.toString(); + } +} diff --git a/filesys/FileSystem.java b/filesys/FileSystem.java index 8d7a83b..57cfe93 100644 --- a/filesys/FileSystem.java +++ b/filesys/FileSystem.java @@ -1,5 +1,7 @@ package filesys; +import java.util.List; + import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; import exception.PermissaoException; @@ -13,6 +15,10 @@ public FileSystem() { fileSystemImpl = new FileSystemImpl(); } + public FileSystem(List usuarios) { + fileSystemImpl = new FileSystemImpl(usuarios); + } + @Override public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { @@ -31,7 +37,7 @@ public void rm(String caminho, String usuario, boolean recursivo) } @Override - public void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { + public void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException { fileSystemImpl.touch(caminho, usuario); } @@ -42,9 +48,9 @@ public void write(String caminho, String usuario, boolean anexar, byte[] buffer) } @Override - public void read(String caminho, String usuario, byte[] buffer) + public int read(String caminho, String usuario, byte[] buffer, int offset) throws CaminhoNaoEncontradoException, PermissaoException { - fileSystemImpl.read(caminho, usuario, buffer); + return fileSystemImpl.read(caminho, usuario, buffer, offset); } @Override @@ -64,4 +70,9 @@ public void cp(String caminhoOrigem, String caminhoDestino, String usuario, bool throws CaminhoNaoEncontradoException, PermissaoException { fileSystemImpl.cp(caminhoOrigem, caminhoDestino, usuario, recursivo); } + + @Override + public void addUser(Usuario usuario) { + fileSystemImpl.addUser(usuario); + } } \ No newline at end of file diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index 45fa05d..6e67d46 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -1,70 +1,727 @@ package filesys; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; import exception.PermissaoException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + // Implemente nesta classe o seu código do FileSystem. // A classe pode ser alterada. // O construtor, argumentos do construtor podem ser modificados // e atributos & métodos privados podem ser adicionados public final class FileSystemImpl implements IFileSystem { - private static final String ROOT_USER = "root"; // pode ser necessário + private static final String ROOT_USER = "root"; + + private List usuarios = new ArrayList<>(); + private Dir raiz; // Diretório raiz + + public FileSystemImpl() { + usuarios.add(new Usuario(ROOT_USER, "/", "rwx")); // Adiciona o usuário root com permissões totais + this.raiz = new Dir("/", ROOT_USER, "rwx"); + } + + public FileSystemImpl(List usuarios) { + if (usuarios.isEmpty()) { + throw new IllegalArgumentException("Lista de usuários não pode ser nula"); + } + + this.usuarios = usuarios; + this.raiz = new Dir("/", ROOT_USER, "rwx"); + } + + // Método auxiliar para navegar até o diretório especificado pelo caminho + private Dir irPara(String caminho) throws CaminhoNaoEncontradoException { + if (caminho.equals("/") || caminho.isEmpty()) { + return raiz; + } + + Dir diretorioAtual = raiz; + + String[] partes = caminho.split("/"); + + for (String parte : partes) { + if (parte == null || parte.isEmpty()) + continue; + if (!diretorioAtual.getFilhos().containsKey(parte)) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + diretorioAtual = diretorioAtual.getFilhos().get(parte); + } + + return diretorioAtual; + } + + // Lista o conteúdo de um diretório e, se recursivo=true, lista também os + // subdiretórios + private String lsRecursivo(Dir diretorio, String caminho, boolean recursivo, String usuario) { + StringBuilder saida = new StringBuilder(); + String nomeCaminho = (caminho == null || caminho.isEmpty() || !caminho.startsWith("/")) ? "/" + caminho + : caminho; + saida.append(nomeCaminho).append(":\n"); + + // Lista todos os filhos (arquivos e diretórios) do diretório atual + if (diretorio.getFilhos().isEmpty()) { + saida.append(" - Vazio\n"); + } else { + for (Dir filho : diretorio.getFilhos().values()) { + saida.append(filho.toString()).append("\n"); + } + } - public FileSystemImpl() {} + // Se for para listar recursivamente, faz o mesmo para cada subdiretório + if (recursivo) { + for (Dir filho : diretorio.getFilhos().values()) { + if (!filho.isArquivo()) { // Só entra em diretórios + String novoCaminho = caminho.equals("/") ? "/" + filho.getNome() : caminho + "/" + filho.getNome(); + saida.append(lsRecursivo(filho, novoCaminho, true, usuario)); + } + } + } + + return saida.toString(); + } @Override - public void mkdir(String caminho, String nome) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mkdir'"); + public void mkdir(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { + if (caminho == null || caminho.isEmpty() || usuario == null || usuario.isEmpty()) { + throw new IllegalArgumentException("Caminho e usuário não podem ser nulos"); + } + + // Normaliza o caminho para formato UNIX + caminho = caminho.replace("\\", "/"); // Converte barras invertidas para barras normais + + // Remove barras finais + if (caminho.length() > 1 && caminho.endsWith("/")) { + caminho = caminho.substring(0, caminho.length() - 1); + } + + if (caminho.equals("/")) { + throw new UnsupportedOperationException("Não é possível criar diretório raiz pois ele já existe."); + } + + if (raiz == null) { + System.err.println("Diretório raiz: " + raiz); + throw new IllegalStateException("Diretório raiz não foi inicializado."); + } + + // Separar caminho em partes + String[] partes = caminho.split("/"); + Dir diretorioAtual = raiz; // Começa no diretório raiz + StringBuilder caminhoAtual = new StringBuilder("/"); + + for (int i = 0; i < partes.length; i++) { + String parte = partes[i]; + + if (parte == null || parte.isEmpty()) { + continue; // Ignora partes vazias + } + + // Impede nomes inválidos de diretório + if (parte.contains("/") || parte.contains("\\")) { + throw new IllegalArgumentException("Nome de diretório inválido: " + parte); + } + + caminhoAtual.append(parte).append("/"); + + // Verifica se é o último diretório a ser criado + boolean isUltimoDiretorio = (i == partes.length - 1); + + // Verifica se o diretório já existe + if (diretorioAtual.getFilhos().containsKey(parte)) { + if (diretorioAtual.getFilhos().get(parte).isArquivo()) { + throw new CaminhoJaExistenteException("Caminho já existe como arquivo: " + caminhoAtual); + } + + diretorioAtual = diretorioAtual.getFilhos().get(parte); // Ir para o diretório existente + + if (isUltimoDiretorio) { + throw new CaminhoJaExistenteException("Diretório já existe: " + caminhoAtual); + } + + continue; // Se já existe, não cria novamente + } + + // Verifica se o usuário tem permissão para criar o diretório + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (!usuarioObj.getPermissoes().contains("w")) { + try { + diretorioAtual.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminhoAtual); + } + } + + // Cria o novo diretório + Dir novoDiretorio = new Dir(parte, usuario, "rwx"); + diretorioAtual.addFilho(novoDiretorio); + diretorioAtual = novoDiretorio; // Move para o novo diretório criado + + System.out.println("Diretório criado: " + caminhoAtual); + } } @Override public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'chmod'"); + if (caminho == null || caminho.isEmpty() || usuario == null || usuario.isEmpty() || usuarioAlvo == null || usuarioAlvo.isEmpty() || permissao == null || permissao.isEmpty()) { + throw new IllegalArgumentException("Caminho, usuário, usuário alvo e permissão não podem ser nulos"); + } + + // Verifica se o usuário existe + usuarios.stream() + .filter(u -> u.getNome().equals(usuarioAlvo)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Usuário não encontrado: " + usuarioAlvo)); + + if (!permissao.matches("^[rwx-]{3}$")) { + throw new IllegalArgumentException("Permissão inválida: " + permissao); + } + + caminho = caminho.replace("\\", "/"); + if (caminho.endsWith("/")) + caminho = caminho.substring(0, caminho.length() - 1); + + Dir dir = irPara(caminho); + + // Verifica se o usuário tem permissão para criar o diretório + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (usuarioObj.getPermissoes().contains("w")) { + try { + dir.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + } else { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + + dir.setPermissoesUsuario(usuarioAlvo, permissao); + System.out.println("Permissão alterada para " + usuarioAlvo + " em " + caminho + ": " + permissao); } @Override public void rm(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'rm'"); + + if (caminho == null || caminho.isEmpty() || usuario == null || usuario.isEmpty()) { + throw new IllegalArgumentException("Caminho e usuário não podem ser nulos"); + } + + + caminho = caminho.replace("\\", "/"); + if (caminho.endsWith("/")) + caminho = caminho.substring(0, caminho.length() - 1); + + Dir dir; + + try { + dir = irPara(caminho); + } catch (CaminhoNaoEncontradoException e) { + // Tentativa de recuperar o arquivo pelo pai + int ultimoBarra = caminho.lastIndexOf('/'); + if (ultimoBarra == -1) + throw e; + + String caminhoPai = caminho.substring(0, ultimoBarra); + String nomeArquivo = caminho.substring(ultimoBarra + 1); + + Dir pai = irPara(caminhoPai); + Dir possivelArquivo = pai.getFilhos().get(nomeArquivo); + + if (possivelArquivo != null && possivelArquivo.isArquivo()) { + dir = possivelArquivo; + } else { + throw new CaminhoNaoEncontradoException("Arquivo ou diretório não encontrado: " + caminho); + } + } + + // Busca o objeto usuário + Usuario usuarioObj = null; + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + break; + } + } + + if (usuarioObj == null) { + throw new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + // Verifica permissão de escrita + if (usuarioObj.getPermissoes().contains("w")) { + try { + dir.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para remover: " + dir.getNome()); + } + } else { + throw new PermissaoException("Usuário não tem permissão para remover: " + dir.getNome()); + } + + // Verifica se pode remover diretório com conteúdo + if (!dir.isArquivo() && dir.temSubdiretorios() && !recursivo) { + throw new PermissaoException( + "Esse diretório contém subdiretórios. Use o parâmetro recursivo para removê-lo."); + } + + // Remoção + if (dir.isArquivo()) { + dir.getPai().removeFilho(dir.getNome()); + System.out.println("Arquivo removido: " + caminho); + } else { + if (recursivo) { + for (Dir filho : new ArrayList<>(dir.getFilhos().values())) { + rm(filho.getCaminhoCompleto(), usuario, true); + } + } + dir.getPai().removeFilho(dir.getNome()); + System.out.println("Diretório removido: " + caminho); + } } @Override - public void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'touch'"); + public void touch(String caminho, String usuario) + throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException { + if (caminho == null || caminho.isEmpty() || usuario == null || usuario.isEmpty()) { + throw new IllegalArgumentException("Caminho e usuário não podem ser nulos"); + } + + caminho = caminho.replace("\\", "/"); + if (caminho.endsWith("/")) + caminho = caminho.substring(0, caminho.length() - 1); + + int idx = caminho.lastIndexOf('/'); + String nomeArquivo = caminho.substring(idx + 1); + String caminhoPai = (idx <= 0) ? "/" : caminho.substring(0, idx); + + Dir dirPai = irPara(caminhoPai); + + if (dirPai.getFilhos().containsKey(nomeArquivo)) { + throw new CaminhoJaExistenteException("Arquivo ou diretório já existe: " + caminho); + } + + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (usuarioObj.getPermissoes().contains("w")) { + try { + dirPai.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para criar arquivo: " + caminho); + } + } else { + throw new PermissaoException("Usuário não tem permissão para criar arquivo: " + caminho); + } + + File novoArquivo = new File(nomeArquivo, usuario, "rwx"); + dirPai.addFilho(novoArquivo); + System.out.println("Arquivo criado: " + caminho); } @Override public void write(String caminho, String usuario, boolean anexar, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'write'"); + if (caminho == null || usuario == null || buffer == null || caminho.isEmpty() || usuario.isEmpty() || buffer.length == 0) { + throw new IllegalArgumentException("Caminho, usuário e buffer não podem ser nulos"); + } + + caminho = caminho.replace("\\", "/"); + if (caminho.endsWith("/")) { + caminho = caminho.substring(0, caminho.length() - 1); + } + + Dir diretorio = irPara(caminho); + + if (diretorio == null) { + throw new CaminhoNaoEncontradoException("Caminho não encontrado: " + caminho); + } + + if (!diretorio.isArquivo()) { + throw new IllegalArgumentException("O caminho especificado não é um arquivo: " + caminho); + } + + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (usuarioObj.getPermissoes().contains("w")) { + try { + diretorio.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + } else { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + + File arquivo = (File) diretorio; + if (!anexar) + arquivo.limparBlocos(); + + int offset = 0; + + while (offset < buffer.length) { + // Tamanho do bloco a ser escrito + int tamanhoBloco = Math.min(buffer.length - offset, File.TAMANHO_BYTES_BLOCO); + // Bloco de dados a ser escrito + byte[] blocoDados = new byte[tamanhoBloco]; + // Copiar dados para o bloco + System.arraycopy(buffer, offset, blocoDados, 0, tamanhoBloco); + + // Criar novo bloco de dados + BlocoDeDados novoBloco = new BlocoDeDados(blocoDados); + // Adicionar bloco ao arquivo + arquivo.addBloco(novoBloco); + // Atualizar offset para o próximo bloco + offset += tamanhoBloco; + } } @Override - public void read(String caminho, String usuario, byte[] buffer) + public int read(String caminho, String usuario, byte[] buffer, int offset) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'read'"); + if (caminho == null || usuario == null || buffer == null || caminho.isEmpty() || usuario.isEmpty() || buffer.length == 0) { + throw new IllegalArgumentException("Caminho, usuário e buffer não podem ser nulos"); + } + + caminho = caminho.replace("\\", "/"); + if (caminho.endsWith("/")) { + caminho = caminho.substring(0, caminho.length() - 1); + } + + Dir diretorio = irPara(caminho); + + if (!diretorio.isArquivo()) { + throw new IllegalArgumentException("O caminho especificado não é um arquivo: " + caminho); + } + + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (usuarioObj.getPermissoes().contains("r")) { + try { + diretorio.temPerm(usuario, "r"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + } else { + throw new PermissaoException("Usuário não tem permissão para criar diretório: " + caminho); + } + + File arquivo = (File) diretorio; + int bufferOffset = 0; + int arquivoOffset = 0; + + // Lê os blocos do arquivo e copia para o buffer + for (BlocoDeDados bloco : arquivo.getBlocos()) { + byte[] dadosBloco = bloco.getDados(); + int tamanhoBloco = dadosBloco.length; + + // Se o offset ainda não foi alcançado, pula bytes + if (arquivoOffset + tamanhoBloco <= offset) { + arquivoOffset += tamanhoBloco; + continue; + } + + // Calcula o início da leitura dentro do bloco + int inicioLeitura = Math.max(0, offset - arquivoOffset); + int bytesDisponiveis = tamanhoBloco - inicioLeitura; + int bytesRestantes = Math.min(buffer.length - bufferOffset, bytesDisponiveis); + + // Copia os dados do bloco para o buffer + System.arraycopy(dadosBloco, inicioLeitura, buffer, bufferOffset, bytesRestantes); + bufferOffset += bytesRestantes; + + // Se o buffer estiver cheio, sai do loop + if (bufferOffset >= buffer.length) { + break; + } + } + + return bufferOffset; } @Override public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mv'"); + if (caminhoAntigo == null || caminhoNovo == null || usuario == null || caminhoAntigo.isEmpty() || caminhoNovo.isEmpty() || usuario.isEmpty()) { + throw new IllegalArgumentException("Caminho antigo, caminho novo e usuário não podem ser nulos"); + } + + caminhoAntigo = caminhoAntigo.replace("\\", "/"); + caminhoNovo = caminhoNovo.replace("\\", "/"); + + if (caminhoAntigo.endsWith("/")) { + caminhoAntigo = caminhoAntigo.substring(0, caminhoAntigo.length() - 1); + } + if (caminhoNovo.endsWith("/")) { + caminhoNovo = caminhoNovo.substring(0, caminhoNovo.length() - 1); + } + + if (caminhoAntigo.equals(caminhoNovo)) { + throw new IllegalArgumentException("Caminho antigo e caminho novo não podem ser iguais"); + } + + Dir dirantigo = irPara(caminhoAntigo); + + Usuario usuarioObj = usuarios.stream() + .filter(u -> u.getNome().equals(usuario)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Usuário não encontrado: " + usuario)); + + if (usuarioObj.getPermissoes().contains("r")) { + try { + dirantigo.temPerm(usuario, "r"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Usuário não tem permissão para mover: " + caminhoAntigo); + } + } else { + throw new PermissaoException("Usuário não tem permissão para mover: " + caminhoAntigo); + } + + try { + Dir destino = irPara(caminhoNovo); + + if (usuarioObj.getPermissoes().contains("w")) { + try { + destino.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Sem permissão de escrita no destino"); + } + } else { + throw new PermissaoException("Sem permissão de escrita no destino"); + } + + if (destino.getFilhos().containsKey(dirantigo.getNome())) { + throw new IllegalArgumentException("Já existe um diretório ou arquivo com esse nome no destino"); + } + + dirantigo.getPai().removeFilho(dirantigo.getNome()); + destino.addFilho(dirantigo); + } catch (CaminhoNaoEncontradoException e) { + int idx = caminhoNovo.lastIndexOf('/'); + String novoNome = caminhoNovo.substring(idx + 1); + String caminhoPaiNovo = (idx <= 0) ? "/" : caminhoNovo.substring(0, idx); + Dir novoPai = irPara(caminhoPaiNovo); + + if (usuarioObj.getPermissoes().contains("w")) { + try { + novoPai.temPerm(usuario, "w"); + } catch (IllegalArgumentException ex) { + throw new PermissaoException("Sem permissão de escrita no novo caminho"); + } + } else { + throw new PermissaoException("Sem permissão de escrita no novo caminho"); + } + + if (novoPai.getFilhos().containsKey(novoNome)) { + throw new IllegalArgumentException("Já existe um objeto com esse nome no destino"); + } + + dirantigo.getPai().removeFilho(dirantigo.getNome()); + dirantigo.setNome(novoNome); + novoPai.addFilho(dirantigo); + } } @Override - public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'ls'"); + public void ls(String caminho, String usuario, boolean recursivo) + throws CaminhoNaoEncontradoException, PermissaoException { + Dir diretorio = irPara(caminho); + + // Verifica se o usuário tem permissão para criar o diretório + Usuario usuarioObj = null; + + for (Usuario user : usuarios) { + if (user.getNome().equals(usuario)) { + usuarioObj = user; + } + } + + if (usuarioObj == null) { + new IllegalArgumentException("Usuário não encontrado: " + usuario); + } + + if (usuarioObj.getPermissoes().contains("r")) { + try { + diretorio.temPerm(usuario, "r"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Você não tem permissão para listar este diretório!"); + } + } else { + throw new PermissaoException("Você não tem permissão para listar este diretório!"); + } + + String output = lsRecursivo(diretorio, caminho, recursivo, usuario); + System.out.print(output); } @Override public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'cp'"); + if (caminhoOrigem == null || caminhoDestino == null || usuario == null || caminhoOrigem.isEmpty() || caminhoDestino.isEmpty() || usuario.isEmpty()) { + throw new IllegalArgumentException("Caminho de origem, destino e usuário não podem ser nulos"); + } + + caminhoOrigem = caminhoOrigem.replace("\\", "/").replaceAll("/$", ""); + caminhoDestino = caminhoDestino.replace("\\", "/").replaceAll("/$", ""); + + Dir origem = irPara(caminhoOrigem); + Dir destino = irPara(caminhoDestino); + + Usuario usuarioObj = usuarios.stream() + .filter(u -> u.getNome().equals(usuario)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("Usuário não encontrado: " + usuario)); + + if (usuarioObj.getPermissoes().contains("rw")) { + try { + origem.temPerm(usuario, "r"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Sem permissão de leitura em: " + caminhoOrigem); + } + try { + origem.temPerm(usuario, "w"); + } catch (IllegalArgumentException e) { + throw new PermissaoException("Sem permissão de escrita em: " + caminhoDestino); + } + } else { + throw new PermissaoException("Usuário não tem permissão para copiar: " + caminhoOrigem); + } + + String nomeOrigem = origem.getNome(); + + // Se destino for um arquivo, substituí-lo se possível + if (destino instanceof File) { + if (!origem.isArquivo()) { + throw new IllegalArgumentException("Não é possível copiar um diretório para um arquivo"); + } + copiarConteudoArquivo((File) origem, (File) destino, usuario); + System.out.println("Arquivo sobrescrito: " + destino.getCaminhoCompleto()); + return; + } + + // Se for diretório, verificar se já existe um filho com o mesmo nome + Dir existente = destino.getFilhos().get(nomeOrigem); + + if (existente != null) { + // Se for arquivo, sobrescreve + if (existente.isArquivo() && origem.isArquivo()) { + copiarConteudoArquivo((File) origem, (File) existente, usuario); + System.out.println("Arquivo sobrescrito: " + existente.getCaminhoCompleto()); + return; + } else { + throw new PermissaoException( + "Já existe um diretório/arquivo com esse nome: " + existente.getCaminhoCompleto()); + } + } + + if (origem.isArquivo()) { + File arquivoOrigem = (File) origem; + File arquivoNovo = new File(arquivoOrigem.getNome(), usuario, "rwx"); + for (BlocoDeDados bloco : arquivoOrigem.getBlocos()) { + // Copia física dos blocos + byte[] dadosCopiados = bloco.getDados().clone(); // copia conteúdo + arquivoNovo.addBloco(new BlocoDeDados(dadosCopiados)); + } + destino.addFilho(arquivoNovo); + System.out.println("Arquivo copiado: " + arquivoNovo.getCaminhoCompleto()); + } else { + if (!recursivo) { + throw new IllegalArgumentException("Cópia de diretório requer o modo recursivo"); + } + + Dir novoDir = new Dir(origem.getNome(), usuario, "rwx"); + destino.addFilho(novoDir); + for (Dir filho : origem.getFilhos().values()) { + cp(filho.getCaminhoCompleto(), novoDir.getCaminhoCompleto(), usuario, true); + } + System.out.println("Diretório copiado: " + novoDir.getCaminhoCompleto()); + } + } + + // Método auxiliar + private void copiarConteudoArquivo(File origem, File destino, String usuario) { + destino.limparBlocos(); + for (BlocoDeDados bloco : origem.getBlocos()) { + byte[] dadosCopiados = bloco.getDados().clone(); + destino.addBloco(new BlocoDeDados(dadosCopiados)); + } } - public void addUser(String user) { - throw new UnsupportedOperationException("Método não implementado 'addUser'"); + @Override + public void addUser(Usuario usuario) { + if (usuario == null || usuario.getNome() == null || usuario.getNome().isEmpty() + || usuario.getPermissoes() == null || usuario.getPermissoes().isEmpty()) { + throw new IllegalArgumentException("Usuário, nome e permissões não podem ser nulos"); + } + + // Verifica se o usuário já existe + for (Usuario u : usuarios) { + if (u.getNome().equals(usuario.getNome())) { + throw new IllegalArgumentException("Usuário já existe: " + usuario.getNome()); + } + } + + // Adiciona o novo usuário + usuarios.add(usuario); + System.out.println("Usuário adicionado: " + usuario.getNome()); } -} +} \ No newline at end of file diff --git a/filesys/IFileSystem.java b/filesys/IFileSystem.java index a0f0ce0..60a815c 100644 --- a/filesys/IFileSystem.java +++ b/filesys/IFileSystem.java @@ -5,7 +5,7 @@ import exception.PermissaoException; // Apenas modifique essa interface caso seja EXTREMAMENTE necessário. -// Documente & Justifique TODAS asalterações feitas. +// Documente & Justifique TODAS as alterações feitas. public interface IFileSystem { // Altera as permissões de um arquivo ou diretório. // Configura a permissao do caminho para o usuarioAlvo. @@ -21,7 +21,8 @@ public interface IFileSystem { void rm(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException; // Cria um novo arquivo. Atenção: Se o arquivo já existir, será lançada uma exceção. - void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException; + // ADD: exceção CaminhoNaoEncontradoException + void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException; // Escreve dados em um arquivo. Se o diretório não existir, será lançada uma exceção. // Caso o diretório exista, o arquivo será criado ou sobrescrito. @@ -31,7 +32,9 @@ public interface IFileSystem { // Lê dados de um arquivo. Se o arquivo não existir, será lançada uma exceção. // Leitura sequencial - todo o conteudo do arquivo sera lido e armazenado no buffer. - void read(String caminho, String usuario, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException; + // ADD: offset para indicar a partir de qual posição do buffer os dados serão lidos. + // MOD: void -> int (objetivo: retornar offset do buffer após a leitura) + int read(String caminho, String usuario, byte[] buffer, int offset) throws CaminhoNaoEncontradoException, PermissaoException; // Move ou renomeia um arquivo ou diretório. Se o diretório não existir, será lançada uma exceção. // Se o diretório já existir, será sobrescrito. @@ -44,4 +47,7 @@ public interface IFileSystem { // Copia um arquivo ou diretório. Se o diretório não existir, será lançada uma exceção. void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException; + + // ADD: adiciona um usuário ao sistema de arquivos + void addUser(Usuario usuario); } \ No newline at end of file diff --git a/filesys/Usuario.java b/filesys/Usuario.java new file mode 100644 index 0000000..6d8deb5 --- /dev/null +++ b/filesys/Usuario.java @@ -0,0 +1,30 @@ +package filesys; + +public class Usuario { + private String nome; + private String diretorio; + private String permissoes; + + public Usuario(String nome, String diretorio, String permissoes) { + this.nome = nome; + this.diretorio = diretorio; + this.permissoes = permissoes; + } + + public String getNome() { + return nome; + } + + public String getDiretorio() { + return diretorio; + } + + public String getPermissoes() { + return permissoes; + } + + @Override + public String toString() { + return nome + " " + diretorio + " " + permissoes; + } +} \ No newline at end of file diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..1c840f2 --- /dev/null +++ b/run.bat @@ -0,0 +1,15 @@ +@echo off +echo. + +echo Criando pasta bin... +mkdir bin 2>nul + +echo Compilando programa... +javac -d bin Main.java + +echo Rodando programa... +timeout /t 3 +cls + +java -cp bin Main -u "root" +pause diff --git a/tests/FileSystemImplTest.java b/tests/FileSystemImplTest.java new file mode 100644 index 0000000..8089084 --- /dev/null +++ b/tests/FileSystemImplTest.java @@ -0,0 +1,287 @@ +package tests; + +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; + +import exception.CaminhoJaExistenteException; +import exception.CaminhoNaoEncontradoException; +import exception.PermissaoException; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeAll; + +import filesys.FileSystemImpl; +import filesys.IFileSystem; +import filesys.Usuario; + +// Essa classe testa cenários de permissão +public class FileSystemImplTest { + private static IFileSystem fileSystem; + byte[] buffer = new byte[1024]; + + @BeforeAll + public static void setUp() throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException { + fileSystem = new FileSystemImpl(); + + fileSystem.addUser(new Usuario("maria", "/", "r-x")); + fileSystem.addUser(new Usuario("joao", "/", "rwx")); + fileSystem.addUser(new Usuario("tiago", "/", "rw-")); + fileSystem.addUser(new Usuario("cega", "/", "-wx")); + + fileSystem.mkdir("/area1", "joao"); + fileSystem.mkdir("/area1/area2", "joao"); + fileSystem.mkdir("/area1/area2/area_meh", "root"); + + fileSystem.touch("/area1/area2/arquivo.txt", "joao"); + fileSystem.touch("/area1/area2/arquivo_meh.txt", "joao"); + } + + + // =============== MKDIR =============== + + @Test + public void testMkdirSuccess() throws CaminhoJaExistenteException, PermissaoException { + // Tenta criar um diretório com permissão de rwx + assertDoesNotThrow(() -> fileSystem.mkdir("/area1/area2/area3", "root")); + } + + @Test + public void testMkdirPermissionFail() { + // Tenta criar um diretório sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.mkdir("/area1/area2/area3/area4", "maria")); + } + + + // =============== TOUCH =============== + + @Test + public void testTouchSuccess() throws CaminhoJaExistenteException, PermissaoException, CaminhoNaoEncontradoException { + // Tenta criar um arquivo com permissão de rwx + assertDoesNotThrow(() -> fileSystem.touch("/area1/arquivo2.txt", "joao")); + } + + @Test + public void testTouchPermissionFail() { + // Tenta criar um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.touch("/area1/area2/arquivo2.txt", "maria")); + } + + @Test + public void testTouchPathFail() { + // Tenta criar um arquivo em um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.touch("/area1/area2/inexistente/arquivo3.txt", "root")); + } + + @Test + public void testTouchAlreadyExists() { + // Tenta criar um arquivo que já existe + assertThrows(CaminhoJaExistenteException.class, () -> fileSystem.touch("/area1/area2/arquivo.txt", "joao")); + } + + + // =============== CHMOD =============== + + @Test + public void testChmodSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta alterar as permissões de um diretório existente + assertDoesNotThrow(() -> fileSystem.chmod("/area1/area2", "root", "tiago", "rwx")); + } + + @Test + public void testChmodPermissionFail() { + // Tenta alterar as permissões de um diretório sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.chmod("/area1/area2", "maria", "tiago", "rwx")); + } + + @Test + public void testChmodPathFail() { + // Tenta alterar as permissões de um diretório inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.chmod("/area1/area2/inexistente", "root", "tiago", "rwx")); + } + + @Test + public void testChmodInvalidPermission() { + // Tenta alterar as permissões de um diretório com permissões inválidas + assertThrows(IllegalArgumentException.class, () -> fileSystem.chmod("/area1/area2", "root", "tiago", "rw")); + } + + + // =============== LS =============== + + @Test + public void testLsSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta listar o conteúdo de um diretório com permissão + assertDoesNotThrow(() -> fileSystem.ls("/area1", "joao", true)); + } + + @Test + public void testlsNaoRecursiveSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta listar o conteúdo de um diretório sem permissão de leitura recursiva + assertDoesNotThrow(() -> fileSystem.ls("/area1", "joao", false)); + } + + @Test + public void testLsPermissionFail() { + // Tenta listar o conteúdo de um diretório sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.ls("/area1/area2", "cega", true)); + } + + @Test + public void testLsPathFail() { + // Tenta listar o conteúdo de um diretório inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.ls("/area1/area2/inexistente", "joao", true)); + } + + + // =============== CP =============== + + @Test + public void testCpSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta copiar um arquivo com permissão + assertDoesNotThrow(() -> fileSystem.cp("/area1/area2/arquivo.txt", "/area1", "root", true)); + } + + @Test + public void testCpPermissionFail() { + // Tenta copiar um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.cp("/area1/area2/arquivo.txt", "/area1/area2", "maria", true)); + } + + @Test + public void testCpPathFail() { + // Tenta copiar um arquivo de um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.cp("/area1/area2/inexistente/arquivo.txt", "/area1/area2", "root", true)); + } + + @Test + public void testSobrescreverArquivoSucesso() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta copiar um arquivo sobrescrevendo outro existente + assertDoesNotThrow(() -> fileSystem.cp("/area1/area2/arquivo.txt", "/area1/area2/arquivo.txt", "joao", true)); + } + + + // =============== RM =============== + + @Test + public void testRmSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta remover um arquivo com permissão + assertDoesNotThrow(() -> fileSystem.rm("/area1/area2/arquivo.txt", "joao", true)); + } + + @Test + public void testRmPermissionFail() { + // Tenta remover um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.rm("/area1/area2/arquivo.txt", "maria", true)); + } + + @Test + public void testRmPathFail() { + // Tenta remover um arquivo de um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.rm("/area1/area2/inexistente/arquivo.txt", "joao", true)); + } + + + // =============== MV =============== + + @Test + public void testMvInSamePlaceRenamingSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta mover um arquivo com permissão + assertDoesNotThrow(() -> fileSystem.mv("/area1/area2/arquivo_meh.txt", "/area1/area2/arquivo_moved.txt", "root")); + } + + @Test + public void testMvInSamePlaceFail() { + // Tenta mover um arquivo para o mesmo lugar sem permissão + assertThrows(IllegalArgumentException.class, () -> fileSystem.mv("/area1/area2/arquivo_moved.txt", "/area1/area2/arquivo_moved.txt", "root")); + } + + @Test + public void testMvPermissionFail() { + // Tenta mover um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.mv("/area1/area2/area_meh", "/area1/area3", "maria")); + } + + @Test + public void testMvPathFail() { + // Tenta mover um arquivo de um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.mv("/area1/area2/inexistente/arquivo.txt", "/area1/area2/arquivo_moved.txt", "root")); + } + + + // =============== READ =============== + + @Test + public void testReadSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta ler um arquivo com permissão + assertDoesNotThrow(() -> fileSystem.read("/area1/area2/arquivo.txt", "joao", buffer, 0)); + } + + @Test + public void testReadPermissionFail() { + // Tenta ler um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.read("/area1/area2/arquivo.txt", "cega", buffer, 0)); + } + + @Test + public void testReadPathFail() { + // Tenta ler um arquivo de um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.read("/area1/area2/inexistente/arquivo.txt", "joao", buffer, 0)); + } + + + // =============== WRITE =============== + + @Test + public void testWriteSuccess() throws CaminhoNaoEncontradoException, PermissaoException { + // Tenta escrever em um arquivo com permissão + assertDoesNotThrow(() -> fileSystem.write("/area1/arquivo2.txt", "joao", true, buffer)); + } + + @Test + public void testWritePermissionFail() { + // Tenta escrever em um arquivo sem permissão + assertThrows(PermissaoException.class, () -> fileSystem.write("/area1/area2/arquivo.txt", "maria", true, buffer)); + } + + @Test + public void testWritePathFail() { + // Tenta escrever em um arquivo de um caminho inexistente + assertThrows(CaminhoNaoEncontradoException.class, () -> fileSystem.write("/area1/area2/inexistente/arquivo.txt", "joao", true, buffer)); + } + + + //=============== User =============== + + @Test + public void testAddUser() { + // Tenta adicionar um usuário com permissão + assertDoesNotThrow(() -> fileSystem.addUser(new Usuario("carlos", "/", "rwx"))); + } + + @Test + public void testAddUserWithExistingName() { + // Tenta adicionar um usuário com nome já existente + assertThrows(IllegalArgumentException.class, () -> fileSystem.addUser(new Usuario("maria", "/", "rwx"))); + } + + @Test + public void testAddUserWithInvalidPermission() { + // Tenta adicionar um usuário com permissões inválidas + assertThrows(IllegalArgumentException.class, () -> fileSystem.addUser(new Usuario("carlos", "/", "rw"))); + } + + @Test + public void testAddUserWithEmptyName() { + // Tenta adicionar um usuário com nome vazio + assertThrows(IllegalArgumentException.class, () -> fileSystem.addUser(new Usuario("", "/", "rwx"))); + } + + @Test + public void testAddUserWithoutDirectory() { + // Tenta adicionar um usuário sem diretório + assertThrows(IllegalArgumentException.class, () -> fileSystem.addUser(new Usuario("carlos", null, "rwx"))); + } + +} \ No newline at end of file diff --git a/tests/PermissionTest.java b/tests/PermissionTest.java deleted file mode 100644 index 6026e31..0000000 --- a/tests/PermissionTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package tests; - -import static org.junit.Assert.assertTrue; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.BeforeAll; - -import filesys.FileSystemImpl; -import filesys.IFileSystem; - -// Essa classe testa cenários de permissão -public class PermissionTest { - private static IFileSystem fileSystem; - - @BeforeAll - public static void setUp() { - fileSystem = new FileSystemImpl(/*args...*/); - } - - @Test - public void testPermission() { - // Teste de permissão - assertTrue(true); - } -}