Esercizio 2

[L'esercizio deve essere risolto e consegnato entro il giorno 6/2/2004]

Scopo dell'esercizio è implementare una versione semplificata di File System costituita dalle tre classi: Shell, FileDescriptor e FileSystem. L'implementazione deve rispettare le seguenti specifiche:

  • Classe FileDescriptor - Un oggetto istanza di FileDescriptor contiene tutte le informazioni relative ad un singolo file. Queste sono: il nome e l'estensione del file e il suo contenuto (una stringa di caratteri). La classe FileDescriptor deve contenere i metodi:
    1. public FileDescriptor(String nome, String estensione, String contenuto): costruttore di un descrittore di file. I tre argomenti corrispondono alle informazioni conservate rispetto a un certo file e vanno salvate in variabili private;
    2. Insieme di metodi per ottenere i valori delle diverse componenti di un oggetto istanza di FileDescriptor. Saranno definiti secondo lo schema public A getP(), dove P deve essere sostituito da un termine che specifica di quale componente stiamo chiedendo il valore mentre A deve essere sostituita con il tipo del valore restituito. Per esempio, public String getNome() potrebbe essere il metodo per ottenere il nome di un file
    3. Insieme di metodi per assegnare valori alle diverse componenti di un oggetto istanza di FileDescriptor. Saranno definiti secondo lo schema public void setP(A val), dove P deve essere sostituito da un termine che indica la componente di interesse e A è il tipo di dato relativo al valore in questione.
    4. public void rename(String nuovoNome, String nuovaEst): metodo per modificare nome ed estensione di un oggetto FileDescriptor.
  • Classe FileSystem - La classe FileSystem implementa il FileSystem vero e proprio.
    In questo esercizio vengono fatte le seguenti semplificazioni:
    1. Il file system è supposto costituito di una sola directory, chiamata root, quindi al contrario che nel caso reale root non conterrà delle sottodirectory ma esclusivamente dei file e sarà l'unica istanza di FileSystem;
    2. La classe FileSystem deve implementare una directory come un array di FileDescriptor;
    3. La dimensione dell'array citato al punto precedente è passata come argomento al costruttore, public FileSystem(int dim), e risulta quindi fissata all'atto della creazione;
    4. Una variabile pos deve mantenere l'indice del primo elemento libero dell'array. In ogni istante tutte le componenti dell'array comprese fra la posizione 0 e la posizione pos - 1 conterranno un'istanza di FileDescriptor, tutte le altre conterranno null. Ad esempio, nel caso in cui pos = = 3:

      FD0FD1 FD2null null
      012 34
      pos
      N.B.: tutte le operazioni eseguite sugli oggetti FileSystem devono mantenere questa struttura. In parole povere: non devono essere lasciati buchi fra un FileDescriptor e l'altro. Inoltre non è permesso che in uno stesso FileSystem siano presenti due FileDescriptor diversi aventi stesso nome e stessa estensione.

    Oltre al costruttore citato, la classe FileSystem deve contenere i seguenti metodi:
    1. public void dir(): metodo che stampa a video l'elenco dei file contenuti nel FileSystem a cui è applicato. Di ogni file vengono visualizzate tutte le informazioni (nome, estensione e contenuto).
    2. public int search(String nome, String estensione): metodo che cerca nel FileSystem il FileDescriptor del file, il cui nome e la cui estensione sono passati come argomenti. Se trova tale elemento, restituisce l'indice dell'array ad esso corrispondente; se non lo trova restituisce il valore convenzionale -1.
    3. public boolean create(String nome, String estensione, String contenuto): metodo che inserisce un nuovo elemento di classe FileDescriptor nel FileSystem. Gli argomenti contengono le informazioni relative al file in questione (il suo nome, la sua estensione il suo contenuto). Il metodo restituisce true in caso di successo e false in caso di fallimento (se il file system è pieno oppure se esiste già un file avente quel nome e quell'estensione);
    4. public boolean delete(String nome, String estensione): metodo che cerca nel FileSystem il FileDescriptor del file, il cui nome e la cui estensione sono passati come argomenti. Se trova tale elemento, lo rimuove dal file system e compatta quest'ultimo per non lasciare buchi, restituendo il valore true; se non lo trova restituisce il valore false;
    5. public boolean rename(String n, String e, String nuovoN, String nuovaE): rinomina il file con nome n ed estensione e al nuovo nome nuovoN e nuova estensione nuovaE. Attenzione: per poter effettuare la rinomina, il metodo deve verificare che il file da rinominare sia effettivamente presente nel file system e che non ci siano altri file aventi contemporaneamente nome uguale a nuovoN e estensione uguale a nuovaE.
  • Classe Shell - La classe Shell implementa l'interfaccia con l'utente. Deve contenere una variabile istanza di FileSystem sulla quale l'utente deve poter eseguire da linea di comando le operazioni di creazione, cancellazione, rinomina e ricerca viste sopra. Specifiche:

    Una shell esegue un ciclo potenzialmente infinito, costituito dai seguenti passi:

    1. Stampa a video un simbolo convenzionale di prompt (ad es. '>>'), per indicare all'utente che sei in attesa di un comando
    2. Leggi il comando inserito dall'utente con i suoi eventuali argomenti. Un comando è una stringa di caratteri.
    3. Se si tratta di uno dei comandi previsti mandalo in esecuzione, altrimenti visualizza un messaggio d'errore.

    Supponiamo per es. che l'utente voglia creare un nuovo file e che il comando di creazione sia crea; ecco una possibile interazione fra utente e sistema:

    Passo 1: l'utente inserisce il nome del comando, che viene analizzato dal sistema. Se il comando è riconosciuto, viene eseguito. Qualora richieda l'inserzione di alcuni parametri inizierà un'interazione specifica (vedi Passo 2)
    >> crea

    Passo 2: per creare un file occorre specificarne nome, estensione e contenuto. Il sistema richiede all'utente questi valori, che vengono immessi uno per volta, ad esempio ...
    nome del file: pippo
    estensione: doc
    contenuto: ex falso quodlibet

    Passo 3: il sistema esegue la creazione e poi visualizza il prompt e torna in attesa di comandi:
    >>

    La Shell deve prevedere due comandi speciali: help e quit. Il primo stampa l'elenco dei comandi che la shell conosce, il secondo causa la terminazione dell'esecuzione del ciclo di Shell.