From 7a02e89bc7fb413a715cad47fda423e7d551e364 Mon Sep 17 00:00:00 2001 From: Mirelly Pego Cordeiro de Alvarenga Date: Sun, 15 Jun 2025 19:39:44 -0300 Subject: [PATCH 1/5] =?UTF-8?q?Cria=C3=A7=C3=A3o=20dos=20arquivos=20de=20b?= =?UTF-8?q?ase:=20Arquivo,=20Bloco,=20MetaDados=20e=20Diretorio=20-=20Impl?= =?UTF-8?q?ementa=C3=A7=C3=A3o=20de=20alguns=20met=C3=B3dos=20em=20FileSys?= =?UTF-8?q?temImpl=20-=20Implementa=C3=A7=C3=A3o=20dos=20arquivos=20de=20t?= =?UTF-8?q?este=20dos=20arquivos=20criados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filesys/Arquivo.java | 23 +++++ filesys/Bloco.java | 17 ++++ filesys/Diretorio.java | 49 ++++++++++ filesys/FileSystemImpl.java | 170 +++++++++++++++++++++++++++------- filesys/MetaDados.java | 52 +++++++++++ tests/ArquivoTest.java | 27 ++++++ tests/BlocoTest.java | 22 +++++ tests/DiretorioTest.java | 37 ++++++++ tests/FileSystemImplTest.java | 65 +++++++++++++ tests/MetaDadosTest.java | 52 +++++++++++ 10 files changed, 482 insertions(+), 32 deletions(-) create mode 100644 filesys/Arquivo.java create mode 100644 filesys/Bloco.java create mode 100644 filesys/Diretorio.java create mode 100644 filesys/MetaDados.java create mode 100644 tests/ArquivoTest.java create mode 100644 tests/BlocoTest.java create mode 100644 tests/DiretorioTest.java create mode 100644 tests/FileSystemImplTest.java create mode 100644 tests/MetaDadosTest.java diff --git a/filesys/Arquivo.java b/filesys/Arquivo.java new file mode 100644 index 0000000..7a10d16 --- /dev/null +++ b/filesys/Arquivo.java @@ -0,0 +1,23 @@ +package filesys; + +import java.util.ArrayList; +import java.util.List; + +public class Arquivo { + private MetaDados metaDados; + private List blocos; + + public Arquivo(String nome, String dono) { + this.metaDados = new MetaDados(nome, dono); + this.blocos = new ArrayList<>(); + } + + public MetaDados getMetaDados() { + return metaDados; + } + + public List getBlocos() { + return blocos; + } + +} \ No newline at end of file diff --git a/filesys/Bloco.java b/filesys/Bloco.java new file mode 100644 index 0000000..1ba298b --- /dev/null +++ b/filesys/Bloco.java @@ -0,0 +1,17 @@ +package filesys; + +public class Bloco { + private byte[] dados; + + public Bloco(int tamanho) { + this.dados = new byte[tamanho]; + } + + public byte[] getDados() { + return dados; + } + + public void setDados(byte[] dados) { + this.dados = dados; + } +} \ No newline at end of file diff --git a/filesys/Diretorio.java b/filesys/Diretorio.java new file mode 100644 index 0000000..3c9264d --- /dev/null +++ b/filesys/Diretorio.java @@ -0,0 +1,49 @@ +package filesys; + +import java.util.*; + +public class Diretorio { + private MetaDados metaDados; + private Map subDiretorio; + private Map arquivos; + private Diretorio pai; + + public Diretorio(String nome, String dono, Diretorio pai) { + this.metaDados = new MetaDados(nome, dono); + this.subDiretorio = new HashMap<>(); + this.arquivos = new HashMap<>(); + this.pai = pai; + } + + public MetaDados getMetaDados() { + return metaDados; + } + + public Map getSubDiretorio() { + return subDiretorio; + } + + public Map getArquivos() { + return arquivos; + } + + public Diretorio getPai() { + return pai; + } + + public void addSubDiretorio(Diretorio dir) { + subDiretorio.put(dir.getMetaDados().getNome(), dir); + } + + public void addArquivo(Arquivo arq) { + arquivos.put(arq.getMetaDados().getNome(), arq); + } + + public boolean existeSubDiretorio(String nome) { + return subDiretorio.containsKey(nome); + } + + public boolean existeArquivo(String nome) { + return arquivos.containsKey(nome); + } +} \ No newline at end of file diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index 45fa05d..bf3dab9 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -4,67 +4,173 @@ import exception.CaminhoNaoEncontradoException; import exception.PermissaoException; -// 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 Diretorio raiz; - public FileSystemImpl() {} + public FileSystemImpl() { + raiz = new Diretorio("/", ROOT_USER, null); + // root tem permissão total na raiz + raiz.getMetaDados().setPermissao(ROOT_USER, "rwx"); + } - @Override - public void mkdir(String caminho, String nome) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mkdir'"); + // Utilitário: Navega até o diretório/arquivo alvo + private Diretorio navegarParaDiretorio(String caminho) throws CaminhoNaoEncontradoException { + if (!caminho.startsWith("/")) + throw new CaminhoNaoEncontradoException("Caminho inválido: " + caminho); + if (caminho.equals("/")) + return raiz; + + String[] partes = caminho.split("/"); + Diretorio atual = raiz; + for (int i = 1; i < partes.length; i++) { + if (partes[i].isEmpty()) + continue; + if (!atual.getSubDiretorio().containsKey(partes[i])) { + throw new CaminhoNaoEncontradoException("Diretório não encontrado: " + partes[i]); + } + atual = atual.getSubDiretorio().get(partes[i]); + } + return atual; } - @Override - public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) - throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'chmod'"); + // Retorna [diretorioPai, nomeFinal] + private Object[] navegarParaPai(String caminho) throws CaminhoNaoEncontradoException { + if (!caminho.startsWith("/")) + throw new CaminhoNaoEncontradoException("Caminho inválido: " + caminho); + int idx = caminho.lastIndexOf('/'); + String pathPai = (idx == 0) ? "/" : caminho.substring(0, idx); + String nomeFinal = caminho.substring(idx + 1); + Diretorio pai = navegarParaDiretorio(pathPai); + return new Object[] { pai, nomeFinal }; + } + + private void checarPermissaoEscrita(Diretorio dir, String usuario) throws PermissaoException { + if (!dir.getMetaDados().hasPermissao(usuario, 'w')) { + throw new PermissaoException( + "Usuário sem permissão de escrita no diretório " + dir.getMetaDados().getNome()); + } + } + + private void checarPermissaoLeitura(Diretorio dir, String usuario) throws PermissaoException { + if (!dir.getMetaDados().hasPermissao(usuario, 'r')) { + throw new PermissaoException( + "Usuário sem permissão de leitura no diretório " + dir.getMetaDados().getNome()); + } } @Override - public void rm(String caminho, String usuario, boolean recursivo) - throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'rm'"); + public void mkdir(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { + try { + Object[] res = navegarParaPai(caminho); + Diretorio pai = (Diretorio) res[0]; + String nomeNovo = (String) res[1]; + + checarPermissaoEscrita(pai, usuario); + + if (pai.existeSubDiretorio(nomeNovo) || pai.existeArquivo(nomeNovo)) { + throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome."); + } + Diretorio novo = new Diretorio(nomeNovo, usuario, pai); + pai.addSubDiretorio(novo); + } catch (CaminhoNaoEncontradoException e) { + throw new CaminhoJaExistenteException("Diretório pai não encontrado."); + } } @Override public void touch(String caminho, String usuario) throws CaminhoJaExistenteException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'touch'"); + try { + Object[] res = navegarParaPai(caminho); + Diretorio pai = (Diretorio) res[0]; + String nomeNovo = (String) res[1]; + + checarPermissaoEscrita(pai, usuario); + + if (pai.existeArquivo(nomeNovo) || pai.existeSubDiretorio(nomeNovo)) { + throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome."); + } + Arquivo novo = new Arquivo(nomeNovo, usuario); + pai.addArquivo(novo); + } catch (CaminhoNaoEncontradoException e) { + throw new CaminhoJaExistenteException("Diretório pai não encontrado."); + } } @Override - public void write(String caminho, String usuario, boolean anexar, byte[] buffer) + public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'write'"); + Diretorio dir = navegarParaDiretorio(caminho); + checarPermissaoLeitura(dir, usuario); + listarConteudo(dir, "", recursivo); + } + + private void listarConteudo(Diretorio dir, String prefixo, boolean recursivo) { + System.out.println(prefixo + dir.getMetaDados().getNome() + "/"); + for (Arquivo arq : dir.getArquivos().values()) { + System.out.println(prefixo + " " + arq.getMetaDados().getNome()); + } + if (recursivo) { + for (Diretorio sub : dir.getSubDiretorio().values()) { + listarConteudo(sub, prefixo + " ", true); + } + } else { + for (Diretorio sub : dir.getSubDiretorio().values()) { + System.out.println(prefixo + " " + sub.getMetaDados().getNome() + "/"); + } + } } @Override - public void read(String caminho, String usuario, byte[] buffer) + public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'read'"); + // Pode ser arquivo ou diretório + Object[] res = navegarParaPai(caminho); + Diretorio pai = (Diretorio) res[0]; + String nome = (String) res[1]; + + if (pai.existeArquivo(nome)) { + Arquivo arq = pai.getArquivos().get(nome); + MetaDados md = arq.getMetaDados(); + if (!usuario.equals(ROOT_USER) && !md.hasPermissao(usuario, 'w')) { + throw new PermissaoException("Sem permissão para alterar permissões desse arquivo."); + } + md.setPermissao(usuarioAlvo, permissao); + } else if (pai.existeSubDiretorio(nome)) { + Diretorio dir = pai.getSubDiretorio().get(nome); + MetaDados md = dir.getMetaDados(); + if (!usuario.equals(ROOT_USER) && !md.hasPermissao(usuario, 'w')) { + throw new PermissaoException("Sem permissão para alterar permissões desse diretório."); + } + md.setPermissao(usuarioAlvo, permissao); + } else { + throw new CaminhoNaoEncontradoException("Arquivo/diretório não encontrado para chmod."); + } } + // Métodos ainda não implementados: @Override - public void mv(String caminhoAntigo, String caminhoNovo, String usuario) - throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'mv'"); + public void rm(String caminho, String usuario, boolean recursivo) { + throw new UnsupportedOperationException("Método não implementado 'rm'"); } @Override - public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'ls'"); + public void write(String caminho, String usuario, boolean anexar, byte[] buffer) { + throw new UnsupportedOperationException("Método não implementado 'write'"); } @Override - public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) - throws CaminhoNaoEncontradoException, PermissaoException { - throw new UnsupportedOperationException("Método não implementado 'cp'"); + public void read(String caminho, String usuario, byte[] buffer) { + throw new UnsupportedOperationException("Método não implementado 'read'"); + } + + @Override + public void mv(String caminhoAntigo, String caminhoNovo, String usuario) { + throw new UnsupportedOperationException("Método não implementado 'mv'"); } - public void addUser(String user) { - throw new UnsupportedOperationException("Método não implementado 'addUser'"); + @Override + public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) { + throw new UnsupportedOperationException("Método não implementado 'cp'"); } -} +} \ No newline at end of file diff --git a/filesys/MetaDados.java b/filesys/MetaDados.java new file mode 100644 index 0000000..a0e2762 --- /dev/null +++ b/filesys/MetaDados.java @@ -0,0 +1,52 @@ +package filesys; + +import java.util.HashMap; +import java.util.Map; + +public class MetaDados { + private String nome; + private int tamanho; + private String dono; + // + private Map permissoes; + + public MetaDados(String nome, String dono) { + this.nome = nome; + this.dono = dono; + this.tamanho = 0; + this.permissoes = new HashMap<>(); + // Dono tem permissão total por padrão + this.permissoes.put(dono, "rwx"); + } + + public String getNome() { return nome; } + public void setNome(String nome) { this.nome = nome; } + + public int getTamanho() { return tamanho; } + public void setTamanho(int tamanho) { this.tamanho = tamanho; } + + public String getDono() { return dono; } + public void setDono(String dono) { this.dono = dono; } + + public Map getPermissoes() { return permissoes; } + + public void setPermissao(String usuario, String permissao) { + permissoes.put(usuario, permissao); + } + + public String getPermissao(String usuario) { + return permissoes.getOrDefault(usuario, "---"); + } + + public boolean hasPermissao(String usuario, char tipo) { + if (usuario.equals("root")) return true; + String p = permissoes.get(usuario); + if (p == null) return false; + switch (tipo) { + case 'r': return p.charAt(0) == 'r'; + case 'w': return p.charAt(1) == 'w'; + case 'x': return p.charAt(2) == 'x'; + default: return false; + } + } +} \ No newline at end of file diff --git a/tests/ArquivoTest.java b/tests/ArquivoTest.java new file mode 100644 index 0000000..08a3aea --- /dev/null +++ b/tests/ArquivoTest.java @@ -0,0 +1,27 @@ +package tests; + +import filesys.Arquivo; +import filesys.Bloco; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class ArquivoTest { + +@Test +public void testConstrutor() { + Arquivo arq = new Arquivo("meu.txt", "mirelly"); + assertEquals("meu.txt", arq.getMetaDados().getNome()); + assertEquals("mirelly", arq.getMetaDados().getDono()); + assertNotNull(arq.getBlocos()); + assertEquals(0, arq.getBlocos().size()); +} + +@Test +public void testAdicionarBloco() { + Arquivo arq = new Arquivo("meu.txt", "mirelly"); + Bloco b = new Bloco(8); + arq.getBlocos().add(b); + assertEquals(1, arq.getBlocos().size()); + assertSame(b, arq.getBlocos().get(0)); +} +} \ No newline at end of file diff --git a/tests/BlocoTest.java b/tests/BlocoTest.java new file mode 100644 index 0000000..81a4993 --- /dev/null +++ b/tests/BlocoTest.java @@ -0,0 +1,22 @@ +package tests; + +import filesys.Bloco; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class BlocoTest { + +@Test +public void testConstrutorETamanho() { + Bloco bloco = new Bloco(10); + assertEquals(10, bloco.getDados().length); +} + +@Test +public void testSetDados() { + Bloco bloco = new Bloco(5); + byte[] novo = {1,2,3,4,5}; + bloco.setDados(novo); + assertArrayEquals(novo, bloco.getDados()); +} +} \ No newline at end of file diff --git a/tests/DiretorioTest.java b/tests/DiretorioTest.java new file mode 100644 index 0000000..026f605 --- /dev/null +++ b/tests/DiretorioTest.java @@ -0,0 +1,37 @@ +package tests; + +import filesys.Diretorio; +import filesys.Arquivo; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class DiretorioTest { + +@Test +public void testConstrutorEGetters() { + Diretorio d = new Diretorio("home", "mirelly", null); + assertEquals("home", d.getMetaDados().getNome()); + assertEquals("mirelly", d.getMetaDados().getDono()); + assertNull(d.getPai()); + assertTrue(d.getSubDiretorio().isEmpty()); + assertTrue(d.getArquivos().isEmpty()); +} + +@Test +public void testAddSubDiretorioEExiste() { + Diretorio pai = new Diretorio("pai", "mirelly", null); + Diretorio filho = new Diretorio("filho", "mirelly", pai); + pai.addSubDiretorio(filho); + assertTrue(pai.existeSubDiretorio("filho")); + assertSame(filho, pai.getSubDiretorio().get("filho")); +} + +@Test +public void testAddArquivoEExiste() { + Diretorio dir = new Diretorio("docs", "mirelly", null); + Arquivo arq = new Arquivo("a.txt", "mirelly"); + dir.addArquivo(arq); + assertTrue(dir.existeArquivo("a.txt")); + assertSame(arq, dir.getArquivos().get("a.txt")); +} +} \ No newline at end of file diff --git a/tests/FileSystemImplTest.java b/tests/FileSystemImplTest.java new file mode 100644 index 0000000..958ddb2 --- /dev/null +++ b/tests/FileSystemImplTest.java @@ -0,0 +1,65 @@ +package tests; + +import filesys.FileSystemImpl; +import exception.CaminhoJaExistenteException; +import exception.PermissaoException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class FileSystemImplTest { + private FileSystemImpl fs; + + @BeforeEach + public void setup() { + fs = new FileSystemImpl(); + } + + @Test + public void testMkdirTouchLs() throws Exception { + fs.mkdir("/home", "root"); + fs.mkdir("/home/mirelly", "root"); + fs.chmod("/home/mirelly", "root", "mirelly", "rwx"); + fs.touch("/home/mirelly/arq.txt", "mirelly"); + fs.ls("/home", "root", false); + fs.ls("/home", "root", true); + } + + @Test + public void testTouchDuplicado() throws Exception { + fs.mkdir("/d", "root"); + fs.chmod("/d", "root", "mirelly", "rwx"); + fs.touch("/d/a.txt", "mirelly"); + assertThrows(CaminhoJaExistenteException.class, () -> { + fs.touch("/d/a.txt", "mirelly"); + }); + } + + @Test + public void testPermissaoEscrita() throws Exception { + fs.mkdir("/priv", "root"); + fs.chmod("/priv", "root", "mirelly", "r--"); + assertThrows(PermissaoException.class, () -> { + fs.touch("/priv/novo.txt", "mirelly"); + }); + } + + @Test + public void testChmodPermissao() throws Exception { + fs.mkdir("/t", "root"); + fs.chmod("/t", "root", "mirelly", "rwx"); + fs.touch("/t/x.txt", "mirelly"); + fs.chmod("/t/x.txt", "root", "outro", "rw-"); + fs.chmod("/t/x.txt", "mirelly", "outro", "rwx"); + } + + @Test + public void testChmodSemPermissao() throws Exception { + fs.mkdir("/abc", "root"); + fs.chmod("/abc", "root", "mirelly", "rwx"); + fs.touch("/abc/y.txt", "mirelly"); + assertThrows(PermissaoException.class, () -> { + fs.chmod("/abc/y.txt", "outro", "mirelly", "rwx"); + }); + } +} \ No newline at end of file diff --git a/tests/MetaDadosTest.java b/tests/MetaDadosTest.java new file mode 100644 index 0000000..2ea1235 --- /dev/null +++ b/tests/MetaDadosTest.java @@ -0,0 +1,52 @@ +package tests; + +import filesys.MetaDados; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class MetaDadosTest { + +@Test +public void testConstrutorEGetters() { + MetaDados md = new MetaDados("arquivo.txt", "mirelly"); + assertEquals("arquivo.txt", md.getNome()); + assertEquals("mirelly", md.getDono()); + assertEquals(0, md.getTamanho()); + assertEquals("rwx", md.getPermissao("mirelly")); +} + +@Test +public void testSetters() { + MetaDados md = new MetaDados("a", "b"); + md.setNome("novo"); + md.setDono("root"); + md.setTamanho(42); + assertEquals("novo", md.getNome()); + assertEquals("root", md.getDono()); + assertEquals(42, md.getTamanho()); +} + +@Test +public void testPermissoesPadrao() { + MetaDados md = new MetaDados("arq", "user1"); + assertEquals("rwx", md.getPermissao("user1")); + assertEquals("---", md.getPermissao("user2")); +} + +@Test +public void testSetPermissao() { + MetaDados md = new MetaDados("arq", "user1"); + md.setPermissao("user2", "rw-"); + assertEquals("rw-", md.getPermissao("user2")); +} + +@Test +public void testHasPermissao() { + MetaDados md = new MetaDados("arq", "user1"); + md.setPermissao("user2", "rw-"); + assertTrue(md.hasPermissao("user1", 'r')); + assertTrue(md.hasPermissao("user2", 'w')); + assertFalse(md.hasPermissao("user2", 'x')); + assertTrue(md.hasPermissao("root", 'x')); +} +} \ No newline at end of file From 80ad63ffda8b650b0b7a9d29e4afdb0d94c41606 Mon Sep 17 00:00:00 2001 From: ALuiz19 Date: Tue, 17 Jun 2025 21:31:08 -0300 Subject: [PATCH 2/5] =?UTF-8?q?Primeiras=20altera=C3=A7=C3=B5es=20para=20c?= =?UTF-8?q?p,=20mv,=20rm=20e=20arquivos=20grandes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exception/DiretorioNaoVazioException.java | 7 + filesys/Diretorio.java | 5 + filesys/FileSystemImpl.java | 305 +++++++++++++++++----- tests/FileSystemImplTest.java | 286 ++++++++++++++++---- 4 files changed, 478 insertions(+), 125 deletions(-) create mode 100644 exception/DiretorioNaoVazioException.java diff --git a/exception/DiretorioNaoVazioException.java b/exception/DiretorioNaoVazioException.java new file mode 100644 index 0000000..9a7fdd1 --- /dev/null +++ b/exception/DiretorioNaoVazioException.java @@ -0,0 +1,7 @@ +package exception; + +public class DiretorioNaoVazioException extends PermissaoException { + public DiretorioNaoVazioException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/filesys/Diretorio.java b/filesys/Diretorio.java index 3c9264d..f65174f 100644 --- a/filesys/Diretorio.java +++ b/filesys/Diretorio.java @@ -31,6 +31,11 @@ public Diretorio getPai() { return pai; } + // Adicionado para a funcionalidade 'mv' + public void setPai(Diretorio pai) { + this.pai = pai; + } + public void addSubDiretorio(Diretorio dir) { subDiretorio.put(dir.getMetaDados().getNome(), dir); } diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index bf3dab9..dab303e 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -2,11 +2,15 @@ import exception.CaminhoJaExistenteException; import exception.CaminhoNaoEncontradoException; +import exception.DiretorioNaoVazioException; import exception.PermissaoException; +import java.util.Arrays; + public final class FileSystemImpl implements IFileSystem { private static final String ROOT_USER = "root"; private Diretorio raiz; + private static final int TAMANHO_BLOCO = 1024; // 1KB por bloco public FileSystemImpl() { raiz = new Diretorio("/", ROOT_USER, null); @@ -14,7 +18,7 @@ public FileSystemImpl() { raiz.getMetaDados().setPermissao(ROOT_USER, "rwx"); } - // Utilitário: Navega até o diretório/arquivo alvo + // Utilitário: Navega até um diretório específico. private Diretorio navegarParaDiretorio(String caminho) throws CaminhoNaoEncontradoException { if (!caminho.startsWith("/")) throw new CaminhoNaoEncontradoException("Caminho inválido: " + caminho); @@ -27,35 +31,55 @@ private Diretorio navegarParaDiretorio(String caminho) throws CaminhoNaoEncontra if (partes[i].isEmpty()) continue; if (!atual.getSubDiretorio().containsKey(partes[i])) { - throw new CaminhoNaoEncontradoException("Diretório não encontrado: " + partes[i]); + throw new CaminhoNaoEncontradoException("Diretório não encontrado: " + partes[i] + " em " + caminho); } atual = atual.getSubDiretorio().get(partes[i]); } return atual; } - - // Retorna [diretorioPai, nomeFinal] + + // Retorna [objetoPai, nomeFinal]. O objeto pai é sempre um Diretorio. private Object[] navegarParaPai(String caminho) throws CaminhoNaoEncontradoException { if (!caminho.startsWith("/")) throw new CaminhoNaoEncontradoException("Caminho inválido: " + caminho); + if (caminho.equals("/")) { + return new Object[]{raiz, "/"}; + } int idx = caminho.lastIndexOf('/'); String pathPai = (idx == 0) ? "/" : caminho.substring(0, idx); String nomeFinal = caminho.substring(idx + 1); + if (nomeFinal.isEmpty()){ + throw new CaminhoNaoEncontradoException("Nome do arquivo/diretório não pode ser vazio."); + } Diretorio pai = navegarParaDiretorio(pathPai); return new Object[] { pai, nomeFinal }; } - private void checarPermissaoEscrita(Diretorio dir, String usuario) throws PermissaoException { - if (!dir.getMetaDados().hasPermissao(usuario, 'w')) { - throw new PermissaoException( - "Usuário sem permissão de escrita no diretório " + dir.getMetaDados().getNome()); + // Retorna o objeto (Arquivo ou Diretorio) no caminho especificado. + private Object encontrarObjeto(String caminho) throws CaminhoNaoEncontradoException { + Object[] res = navegarParaPai(caminho); + Diretorio pai = (Diretorio) res[0]; + String nome = (String) res[1]; + + if (pai.existeSubDiretorio(nome)) { + return pai.getSubDiretorio().get(nome); + } else if (pai.existeArquivo(nome)) { + return pai.getArquivos().get(nome); + } else { + throw new CaminhoNaoEncontradoException("Arquivo ou diretório não encontrado: " + caminho); } } - private void checarPermissaoLeitura(Diretorio dir, String usuario) throws PermissaoException { - if (!dir.getMetaDados().hasPermissao(usuario, 'r')) { - throw new PermissaoException( - "Usuário sem permissão de leitura no diretório " + dir.getMetaDados().getNome()); + + private void checarPermissaoEscrita(MetaDados meta, String usuario) throws PermissaoException { + if (!meta.hasPermissao(usuario, 'w')) { + throw new PermissaoException("Usuário " + usuario + " sem permissão de escrita em " + meta.getNome()); + } + } + + private void checarPermissaoLeitura(MetaDados meta, String usuario) throws PermissaoException { + if (!meta.hasPermissao(usuario, 'r')) { + throw new PermissaoException("Usuário " + usuario + " sem permissão de leitura em " + meta.getNome()); } } @@ -66,15 +90,15 @@ public void mkdir(String caminho, String usuario) throws CaminhoJaExistenteExcep Diretorio pai = (Diretorio) res[0]; String nomeNovo = (String) res[1]; - checarPermissaoEscrita(pai, usuario); + checarPermissaoEscrita(pai.getMetaDados(), usuario); if (pai.existeSubDiretorio(nomeNovo) || pai.existeArquivo(nomeNovo)) { - throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome."); + throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome: " + nomeNovo); } Diretorio novo = new Diretorio(nomeNovo, usuario, pai); pai.addSubDiretorio(novo); } catch (CaminhoNaoEncontradoException e) { - throw new CaminhoJaExistenteException("Diretório pai não encontrado."); + throw new CaminhoJaExistenteException("Diretório pai não encontrado para o caminho: " + caminho); } } @@ -85,92 +109,235 @@ public void touch(String caminho, String usuario) throws CaminhoJaExistenteExcep Diretorio pai = (Diretorio) res[0]; String nomeNovo = (String) res[1]; - checarPermissaoEscrita(pai, usuario); + checarPermissaoEscrita(pai.getMetaDados(), usuario); if (pai.existeArquivo(nomeNovo) || pai.existeSubDiretorio(nomeNovo)) { - throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome."); + throw new CaminhoJaExistenteException("Já existe arquivo ou diretório com esse nome: " + nomeNovo); } Arquivo novo = new Arquivo(nomeNovo, usuario); pai.addArquivo(novo); } catch (CaminhoNaoEncontradoException e) { - throw new CaminhoJaExistenteException("Diretório pai não encontrado."); + throw new CaminhoJaExistenteException("Diretório pai não encontrado para o caminho: " + caminho); } } - + @Override - public void ls(String caminho, String usuario, boolean recursivo) - throws CaminhoNaoEncontradoException, PermissaoException { - Diretorio dir = navegarParaDiretorio(caminho); - checarPermissaoLeitura(dir, usuario); - listarConteudo(dir, "", recursivo); - } - - private void listarConteudo(Diretorio dir, String prefixo, boolean recursivo) { - System.out.println(prefixo + dir.getMetaDados().getNome() + "/"); - for (Arquivo arq : dir.getArquivos().values()) { - System.out.println(prefixo + " " + arq.getMetaDados().getNome()); - } - if (recursivo) { - for (Diretorio sub : dir.getSubDiretorio().values()) { - listarConteudo(sub, prefixo + " ", true); - } - } else { - for (Diretorio sub : dir.getSubDiretorio().values()) { - System.out.println(prefixo + " " + sub.getMetaDados().getNome() + "/"); - } + public void rm(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + if (caminho.equals("/")) { + throw new PermissaoException("Não é permitido remover o diretório raiz."); } - } - - @Override - public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) - throws CaminhoNaoEncontradoException, PermissaoException { - // Pode ser arquivo ou diretório Object[] res = navegarParaPai(caminho); Diretorio pai = (Diretorio) res[0]; String nome = (String) res[1]; + checarPermissaoEscrita(pai.getMetaDados(), usuario); + if (pai.existeArquivo(nome)) { - Arquivo arq = pai.getArquivos().get(nome); - MetaDados md = arq.getMetaDados(); - if (!usuario.equals(ROOT_USER) && !md.hasPermissao(usuario, 'w')) { - throw new PermissaoException("Sem permissão para alterar permissões desse arquivo."); - } - md.setPermissao(usuarioAlvo, permissao); + pai.getArquivos().remove(nome); } else if (pai.existeSubDiretorio(nome)) { - Diretorio dir = pai.getSubDiretorio().get(nome); - MetaDados md = dir.getMetaDados(); - if (!usuario.equals(ROOT_USER) && !md.hasPermissao(usuario, 'w')) { - throw new PermissaoException("Sem permissão para alterar permissões desse diretório."); + Diretorio dirParaRemover = pai.getSubDiretorio().get(nome); + if (!dirParaRemover.getArquivos().isEmpty() || !dirParaRemover.getSubDiretorio().isEmpty()) { + if (!recursivo) { + throw new DiretorioNaoVazioException("O diretório não está vazio: " + caminho); + } + removerRecursivamente(dirParaRemover, usuario); } - md.setPermissao(usuarioAlvo, permissao); + pai.getSubDiretorio().remove(nome); } else { - throw new CaminhoNaoEncontradoException("Arquivo/diretório não encontrado para chmod."); + throw new CaminhoNaoEncontradoException("Arquivo ou diretório não encontrado: " + caminho); } } - // Métodos ainda não implementados: - @Override - public void rm(String caminho, String usuario, boolean recursivo) { - throw new UnsupportedOperationException("Método não implementado 'rm'"); + private void removerRecursivamente(Diretorio dir, String usuario) throws PermissaoException { + checarPermissaoEscrita(dir.getMetaDados(), usuario); + + // Copia as chaves para evitar ConcurrentModificationException + for (String nomeSubDir : dir.getSubDiretorio().keySet().toArray(new String[0])) { + removerRecursivamente(dir.getSubDiretorio().get(nomeSubDir), usuario); + dir.getSubDiretorio().remove(nomeSubDir); + } + dir.getArquivos().clear(); } + + @Override + public void write(String caminho, String usuario, boolean anexar, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { + Object obj = encontrarObjeto(caminho); + if (!(obj instanceof Arquivo)) { + throw new CaminhoNaoEncontradoException("O caminho especificado não é um arquivo: " + caminho); + } + Arquivo arq = (Arquivo) obj; + checarPermissaoEscrita(arq.getMetaDados(), usuario); + + if (!anexar) { + arq.getBlocos().clear(); + arq.getMetaDados().setTamanho(0); + } + + int offset = 0; + while(offset < buffer.length) { + Bloco bloco = new Bloco(TAMANHO_BLOCO); + int tamanhoCopia = Math.min(TAMANHO_BLOCO, buffer.length - offset); + byte[] dadosBloco = Arrays.copyOfRange(buffer, offset, offset + tamanhoCopia); + bloco.setDados(dadosBloco); + arq.getBlocos().add(bloco); + offset += tamanhoCopia; + } + arq.getMetaDados().setTamanho(arq.getMetaDados().getTamanho() + buffer.length); + } + @Override - public void write(String caminho, String usuario, boolean anexar, byte[] buffer) { - throw new UnsupportedOperationException("Método não implementado 'write'"); + public void read(String caminho, String usuario, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { + Object obj = encontrarObjeto(caminho); + if (!(obj instanceof Arquivo)) { + throw new CaminhoNaoEncontradoException("O caminho especificado não é um arquivo: " + caminho); + } + Arquivo arq = (Arquivo) obj; + checarPermissaoLeitura(arq.getMetaDados(), usuario); + + Arrays.fill(buffer, (byte)0); // Limpa o buffer antes da leitura + + int offset = 0; + for(Bloco bloco : arq.getBlocos()) { + byte[] dadosBloco = bloco.getDados(); + int tamanhoCopia = Math.min(dadosBloco.length, buffer.length - offset); + System.arraycopy(dadosBloco, 0, buffer, offset, tamanhoCopia); + offset += tamanhoCopia; + if (offset >= buffer.length) { + System.out.println("Aviso: Buffer de leitura preenchido. O arquivo pode ser maior que o buffer."); + break; + } + } } + + @Override + public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { + if (caminhoAntigo.equals("/") || caminhoNovo.equals("/")) { + throw new PermissaoException("Não é permitido mover ou renomear o diretório raiz."); + } + + Object[] resAntigo = navegarParaPai(caminhoAntigo); + Diretorio paiAntigo = (Diretorio) resAntigo[0]; + String nomeAntigo = (String) resAntigo[1]; + + Object[] resNovo = navegarParaPai(caminhoNovo); + Diretorio paiNovo = (Diretorio) resNovo[0]; + String nomeNovo = (String) resNovo[1]; + + checarPermissaoEscrita(paiAntigo.getMetaDados(), usuario); + if (paiAntigo != paiNovo) { + checarPermissaoEscrita(paiNovo.getMetaDados(), usuario); + } + + if (paiNovo.existeArquivo(nomeNovo) || paiNovo.existeSubDiretorio(nomeNovo)) { + throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoNovo); + } + Object objMovido = encontrarObjeto(caminhoAntigo); + if (objMovido instanceof Arquivo) { + Arquivo arq = (Arquivo) paiAntigo.getArquivos().remove(nomeAntigo); + arq.getMetaDados().setNome(nomeNovo); + paiNovo.addArquivo(arq); + } else if (objMovido instanceof Diretorio) { + Diretorio dir = (Diretorio) paiAntigo.getSubDiretorio().remove(nomeAntigo); + dir.getMetaDados().setNome(nomeNovo); + dir.setPai(paiNovo); // Atualiza a referência do pai + paiNovo.addSubDiretorio(dir); + } + } + @Override - public void read(String caminho, String usuario, byte[] buffer) { - throw new UnsupportedOperationException("Método não implementado 'read'"); + public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + Object objOrigem = encontrarObjeto(caminhoOrigem); + + Object[] resDestino = navegarParaPai(caminhoDestino); + Diretorio paiDestino = (Diretorio) resDestino[0]; + String nomeDestino = (String) resDestino[1]; + + checarPermissaoEscrita(paiDestino.getMetaDados(), usuario); + + if (paiDestino.existeArquivo(nomeDestino) || paiDestino.existeSubDiretorio(nomeDestino)) { + throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoDestino); + } + + if (objOrigem instanceof Arquivo) { + copiarArquivo((Arquivo) objOrigem, paiDestino, nomeDestino, usuario); + } else if (objOrigem instanceof Diretorio) { + if (!recursivo) { + throw new PermissaoException("É necessário usar a opção recursiva para copiar diretórios."); + } + copiarDiretorioRecursivamente((Diretorio) objOrigem, paiDestino, nomeDestino, usuario); + } + } + + private void copiarArquivo(Arquivo arqOrigem, Diretorio paiDestino, String nomeNovo, String usuario) throws PermissaoException { + checarPermissaoLeitura(arqOrigem.getMetaDados(), usuario); + + Arquivo arqNovo = new Arquivo(nomeNovo, usuario); + + // Copia os blocos + for(Bloco blocoOrigem : arqOrigem.getBlocos()) { + Bloco blocoNovo = new Bloco(TAMANHO_BLOCO); + byte[] dadosCopiados = Arrays.copyOf(blocoOrigem.getDados(), blocoOrigem.getDados().length); + blocoNovo.setDados(dadosCopiados); + arqNovo.getBlocos().add(blocoNovo); + } + + arqNovo.getMetaDados().setTamanho(arqOrigem.getMetaDados().getTamanho()); + paiDestino.addArquivo(arqNovo); + } + + private void copiarDiretorioRecursivamente(Diretorio dirOrigem, Diretorio paiDestino, String nomeNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { + checarPermissaoLeitura(dirOrigem.getMetaDados(), usuario); + + Diretorio dirNovo = new Diretorio(nomeNovo, usuario, paiDestino); + paiDestino.addSubDiretorio(dirNovo); + + // Copia arquivos + for (Arquivo arq : dirOrigem.getArquivos().values()) { + copiarArquivo(arq, dirNovo, arq.getMetaDados().getNome(), usuario); + } + // Copia subdiretórios + for (Diretorio subDir : dirOrigem.getSubDiretorio().values()) { + copiarDiretorioRecursivamente(subDir, dirNovo, subDir.getMetaDados().getNome(), usuario); + } } @Override - public void mv(String caminhoAntigo, String caminhoNovo, String usuario) { - throw new UnsupportedOperationException("Método não implementado 'mv'"); + public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + Diretorio dir = navegarParaDiretorio(caminho); + checarPermissaoLeitura(dir.getMetaDados(), usuario); + System.out.println("Listando " + caminho + ":"); + listarConteudo(dir, "", recursivo); + } + + private void listarConteudo(Diretorio dir, String prefixo, boolean recursivo) { + for (Diretorio sub : dir.getSubDiretorio().values()) { + System.out.println(prefixo + sub.getMetaDados().getNome() + "/"); + if (recursivo) { + listarConteudo(sub, prefixo + " ", true); + } + } + for (Arquivo arq : dir.getArquivos().values()) { + System.out.println(prefixo + arq.getMetaDados().getNome()); + } } @Override - public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) { - throw new UnsupportedOperationException("Método não implementado 'cp'"); + public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { + Object obj = encontrarObjeto(caminho); + MetaDados md; + + if (obj instanceof Arquivo) { + md = ((Arquivo) obj).getMetaDados(); + } else { + md = ((Diretorio) obj).getMetaDados(); + } + + // Apenas o dono ou o root podem alterar permissões + if (!usuario.equals(ROOT_USER) && !usuario.equals(md.getDono())) { + throw new PermissaoException("Apenas o dono do arquivo/diretório ou root podem alterar permissões."); + } + md.setPermissao(usuarioAlvo, permissao); } } \ No newline at end of file diff --git a/tests/FileSystemImplTest.java b/tests/FileSystemImplTest.java index 958ddb2..f31f5db 100644 --- a/tests/FileSystemImplTest.java +++ b/tests/FileSystemImplTest.java @@ -1,65 +1,239 @@ package tests; +import exception.*; import filesys.FileSystemImpl; -import exception.CaminhoJaExistenteException; -import exception.PermissaoException; +import filesys.IFileSystem; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class FileSystemImplTest { - private FileSystemImpl fs; - - @BeforeEach - public void setup() { - fs = new FileSystemImpl(); - } - - @Test - public void testMkdirTouchLs() throws Exception { - fs.mkdir("/home", "root"); - fs.mkdir("/home/mirelly", "root"); - fs.chmod("/home/mirelly", "root", "mirelly", "rwx"); - fs.touch("/home/mirelly/arq.txt", "mirelly"); - fs.ls("/home", "root", false); - fs.ls("/home", "root", true); - } - - @Test - public void testTouchDuplicado() throws Exception { - fs.mkdir("/d", "root"); - fs.chmod("/d", "root", "mirelly", "rwx"); - fs.touch("/d/a.txt", "mirelly"); - assertThrows(CaminhoJaExistenteException.class, () -> { - fs.touch("/d/a.txt", "mirelly"); - }); - } - - @Test - public void testPermissaoEscrita() throws Exception { - fs.mkdir("/priv", "root"); - fs.chmod("/priv", "root", "mirelly", "r--"); - assertThrows(PermissaoException.class, () -> { - fs.touch("/priv/novo.txt", "mirelly"); - }); - } - - @Test - public void testChmodPermissao() throws Exception { - fs.mkdir("/t", "root"); - fs.chmod("/t", "root", "mirelly", "rwx"); - fs.touch("/t/x.txt", "mirelly"); - fs.chmod("/t/x.txt", "root", "outro", "rw-"); - fs.chmod("/t/x.txt", "mirelly", "outro", "rwx"); - } - - @Test - public void testChmodSemPermissao() throws Exception { - fs.mkdir("/abc", "root"); - fs.chmod("/abc", "root", "mirelly", "rwx"); - fs.touch("/abc/y.txt", "mirelly"); - assertThrows(PermissaoException.class, () -> { - fs.chmod("/abc/y.txt", "outro", "mirelly", "rwx"); - }); - } + + private IFileSystem fs; + private final String rootUser = "root"; + private final String user = "mirelly"; + + @BeforeEach + public void setup() throws Exception { + fs = new FileSystemImpl(); + // Cria um ambiente base para os testes + fs.mkdir("/home", rootUser); + fs.mkdir("/home/" + user, rootUser); + fs.chmod("/home/" + user, rootUser, user, "rwx"); // Dá permissão total para o usuário em seu /home + } + + @Test + public void testMkdirTouchLs() throws Exception { + // Usa o /home/mirelly criado no setup + fs.touch("/home/" + user + "/arq.txt", user); + // O comando ls imprime no console, o teste aqui é para garantir que não lance exceção + assertDoesNotThrow(() -> fs.ls("/home", rootUser, false)); + assertDoesNotThrow(() -> fs.ls("/home", rootUser, true)); + } + + @Test + public void testTouchDuplicado() throws Exception { + fs.mkdir("/d", "root"); + fs.chmod("/d", "root", user, "rwx"); + fs.touch("/d/a.txt", user); + assertThrows(CaminhoJaExistenteException.class, () -> { + fs.touch("/d/a.txt", user); + }); + } + + @Test + public void testPermissaoEscrita() throws Exception { + fs.mkdir("/priv", "root"); + fs.chmod("/priv", "root", user, "r--"); // Apenas leitura + assertThrows(PermissaoException.class, () -> { + fs.touch("/priv/novo.txt", user); + }); + } + + @Test + public void testChmodPermissao() throws Exception { + fs.mkdir("/t", "root"); + fs.chmod("/t", "root", user, "rwx"); + fs.touch("/t/x.txt", user); + // Root e o dono (mirelly) podem alterar permissões + assertDoesNotThrow(() -> fs.chmod("/t/x.txt", rootUser, "outro", "rw-")); + assertDoesNotThrow(() -> fs.chmod("/t/x.txt", user, "outro", "rwx")); + } + + @Test + public void testChmodSemPermissao() throws Exception { + fs.mkdir("/abc", "root"); + fs.chmod("/abc", "root", user, "rwx"); + fs.touch("/abc/y.txt", user); + // Um terceiro usuário não pode alterar a permissão + assertThrows(PermissaoException.class, () -> { + fs.chmod("/abc/y.txt", "outro_usuario", user, "rwx"); + }); + } + + @Test + void testWriteAndReadFile() throws Exception { + String filePath = "/home/" + user + "/teste.txt"; + fs.touch(filePath, user); + + String content = "Este é um teste de escrita e leitura de arquivo."; + byte[] writeBuffer = content.getBytes(); + fs.write(filePath, user, false, writeBuffer); + + byte[] readBuffer = new byte[100]; + fs.read(filePath, user, readBuffer); + + String readContent = new String(readBuffer).trim(); + assertEquals(content, readContent); + } + + @Test + void testWriteLargeFile() throws Exception { + String filePath = "/home/" + user + "/grande.txt"; + fs.touch(filePath, user); + + // Cria um conteúdo com 3000 bytes, o que deve gerar 3 blocos (1024 * 2 + 952) + StringBuilder sb = new StringBuilder(3000); + for(int i = 0; i < 300; i++) { + sb.append("0123456789"); + } + byte[] largeBuffer = sb.toString().getBytes(); + + fs.write(filePath, user, false, largeBuffer); + + byte[] readBuffer = new byte[3000]; + fs.read(filePath, user, readBuffer); + + assertArrayEquals(largeBuffer, readBuffer); + } + + @Test + void testAppendToFile() throws Exception { + String filePath = "/home/" + user + "/append.txt"; + fs.touch(filePath, user); + + String part1 = "Primeira parte."; + fs.write(filePath, user, false, part1.getBytes()); + + String part2 = " Segunda parte."; + fs.write(filePath, user, true, part2.getBytes()); + + byte[] readBuffer = new byte[100]; + fs.read(filePath, user, readBuffer); + + assertEquals((part1 + part2), new String(readBuffer).trim()); + } + + @Test + void testRemoveFile() throws Exception { + String filePath = "/home/" + user + "/para_remover.txt"; + fs.touch(filePath, user); + fs.rm(filePath, user, false); + + assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(filePath, user, false)); + } + + @Test + void testRemoveNonEmptyDirFailsWithoutRecursive() throws Exception { + String dirPath = "/home/" + user + "/docs"; + fs.mkdir(dirPath, user); + fs.touch(dirPath + "/doc1.txt", user); + + assertThrows(DiretorioNaoVazioException.class, () -> fs.rm(dirPath, user, false)); + } + + @Test + void testRemoveDirRecursively() throws Exception { + String dirPath = "/home/" + user + "/docs_rec"; + fs.mkdir(dirPath, user); + fs.touch(dirPath + "/doc1.txt", user); + fs.mkdir(dirPath + "/subdir", user); + fs.touch(dirPath + "/subdir/doc2.txt", user); + + fs.rm(dirPath, user, true); + + assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(dirPath, user, true)); + } + + @Test + void testMoveFile() throws Exception { + String oldPath = "/home/" + user + "/original.txt"; + String newPath = "/home/novo.txt"; + fs.touch(oldPath, user); + + fs.mv(oldPath, newPath, user); + + assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(oldPath, user, false)); + assertDoesNotThrow(() -> fs.ls(newPath, rootUser, false)); + } + + @Test + void testRenameFile() throws Exception { + String oldPath = "/home/" + user + "/antigo.txt"; + String newPath = "/home/" + user + "/novo_nome.txt"; + fs.touch(oldPath, user); + + fs.mv(oldPath, newPath, user); + + assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(oldPath, user, false)); + assertDoesNotThrow(() -> fs.ls(newPath, user, false)); + } + + @Test + void testMoveDirectory() throws Exception { + String oldPath = "/home/" + user + "/pasta_movida"; + String newPath = "/home/pasta_movida"; + fs.mkdir(oldPath, user); + fs.touch(oldPath + "/file.txt", user); + + fs.mv(oldPath, newPath, user); + + assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(oldPath, user, false)); + assertDoesNotThrow(() -> fs.ls(newPath, rootUser, false)); + assertDoesNotThrow(() -> fs.ls(newPath + "/file.txt", rootUser, false)); + } + + @Test + void testCopyFile() throws Exception { + String sourcePath = "/home/" + user + "/fonte.txt"; + String destPath = "/home/copia.txt"; + fs.touch(sourcePath, user); + String content = "conteudo para copiar"; + fs.write(sourcePath, user, false, content.getBytes()); + + fs.cp(sourcePath, destPath, user, false); + + byte[] readBuffer = new byte[50]; + fs.read(destPath, rootUser, readBuffer); + assertEquals(content, new String(readBuffer).trim()); + + // Verifica que o original ainda existe + assertDoesNotThrow(() -> fs.ls(sourcePath, user, false)); + } + + @Test + void testCopyDirectoryRecursively() throws Exception { + String sourcePath = "/home/" + user + "/dir_fonte"; + String destPath = "/home/dir_copia"; + fs.mkdir(sourcePath, user); + fs.touch(sourcePath + "/file1.txt", user); + fs.mkdir(sourcePath + "/subdir", user); + fs.touch(sourcePath + "/subdir/file2.txt", user); + + fs.cp(sourcePath, destPath, user, true); + + assertDoesNotThrow(() -> fs.ls(destPath, rootUser, false)); + assertDoesNotThrow(() -> fs.ls(destPath + "/file1.txt", rootUser, false)); + assertDoesNotThrow(() -> fs.ls(destPath + "/subdir", rootUser, false)); + assertDoesNotThrow(() -> fs.ls(destPath + "/subdir/file2.txt", rootUser, false)); + } + + @Test + void testCopyDirectoryFailsWithoutRecursive() throws Exception { + String sourcePath = "/home/" + user + "/dir_fonte2"; + String destPath = "/home/dir_copia2"; + fs.mkdir(sourcePath, user); + + assertThrows(PermissaoException.class, () -> fs.cp(sourcePath, destPath, user, false)); + } } \ No newline at end of file From ecc31544910ca66fe9467167af4867d4d4dc986f Mon Sep 17 00:00:00 2001 From: Igor Reis Date: Fri, 20 Jun 2025 17:43:17 -0300 Subject: [PATCH 3/5] =?UTF-8?q?Teste=20para=20os=20m=C3=A9todos=20Read=20a?= =?UTF-8?q?nd=20Write?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/ReadWriteTest.java | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tests/ReadWriteTest.java diff --git a/tests/ReadWriteTest.java b/tests/ReadWriteTest.java new file mode 100644 index 0000000..29ef2ff --- /dev/null +++ b/tests/ReadWriteTest.java @@ -0,0 +1,78 @@ +package tests; + +import exception.CaminhoJaExistenteException; +import exception.CaminhoNaoEncontradoException; +import exception.PermissaoException; +import filesys.FileSystemImpl; +import filesys.IFileSystem; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class ReadWriteTest { + + private IFileSystem fs; + private final String usuario = "root"; + private final String caminhoArquivo = "/teste.txt"; + + @BeforeEach + public void setup() throws CaminhoJaExistenteException, PermissaoException { + fs = new FileSystemImpl(); + fs.touch(caminhoArquivo, usuario); + } + + @Test + public void testEscritaSimples() throws CaminhoNaoEncontradoException, PermissaoException { + byte[] dados = "Hello World".getBytes(); + fs.write(caminhoArquivo, usuario, false, dados); + + byte[] buffer = new byte[50]; + fs.read(caminhoArquivo, usuario, buffer); + + String resultado = new String(buffer).trim(); + assertTrue(resultado.startsWith("Hello World")); + } + + @Test + public void testEscritaComAppend() throws CaminhoNaoEncontradoException, PermissaoException { + fs.write(caminhoArquivo, usuario, false, "Parte1".getBytes()); + fs.write(caminhoArquivo, usuario, true, "Parte2".getBytes()); + + byte[] buffer = new byte[50]; + fs.read(caminhoArquivo, usuario, buffer); + + String resultado = new String(buffer).trim(); + assertTrue(resultado.startsWith("Parte1Parte2")); + } + + @Test + public void testLeituraComBufferPequeno() throws CaminhoNaoEncontradoException, PermissaoException { + String conteudo = "1234567890"; + fs.write(caminhoArquivo, usuario, false, conteudo.getBytes()); + + byte[] buffer = new byte[5]; + fs.read(caminhoArquivo, usuario, buffer); + + String resultado = new String(buffer).trim(); + assertEquals("12345", resultado); + } + + @Test + public void testLeituraArquivoInexistente() { + byte[] buffer = new byte[10]; + assertThrows(CaminhoNaoEncontradoException.class, () -> { + fs.read("/inexistente.txt", usuario, buffer); + }); + } + + @Test + public void testEscritaSemPermissao() throws CaminhoNaoExistenteException, PermissaoException { + String outroUsuario = "user1"; + fs.chmod(caminhoArquivo, usuario, outroUsuario, "---"); + + assertThrows(PermissaoException.class, () -> { + fs.write(caminhoArquivo, outroUsuario, false, "teste".getBytes()); + }); + } +} From b2cf3726fdbf9ba4897dd5b871b0ac3fc56770a4 Mon Sep 17 00:00:00 2001 From: Igor Reis Date: Fri, 20 Jun 2025 23:15:21 -0300 Subject: [PATCH 4/5] correcoes --- Main.java | 76 ++++++++++++++++++++----------------- filesys/FileSystemImpl.java | 75 +++++++++++++++++++++--------------- tests/ReadWriteTest.java | 2 +- 3 files changed, 88 insertions(+), 65 deletions(-) diff --git a/Main.java b/Main.java index 3b8673a..a6ae7d7 100644 --- a/Main.java +++ b/Main.java @@ -13,8 +13,8 @@ // SINTA-SE LIVRE PARA ALTERAR A CLASSE MAIN public class Main { - // Constantes úteis para a versão interativa. - // Para esse tipo de execução, o tamanho max do buffer de + // Constantes úteis para a versão interativa. + // Para esse tipo de execução, o tamanho max do buffer de // leitura pode ser menor. private static final String ROOT_USER = "root"; private static final String ROOT_DIR = "/"; @@ -29,27 +29,31 @@ public class Main { // Usuário que está executando o programa private static String user; - // 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. + // 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) { // Usuário que está executando o programa. - // Para quaisquer operações que serão feitas por esse usuário em um caminho /path/**, + // Para quaisquer operações que serão feitas por esse usuário em um caminho + // /path/**, // deve-se checar se o usuário tem permissão de escrita (r) neste caminho. if (args.length < 2) { System.out.println("Usuário não fornecido"); return; } user = args[1]; - + // Carrega a lista de usuários do sistema a partir de arquivo // Formato do arquivo users: - // username dir permission + // username dir permission // Exemplo: - // maria /** rw- - // luzia /** rwx + // maria /** rw- + // luzia /** rwx // Essa permissão vale para o diretório raiz e sub diretórios. - // A partir do momento que um usuário cria outro diretório ou arquivo, - // a permissão desse usuário é de leitura, escrita e execução nesse novo diretório/arquivo, + // A partir do momento que um usuário cria outro diretório ou arquivo, + // a permissão desse usuário é de leitura, escrita e execução nesse novo + // diretório/arquivo, // e sempre será rwx para o usuário root. try { Scanner userScanner = new Scanner(new java.io.File("users/users")); @@ -61,13 +65,15 @@ public static void main(String[] args) { String userListed = parts[0]; String dir = parts[1]; String dirPermission = parts[2]; - - /* A FAZER: - * Processar a permissão de todos os usuários existentes por diretório. - * Por enquanto esse código somente imprime as permissões contidas no arquivo users. - */ - System.out.println(userListed + " " + dir + " " + dirPermission); // Somente imprime o usuário, diretório e permissão + /* + * A FAZER: + * Processar a permissão de todos os usuários existentes por diretório. + * Por enquanto esse código somente imprime as permissões contidas no arquivo + * users. + */ + System.out.println(userListed + " " + dir + " " + dirPermission); // Somente imprime o usuário, + // diretório e permissão } else { System.out.println("Formato ruim no arquivo de usuários. Linha: " + line); @@ -80,18 +86,19 @@ public static void main(String[] args) { return; } - + // 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(/* usuários? */); - // // DESCOMENTE O BLOCO ABAIXO PARA CRIAR O DIRETÓRIO RAIZ ANTES DE RODAR O MENU + // // 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); + // fileSystem.mkdir(ROOT_DIR, ROOT_USER); // } catch (CaminhoJaExistenteException | PermissaoException e) { - // System.out.println(e.getMessage()); + // System.out.println(e.getMessage()); // } // Menu interativo. @@ -152,7 +159,7 @@ public static void menu() { return; default: System.out.println("Comando inválido!"); - } + } } catch (CaminhoNaoEncontradoException | CaminhoJaExistenteException | PermissaoException e) { System.out.println("Erro: " + e.getMessage()); } @@ -171,14 +178,14 @@ public static void chmod() throws CaminhoNaoEncontradoException, PermissaoExcept String usuarioAlvo = scanner.nextLine(); System.out.println("Insira a permissão (formato: 3 caracteres\"rwx\"):"); String permissoes = scanner.nextLine(); - + fileSystem.chmod(caminho, user, usuarioAlvo, permissoes); } public static void mkdir() throws CaminhoJaExistenteException, PermissaoException { System.out.println("Insira o caminho do diretório a ser criado:"); String caminho = scanner.nextLine(); - + fileSystem.mkdir(caminho, user); } @@ -187,14 +194,14 @@ public static void rm() throws CaminhoNaoEncontradoException, PermissaoException 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 { System.out.println("Insira o caminho do arquivo a ser criado:"); String caminho = scanner.nextLine(); - + fileSystem.touch(caminho, user); } @@ -206,16 +213,17 @@ public static void write() throws CaminhoNaoEncontradoException, PermissaoExcept System.out.println("Insira o conteúdo a ser escrito:"); String content = scanner.nextLine(); byte[] buffer = content.getBytes(); - + fileSystem.write(caminho, user, anexar, buffer); } 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. + 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. } public static void mv() throws CaminhoNaoEncontradoException, PermissaoException { @@ -223,7 +231,7 @@ public static void mv() throws CaminhoNaoEncontradoException, PermissaoException String caminhoAntigo = scanner.nextLine(); System.out.println("Insira o novo caminho do arquivo:"); String caminhoNovo = scanner.nextLine(); - + fileSystem.mv(caminhoAntigo, caminhoNovo, user); } @@ -232,7 +240,7 @@ public static void ls() throws CaminhoNaoEncontradoException, PermissaoException String caminho = scanner.nextLine(); System.out.println("Listar recursivamente? (true/false):"); boolean recursivo = Boolean.parseBoolean(scanner.nextLine()); - + fileSystem.ls(caminho, user, recursivo); } @@ -243,7 +251,7 @@ public static void cp() throws CaminhoNaoEncontradoException, PermissaoException String caminhoDestino = scanner.nextLine(); System.out.println("Copiar recursivamente? (true/false):"); boolean recursivo = Boolean.parseBoolean(scanner.nextLine()); - + fileSystem.cp(caminhoOrigem, caminhoDestino, user, recursivo); } } diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index dab303e..9ed98b8 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -37,18 +37,18 @@ private Diretorio navegarParaDiretorio(String caminho) throws CaminhoNaoEncontra } return atual; } - + // Retorna [objetoPai, nomeFinal]. O objeto pai é sempre um Diretorio. private Object[] navegarParaPai(String caminho) throws CaminhoNaoEncontradoException { if (!caminho.startsWith("/")) throw new CaminhoNaoEncontradoException("Caminho inválido: " + caminho); if (caminho.equals("/")) { - return new Object[]{raiz, "/"}; + return new Object[] { raiz, "/" }; } int idx = caminho.lastIndexOf('/'); String pathPai = (idx == 0) ? "/" : caminho.substring(0, idx); String nomeFinal = caminho.substring(idx + 1); - if (nomeFinal.isEmpty()){ + if (nomeFinal.isEmpty()) { throw new CaminhoNaoEncontradoException("Nome do arquivo/diretório não pode ser vazio."); } Diretorio pai = navegarParaDiretorio(pathPai); @@ -70,7 +70,6 @@ private Object encontrarObjeto(String caminho) throws CaminhoNaoEncontradoExcept } } - private void checarPermissaoEscrita(MetaDados meta, String usuario) throws PermissaoException { if (!meta.hasPermissao(usuario, 'w')) { throw new PermissaoException("Usuário " + usuario + " sem permissão de escrita em " + meta.getNome()); @@ -120,9 +119,10 @@ public void touch(String caminho, String usuario) throws CaminhoJaExistenteExcep throw new CaminhoJaExistenteException("Diretório pai não encontrado para o caminho: " + caminho); } } - + @Override - public void rm(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + public void rm(String caminho, String usuario, boolean recursivo) + throws CaminhoNaoEncontradoException, PermissaoException { if (caminho.equals("/")) { throw new PermissaoException("Não é permitido remover o diretório raiz."); } @@ -159,9 +159,9 @@ private void removerRecursivamente(Diretorio dir, String usuario) throws Permiss dir.getArquivos().clear(); } - @Override - public void write(String caminho, String usuario, boolean anexar, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { + public void write(String caminho, String usuario, boolean anexar, byte[] buffer) + throws CaminhoNaoEncontradoException, PermissaoException { Object obj = encontrarObjeto(caminho); if (!(obj instanceof Arquivo)) { throw new CaminhoNaoEncontradoException("O caminho especificado não é um arquivo: " + caminho); @@ -175,7 +175,7 @@ public void write(String caminho, String usuario, boolean anexar, byte[] buffer) } int offset = 0; - while(offset < buffer.length) { + while (offset < buffer.length) { Bloco bloco = new Bloco(TAMANHO_BLOCO); int tamanhoCopia = Math.min(TAMANHO_BLOCO, buffer.length - offset); byte[] dadosBloco = Arrays.copyOfRange(buffer, offset, offset + tamanhoCopia); @@ -185,9 +185,10 @@ public void write(String caminho, String usuario, boolean anexar, byte[] buffer) } arq.getMetaDados().setTamanho(arq.getMetaDados().getTamanho() + buffer.length); } - + @Override - public void read(String caminho, String usuario, byte[] buffer) throws CaminhoNaoEncontradoException, PermissaoException { + public void read(String caminho, String usuario, byte[] buffer) + throws CaminhoNaoEncontradoException, PermissaoException { Object obj = encontrarObjeto(caminho); if (!(obj instanceof Arquivo)) { throw new CaminhoNaoEncontradoException("O caminho especificado não é um arquivo: " + caminho); @@ -195,10 +196,10 @@ public void read(String caminho, String usuario, byte[] buffer) throws CaminhoNa Arquivo arq = (Arquivo) obj; checarPermissaoLeitura(arq.getMetaDados(), usuario); - Arrays.fill(buffer, (byte)0); // Limpa o buffer antes da leitura + Arrays.fill(buffer, (byte) 0); // Limpa o buffer antes da leitura int offset = 0; - for(Bloco bloco : arq.getBlocos()) { + for (Bloco bloco : arq.getBlocos()) { byte[] dadosBloco = bloco.getDados(); int tamanhoCopia = Math.min(dadosBloco.length, buffer.length - offset); System.arraycopy(dadosBloco, 0, buffer, offset, tamanhoCopia); @@ -209,13 +210,14 @@ public void read(String caminho, String usuario, byte[] buffer) throws CaminhoNa } } } - + @Override - public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { + public void mv(String caminhoAntigo, String caminhoNovo, String usuario) + throws CaminhoNaoEncontradoException, PermissaoException { if (caminhoAntigo.equals("/") || caminhoNovo.equals("/")) { throw new PermissaoException("Não é permitido mover ou renomear o diretório raiz."); } - + Object[] resAntigo = navegarParaPai(caminhoAntigo); Diretorio paiAntigo = (Diretorio) resAntigo[0]; String nomeAntigo = (String) resAntigo[1]; @@ -230,7 +232,11 @@ public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws } if (paiNovo.existeArquivo(nomeNovo) || paiNovo.existeSubDiretorio(nomeNovo)) { - throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoNovo); + try { + throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoNovo); + } catch (CaminhoJaExistenteException e) { + e.printStackTrace(); + } } Object objMovido = encontrarObjeto(caminhoAntigo); @@ -245,11 +251,12 @@ public void mv(String caminhoAntigo, String caminhoNovo, String usuario) throws paiNovo.addSubDiretorio(dir); } } - + @Override - public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + public void cp(String caminhoOrigem, String caminhoDestino, String usuario, boolean recursivo) + throws CaminhoNaoEncontradoException, PermissaoException { Object objOrigem = encontrarObjeto(caminhoOrigem); - + Object[] resDestino = navegarParaPai(caminhoDestino); Diretorio paiDestino = (Diretorio) resDestino[0]; String nomeDestino = (String) resDestino[1]; @@ -257,7 +264,11 @@ public void cp(String caminhoOrigem, String caminhoDestino, String usuario, bool checarPermissaoEscrita(paiDestino.getMetaDados(), usuario); if (paiDestino.existeArquivo(nomeDestino) || paiDestino.existeSubDiretorio(nomeDestino)) { - throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoDestino); + try { + throw new CaminhoJaExistenteException("Caminho de destino já existe: " + caminhoDestino); + } catch (CaminhoJaExistenteException e) { + e.printStackTrace(); + } } if (objOrigem instanceof Arquivo) { @@ -269,25 +280,27 @@ public void cp(String caminhoOrigem, String caminhoDestino, String usuario, bool copiarDiretorioRecursivamente((Diretorio) objOrigem, paiDestino, nomeDestino, usuario); } } - - private void copiarArquivo(Arquivo arqOrigem, Diretorio paiDestino, String nomeNovo, String usuario) throws PermissaoException { + + private void copiarArquivo(Arquivo arqOrigem, Diretorio paiDestino, String nomeNovo, String usuario) + throws PermissaoException { checarPermissaoLeitura(arqOrigem.getMetaDados(), usuario); - + Arquivo arqNovo = new Arquivo(nomeNovo, usuario); - + // Copia os blocos - for(Bloco blocoOrigem : arqOrigem.getBlocos()) { + for (Bloco blocoOrigem : arqOrigem.getBlocos()) { Bloco blocoNovo = new Bloco(TAMANHO_BLOCO); byte[] dadosCopiados = Arrays.copyOf(blocoOrigem.getDados(), blocoOrigem.getDados().length); blocoNovo.setDados(dadosCopiados); arqNovo.getBlocos().add(blocoNovo); } - + arqNovo.getMetaDados().setTamanho(arqOrigem.getMetaDados().getTamanho()); paiDestino.addArquivo(arqNovo); } - private void copiarDiretorioRecursivamente(Diretorio dirOrigem, Diretorio paiDestino, String nomeNovo, String usuario) throws CaminhoNaoEncontradoException, PermissaoException { + private void copiarDiretorioRecursivamente(Diretorio dirOrigem, Diretorio paiDestino, String nomeNovo, + String usuario) throws CaminhoNaoEncontradoException, PermissaoException { checarPermissaoLeitura(dirOrigem.getMetaDados(), usuario); Diretorio dirNovo = new Diretorio(nomeNovo, usuario, paiDestino); @@ -304,7 +317,8 @@ private void copiarDiretorioRecursivamente(Diretorio dirOrigem, Diretorio paiDes } @Override - public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { + public void ls(String caminho, String usuario, boolean recursivo) + throws CaminhoNaoEncontradoException, PermissaoException { Diretorio dir = navegarParaDiretorio(caminho); checarPermissaoLeitura(dir.getMetaDados(), usuario); System.out.println("Listando " + caminho + ":"); @@ -324,7 +338,8 @@ private void listarConteudo(Diretorio dir, String prefixo, boolean recursivo) { } @Override - public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) throws CaminhoNaoEncontradoException, PermissaoException { + public void chmod(String caminho, String usuario, String usuarioAlvo, String permissao) + throws CaminhoNaoEncontradoException, PermissaoException { Object obj = encontrarObjeto(caminho); MetaDados md; diff --git a/tests/ReadWriteTest.java b/tests/ReadWriteTest.java index 29ef2ff..85333de 100644 --- a/tests/ReadWriteTest.java +++ b/tests/ReadWriteTest.java @@ -67,7 +67,7 @@ public void testLeituraArquivoInexistente() { } @Test - public void testEscritaSemPermissao() throws CaminhoNaoExistenteException, PermissaoException { + public void testEscritaSemPermissao() throws CaminhoNaoEncontradoException, PermissaoException { String outroUsuario = "user1"; fs.chmod(caminhoArquivo, usuario, outroUsuario, "---"); From c5645f12f3079d2c25fe1fbdbd8b3b4410e3ece9 Mon Sep 17 00:00:00 2001 From: ALuiz19 Date: Fri, 20 Jun 2025 23:49:14 -0300 Subject: [PATCH 5/5] fix: test --- filesys/FileSystemImpl.java | 20 ++++++++++++++++---- tests/FileSystemImplTest.java | 17 ++++++++++++++--- users/users | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/filesys/FileSystemImpl.java b/filesys/FileSystemImpl.java index 9ed98b8..0e72db7 100644 --- a/filesys/FileSystemImpl.java +++ b/filesys/FileSystemImpl.java @@ -319,10 +319,22 @@ private void copiarDiretorioRecursivamente(Diretorio dirOrigem, Diretorio paiDes @Override public void ls(String caminho, String usuario, boolean recursivo) throws CaminhoNaoEncontradoException, PermissaoException { - Diretorio dir = navegarParaDiretorio(caminho); - checarPermissaoLeitura(dir.getMetaDados(), usuario); - System.out.println("Listando " + caminho + ":"); - listarConteudo(dir, "", recursivo); + try { + Diretorio dir = navegarParaDiretorio(caminho); + checarPermissaoLeitura(dir.getMetaDados(), usuario); + System.out.println("Listando " + caminho + ":"); + listarConteudo(dir, "", recursivo); + } catch (CaminhoNaoEncontradoException e) { + // Se não for diretório, tente como arquivo + Object obj = encontrarObjeto(caminho); + if (obj instanceof Arquivo) { + Arquivo arq = (Arquivo) obj; + checarPermissaoLeitura(arq.getMetaDados(), usuario); + System.out.println(arq.getMetaDados().getNome()); + } else { + throw e; + } + } } private void listarConteudo(Diretorio dir, String prefixo, boolean recursivo) { diff --git a/tests/FileSystemImplTest.java b/tests/FileSystemImplTest.java index f31f5db..2cca9dd 100644 --- a/tests/FileSystemImplTest.java +++ b/tests/FileSystemImplTest.java @@ -160,6 +160,9 @@ void testMoveFile() throws Exception { String oldPath = "/home/" + user + "/original.txt"; String newPath = "/home/novo.txt"; fs.touch(oldPath, user); + + // Concede permissão de escrita ao usuário "mirelly" em /home + fs.chmod("/home", rootUser, user, "rwx"); fs.mv(oldPath, newPath, user); @@ -173,6 +176,8 @@ void testRenameFile() throws Exception { String newPath = "/home/" + user + "/novo_nome.txt"; fs.touch(oldPath, user); + // Concede permissão de escrita ao usuário "mirelly" em /home + fs.chmod("/home", rootUser, user, "rwx"); fs.mv(oldPath, newPath, user); assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(oldPath, user, false)); @@ -185,7 +190,9 @@ void testMoveDirectory() throws Exception { String newPath = "/home/pasta_movida"; fs.mkdir(oldPath, user); fs.touch(oldPath + "/file.txt", user); - + + // Concede permissão de escrita ao usuário "mirelly" em /home + fs.chmod("/home", rootUser, user, "rwx"); fs.mv(oldPath, newPath, user); assertThrows(CaminhoNaoEncontradoException.class, () -> fs.ls(oldPath, user, false)); @@ -200,7 +207,9 @@ void testCopyFile() throws Exception { fs.touch(sourcePath, user); String content = "conteudo para copiar"; fs.write(sourcePath, user, false, content.getBytes()); - + + // Concede permissão de escrita ao usuário "mirelly" em /home + fs.chmod("/home", rootUser, user, "rwx"); fs.cp(sourcePath, destPath, user, false); byte[] readBuffer = new byte[50]; @@ -219,7 +228,9 @@ void testCopyDirectoryRecursively() throws Exception { fs.touch(sourcePath + "/file1.txt", user); fs.mkdir(sourcePath + "/subdir", user); fs.touch(sourcePath + "/subdir/file2.txt", user); - + + // Concede permissão de escrita ao usuário "mirelly" em /home + fs.chmod("/home", rootUser, user, "rwx"); fs.cp(sourcePath, destPath, user, true); assertDoesNotThrow(() -> fs.ls(destPath, rootUser, false)); diff --git a/users/users b/users/users index 58c2992..1c26d69 100644 --- a/users/users +++ b/users/users @@ -3,5 +3,5 @@ maria /** rw- joao /** rw- pedro /** rw- tiago /** rw- -luzia /** rwx +mirelly /** rwx carla /** r-- \ No newline at end of file