Implementando navegador Web através de arquivos de entrada e saída

Galera, eu tô com a missão de implementar algo parecido com um navegador da Web que terá 4 comandos básicos: visitar,voltar,seguir e sair… esses comandos que estão no meu arquivo de entrada implicam em que página da Web eu vou estar… eu fiz só que tá dando erro no VOLTAR e no SEGUIR, segue a classe arquivo e as classes que fiz… eu tentei por pilha, por array, por ponteiros e nada…=( Se alguém puder ajudar agradeço!

[/code]
public class L1Q2 {

/*voltar: colocar a página atual na estrutura 2 e retirar da estrutura 1 a página visitada mais recentemente fazendo desta a nova página atual. Se a estrutura 1 estiver vazia apenas deve ser impresso “ignorado”, caso contrário a operação deve ser realizada normalmente imprimindo o link da nova página atual.
seguir: colocar a página atual na estrutura 1 e retirar da estrutura 2 a página primeiramente visitada fazendo desta a nova página atual. Se a estrutura 2 estiver vazia deve ser impresso “ignorado” caso contrário deve ser impresso o link da nova página atual.
visitar: colocar a página atual na estrutura 1, esvaziar estrutura 2 e colocar o link especificado como a página atual.
sair: sair do navegador web.
*/

public static void main(String[] args) {
Arquivo arquivo = new Arquivo(“L1Q2.in”,“L1Q2.out”);
PaginasAnteriores paginasAnteriores = new PaginasAnteriores();
PaginasPosteriores paginasPosteriores = new PaginasPosteriores();
PaginaAtual paginaAtual = new PaginaAtual();
String nomeDaPagina = “http://www”;
PaginaDaWeb pagina = new PaginaDaWeb(nomeDaPagina);
PaginaAtual.addInicio(nomeDaPagina);
int N = 1;
int A = 0;
int B = 0;
int C = 0;
PaginaDaWeb [] arrayPagina = new PaginaDaWeb[1000000];
arrayPagina[0] = pagina;
arquivo.println(“Conjunto #”+ N);
while(!arquivo.isEndOfFile()){
String comando = arquivo.readString();
if (comando.equals(“visitar”)){
A++;
PaginaAtual.Remover(pagina);
nomeDaPagina = arquivo.readString();
pagina = new PaginaDaWeb(nomeDaPagina);
Array.inserir(pagina);
PaginasAnteriores.addInicio(nomeDaPagina);
PaginasPosteriores.RemoverTudo(pagina);
PaginaAtual.addInicio(nomeDaPagina);
arquivo.println(nomeDaPagina);
}else if (comando.equals(“voltar”)){ // VOLTAR ERRADO!
if (PaginasAnteriores.isVazia()){
arquivo.println(“ignorado”);
}else{
A++;
B++;
PaginaAtual.Remover(pagina);
PaginasPosteriores.addInicio(nomeDaPagina);
PaginasAnteriores.Remover(pagina);
pagina = arrayPagina[A-B];
PaginaAtual.addInicio(nomeDaPagina);
arquivo.println(nomeDaPagina);
}
}else if (comando.equals(“seguir”)){ // SEGUIR ERRADO!
if (PaginasPosteriores.isVazia()){
arquivo.println(“ignorado”);
}else{
A++;
B++;
C++;
PaginaAtual.Remover(pagina);
PaginasAnteriores.addInicio(nomeDaPagina);
PaginasPosteriores.RemoverTudo(pagina);
pagina = arrayPagina[A-B+C];
PaginaAtual.addInicio(nomeDaPagina);
arquivo.println(nomeDaPagina);
}
}else if (comando.equals(“sair”)){
PaginaAtual.Remover(pagina);
PaginasAnteriores.RemoverTudo(pagina);
PaginasPosteriores.RemoverTudo(pagina);
arquivo.println("");
N++;
if (!arquivo.isEndOfFile())
arquivo.println(“Conjunto #”+N);
}
}
}
}

class PaginaDaWeb
{
String nomeDaPagina;
PaginaDaWeb pagina;
PaginaDaWeb proxima;

PaginaDaWeb (String nomeDaPagina){
this.nomeDaPagina = nomeDaPagina;
this.pagina = pagina;
proxima = null;
}
}

class PaginasAnteriores {
private static PaginaDaWeb primeira;
private static PaginaDaWeb ultima;
private static int numeroDePaginas;

PaginasAnteriores ()
{
primeira = null;
ultima = null;
numeroDePaginas = 0;
}

public static boolean isVazia() {
return (primeira == null && ultima == null);
}

public static void addInicio(String nomeDaPagina) {
numeroDePaginas++;
PaginaDaWeb novaPagina = new PaginaDaWeb(nomeDaPagina);
if (isVazia())
ultima = novaPagina;
else
novaPagina.proxima = primeira;
primeira = novaPagina;
}

public int getNumeroDePaginas() {
return numeroDePaginas;
}

/*

  • @param posicao
  • posição contada a partir do zero como primeiro elemento
    */

public static void Remover(PaginaDaWeb pagina)
{
PaginaDaWeb atual = primeira;
PaginaDaWeb anterior = null;

if (primeira.pagina == pagina) {
primeira = primeira.proxima;
numeroDePaginas–;
}
else {
while (atual !=null && !(atual.pagina ==pagina)) {
anterior = atual;
atual = atual.proxima;
}
if(atual != null) {
anterior.proxima = atual.proxima;
numeroDePaginas–;
}
if(atual == ultima) {
ultima = anterior;
}
}
}

public static void RemoverTudo (PaginaDaWeb pagina){
PaginasAnteriores.isVazia();
}

public PaginaDaWeb BuscarPaginaDaWeb (PaginaDaWeb pagina)
{
int i = 1;
PaginaDaWeb atual = primeira;

while (atual !=null) {
if(atual.pagina==pagina) {
return atual;
}
i = i +1;
atual = atual.proxima;
}
return null;
}
}

class PaginasPosteriores {
private static PaginaDaWeb primeira;
private static PaginaDaWeb ultima;
private static int numeroDePaginas;

PaginasPosteriores ()
{
primeira = null;
ultima = null;
numeroDePaginas = 0;
}

public static boolean isVazia() {
return (primeira == null && ultima == null);
}

public static void addInicio(String nomeDaPagina) {
numeroDePaginas++;
PaginaDaWeb novaPagina = new PaginaDaWeb(nomeDaPagina);
if (isVazia())
ultima = novaPagina;
else
novaPagina.proxima = primeira;
primeira = novaPagina;
}

public int getNumeroDePaginas() {
return numeroDePaginas;
}

/*

  • @param posicao
  • posição contada a partir do zero como primeiro elemento
    */

public void Remover(PaginaDaWeb pagina)
{
PaginaDaWeb atual = primeira;
PaginaDaWeb anterior = null;

if (primeira.pagina==pagina) {
primeira = primeira.proxima;
numeroDePaginas–;
}
else {
while (atual !=null && !(atual.pagina==pagina)) {
anterior = atual;
atual = atual.proxima;
}
if(atual != null) {
anterior.proxima = atual.proxima;
numeroDePaginas–;
}
if(atual == ultima) {
ultima = anterior;
}
}
}

public static void RemoverTudo (PaginaDaWeb pagina){
PaginasPosteriores.isVazia();
}

public PaginaDaWeb BuscarPaginaDaWeb (PaginaDaWeb pagina)
{
int i = 1;
PaginaDaWeb atual = primeira;

while (atual !=null) {
if(atual.pagina==pagina) {
return atual;
}
i = i +1;
atual = atual.proxima;
}
return null;
}
}

class PaginaAtual {
private static PaginaDaWeb primeira;
private static PaginaDaWeb ultima;
private static int numeroDePaginas;

PaginaAtual ()
{
primeira = null;
ultima = null;
numeroDePaginas = 0;
}

public static boolean isVazia() {
return (primeira == null && ultima == null);
}

public static void addInicio(String nomeDaPagina) {
numeroDePaginas++;
PaginaDaWeb novaPagina = new PaginaDaWeb(nomeDaPagina);
if (isVazia())
ultima = novaPagina;
else
novaPagina.proxima = primeira;
primeira = novaPagina;
}

public int getNumeroDePaginas() {
return numeroDePaginas;
}

/*

  • @param posicao
  • posição contada a partir do zero como primeiro elemento
    */

public static void Remover(PaginaDaWeb pagina)
{
PaginaDaWeb atual = primeira;
PaginaDaWeb anterior = null;

if (primeira.pagina == pagina) {
primeira = primeira.proxima;
numeroDePaginas–;
}
else {
while (atual !=null && !(atual.pagina ==pagina)) {
anterior = atual;
atual = atual.proxima;
}
if(atual != null) {
anterior.proxima = atual.proxima;
numeroDePaginas–;
}
if(atual == ultima) {
ultima = anterior;
}
}
}

public void RemoverTudo (PaginaDaWeb pagina){
PaginaAtual.isVazia();
}

public static PaginaDaWeb BuscarPaginaDaWeb (PaginaDaWeb pagina)
{
int i = 1;
PaginaDaWeb atual = primeira;

while (atual !=null) {
if(atual.pagina==pagina) {
return atual;
}
i = i +1;
atual = atual.proxima;
}
return null;
}
}
class Array {
private static PaginaDaWeb [] arrayPagina;
static int N;

Array() {
Array.arrayPagina = new PaginaDaWeb[N];
}
public static void inserir(PaginaDaWeb pagina) {
PaginaDaWeb arrayPagina = pagina;
N = N + 1;
}

// metodo adicional para dar acesso ao atributo da classe
public PaginaDaWeb[] getArrayPaginaDaWeb() {
return this.arrayPagina;
}
}

import java.io.*;

/**

  • Classe que manipula a entrada e saída de dados de um programa através de
  • arquivos.

  • Exemplo de Uso:

  • // Abre os arquivos de entrada e saída
  • Arquivo io = new Arquivo(“L1Q1.in”, “L1Q1.out”);

  • // Lê dados do arquivo de entrada
  • String s = io.readString();
  • char c = io.readChar();
  • int i = io.readInt();
  • double d = io.readDouble();

  • // Grava dados no arquivo de saída
  • io.print(“Algoritmos”);
  • io.print(35);
  • io.println(2.3);

  • // Fecha o arquivo após o uso
  • io.close();
  • @author Emannuel Macêdo (egm@cin.ufpe.br)

*/

public class Arquivo {

private BufferedReader in;
private PrintWriter out;
private String[] buffer;
private int nextChar;
private int nextTokenLin, nextTokenCol;
private int primLin, contLin;

/**

  • Construtor da classe Arquivo. Abre o arquivo de entrada no modo leitura,
  • e o arquivo de saída no modo gravação. Se o arquivo de saída já existir,
  • seu conteúdo é descartado.
  • @param in nome do arquivo de entrada de dados
  • @param out nome do arquivo de saída de dados

*/
public Arquivo(String in, String out) {
try {
// abre o arquivo de entrada no modo leitura
this.in = new BufferedReader(new FileReader(in));

// abre o arquivo de saída no modo gravação
this.out = new PrintWriter(new FileWriter(out), true);

this.initBuffer();

} catch (IOException e) {
throw new RuntimeException(e.toString());
}
}

/** Fecha o arquivo quando o garbage collector é chamado */
protected void finalize() {
this.close();
}

/** Fecha o arquivo, após o seu uso. */
public void close() {
try {
if (this.in != null) {
this.in.close();
this.in = null;
}

if (this.out != null) {
this.out.close();
this.out = null;
}
} catch (IOException e) {
throw new RuntimeException(e.toString());
}
}

/* -------------------------------------------- /
/
------------ FUNÇÕES DE LEITURA ------------ /
/
-------------------------------------------- */

/** Indica se foi encontrado o fim do arquivo. */
boolean isEndOfFile() {
return (this.nextTokenLin < 0);
}

/** Indica se foi encontrado o fim da linha. */
public boolean isEndOfLine() {
return (this.nextTokenLin != this.primLin);
}

/**

  • Lê uma linha do arquivo. Se parte da linha já foi lida, então o restante
  • é retornado, mesmo que seja uma linha em branco (String de tamanho zero).
  • @return a próxima linha lida do arquivo, ou null se o fim
  • do arquivo for encontrado

*/
String readLine() {
if (this.contLin <= 0)
return null;

String line = this.buffer[this.primLin];
if (this.nextChar > 0)
if (this.nextChar >= line.length())
line = “”;
else
line = line.substring(this.nextChar, line.length()-1);

this.buffer[this.primLin] = null;
this.nextChar = 0;
this.primLin++;
this.contLin–;

if (this.nextTokenLin >= 0 && this.nextTokenLin < this.primLin)
this.findNext();

return line;
}

/**

  • Lê o próximo caractere do arquivo, incluindo espaços (’ ') e quebras de
  • linha (’\n’). Se o fim do arquivo for alcançado, o caractere nulo (’\0’)
  • é retornado.
  • @return o caractere lido
    */
    @SuppressWarnings(“unused”)
    private char readChar() {
    if (this.contLin <= 0)
    return ‘\0’;

char newChar;
String line = this.buffer[this.primLin];
if (this.nextChar >= line.length()) {
newChar = ‘\n’;
this.readLine();
} else {
newChar = line.charAt(this.nextChar++);
if (newChar != ’ ’ && this.nextTokenLin >= 0)
this.findNext();
}

return newChar;
}

/**

  • Lê uma string do arquivo.
  • @return a string lida

*/
public String readString() {
String next = null;

try {
this.checkEOF();

String line = this.buffer[this.nextTokenLin];
for (int i = this.primLin; i < this.contLin; i++)
this.buffer[i] = null;
this.buffer[0] = line;
this.nextTokenLin = this.primLin = 0;
this.contLin = 1;

int i, size = line.length();
for (i = this.nextTokenCol; i < size; i++)
if (line.charAt(i) == ’ ')
break;

next = line.substring(this.nextTokenCol, i);
this.nextChar = i;
this.findNext();
} catch (IOException e) {
throw new RuntimeException(e.toString());
}

return next;
}

/**

  • Lê um inteiro do arquivo.
  • @return o número lido

*/
public int readInt() {
return Integer.valueOf(this.readString()).intValue();
}

/**

  • Lê um double do arquivo.
  • @return o número lido

*/
public double readDouble() {
return Double.valueOf(this.readString()).doubleValue();
}

/* -------------------------------------------- /
/
------ FUNÇÕES AUXILIARES DE LEITURA ------- /
/
-------------------------------------------- */

/** Prepara o buffer de entrada para ser usado */
private void initBuffer() throws IOException {
this.buffer = new String[5];
this.nextChar = 0;
this.nextTokenLin = 0;
this.primLin = this.contLin = 0;

String line = this.in.readLine();
if (line == null) {
this.nextTokenLin = -1;
} else {
this.buffer[0] = line;
this.contLin++;
this.findNext();
}
}

/** Verifica se o fim do arquivo foi encontrado */
private void checkEOF() throws EOFException {
if (this.isEndOfFile())
throw new EOFException();
}

/** Acrescenta uma linha lida do arquivo no buffer */
private int appendLine(String str) {
if (this.contLin == 0)
this.primLin = 0;

if (this.primLin + this.contLin >= this.buffer.length) {
String[] src = this.buffer;
if (this.contLin >= this.buffer.length)
this.buffer = new String[2 * this.buffer.length];

System.arraycopy(src, this.primLin, this.buffer, 0, this.contLin);
this.nextTokenLin -= this.primLin;
this.primLin = 0;
}

buffer[this.primLin + this.contLin] = str;
this.contLin++;
return (this.primLin + this.contLin - 1);
}

/** Encontra a posição do próximo token a ser lido */
private void findNext() {
try {
String line = this.buffer[this.primLin];
if (line != null) {
int size = line.length();
for (int i = this.nextChar; i < size; i++)
if (line.charAt(i) != ’ ') {
this.nextTokenCol = i;
return;
}
}

this.nextTokenLin = this.nextTokenCol = -1;
while ((line = this.in.readLine()) != null) {
int size = line.length();
for (int i = 0; i < size; i++)
if (line.charAt(i) != ’ ') {
this.nextTokenCol = i;
this.nextTokenLin = this.appendLine(line);
return;
}
this.appendLine(line);
}
} catch (IOException e) {
throw new RuntimeException(e.toString());
}
}

/* -------------------------------------------- /
/
------------ FUNÇÕES DE ESCRITA ------------ /
/
-------------------------------------------- */

/**

  • Escreve um caractere no arquivo.
  • @param c caractere que será escrito no arquivo

*/
public void print(char c) {
this.out.print(String.valueOf©);
}

/**

  • Escreve uma string no arquivo.
  • @param s string que será escrita no arquivo

*/
public void print(String s) {
this.out.print(s);
}

/**

  • Escreve um inteiro no arquivo.
  • @param i número que será escrito no arquivo

*/
public void print(int i) {
this.out.print(i);
}

/**

  • Escreve um double no arquivo.
  • @param d número que será escrito no arquivo
  • @exception IOException em caso de erro de I/O

*/
public void print(double d) {
this.out.print(d);
}

/**

  • Escreve um double no arquivo, com um número fixo de casas decimais. Uma
  • precisão menor ou igual a zero indica que apenas a parte inteira será
  • impressa (com arredondamento).
  • @param d número que será escrito no arquivo
  • @param dec número de casas decimais de precisao
  • @exception IOException em caso de erro de I/O

*/
public void print(double d, int dec) {
this.out.print(this.formatDouble(d, dec));
}

/**

  • Começa uma nova linha no arquivo.

*/
public void println() {
this.out.println();
}

/**

  • Escreve um caractere e começa uma nova linha no arquivo.
  • @param c caractere que será escrito no arquivo

*/
public void println(char c) {
this.out.println(String.valueOf©);
}

/**

  • Escreve uma string e começa uma nova linha no arquivo.
  • @param s string que será gravada no arquivo

*/
public void println(String s) {
this.out.println(s);
}

/**

  • Escreve um inteiro e começa uma nova linha no arquivo.
  • @param i número que será gravado no arquivo

*/
public void println(int i) {
this.out.println(i);
}

/**

  • Escreve um double e começa uma nova linha no arquivo.
  • @param d número que será gravado no arquivo
  • @exception IOException em caso de erro de I/O

*/
public void println(double d) {
this.out.println(d);
}

/**

  • Escreve um double no arquivo, com um número fixo de casas decimais e
  • começa uma nova linha no arquivo. Uma precisão menor ou igual a zero
  • indica que apenas a parte inteira será impressa (com arredondamento).
  • @param d número que será escrito no arquivo
  • @param dec número de casas decimais de precisao
  • @exception IOException em caso de erro de I/O

*/
public void println(double d, int dec) {
this.out.println(this.formatDouble(d, dec));
}

/**

  • Grava os dados do buffer no arquivo. Isto é feito automaticamente a cada
  • quebra de linha (println.
    */
    public void flush() {
    this.out.flush();
    }

/* -------------------------------------------- /
/
------ FUNÇÕES AUXILIARES DE ESCRITA ------- /
/
-------------------------------------------- */

private String formatDouble(double d, int dec) {
if (dec <= 0) {
return String.valueOf(Math.round(d));
}
StringBuffer res = new StringBuffer();
long aprox = (int) Math.round(d * Math.pow(10, dec));
if (d < 0) {
aprox = -aprox;
res.append(’-’);
}
String num = String.valueOf(aprox);
int n = num.length() - dec;
if (n <= 0) {
res.append(“0.”);
for (int i = 0; i < -n; i++)
res.append(‘0’);
res.append(num);
} else {
char[] array = num.toCharArray();
res.append(array, 0, n).append(’.’).append(array, n, dec);
}
return res.toString();
}

}