// Last edited on 2014-12-16 00:35:30 by stolfilocal package quack; import java.io.IOException; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; public interface Server { // Uma instância desta classe armazena o estado do servidor {Quack}. // Somente uma instância deve ser criada quando o servidor começa a rodar, // e deve ser inicializada com o método {inicialize} abaixo. // A instância persiste enquanto o servidor estiver rodando. // Essa instância contem, entre outras variáveis de estado do servidor, // a tabela de usuários (i.e., contas) existentes na rede {Quack} e a tabela // de sessões abertas no momento. No objeto {User} que representa um usuário // estão // pendurados os seus contatos e as mensagens postadas (ou re-postadas). // Usuários, contatos e mensagens são espelhados numa base de dados // persistente. // // SESSÕES E COOKIES // // Alguns dos métodos abaixo somente podem ser executados por // usuários cadastrados na rede {Quack} e atualmente logados. // Nesses casos, a sessão de login é identificada por um {cookie} // atribuído quando o usuário fez login, que deve estar presente // no parâmetro {request}. // // Outros métodos, como os que mostram o perfil e as mensagens públicas de // algum usuário, podem ser executados por qualquer pessoa, sem necessidade // de login. Nesses casos o {request} não precisa conter um cookie válido. // // Em todos os métodos, caso seja fornecido o {cookie} de uma sessão // válida, a página de resultado geralmente vai conter mais // informações e botões, referentes ao usuário {u} que é dono da // sessão. // // DATAHORAS // // Alguns eventos, como o envio ou re-envio de mensagens, são // rotulados com uma /datahora/ (data + hora). Externamente, uma // datahora é uma {String} no formato "%Y-%m-%d %H:%M:%S %Z" onde // "%Z" é o fuso horário, p.ex. "UTC". Internamente, uma datahora é um {long int}. // um número inteiro desde uma data padrão. Veja a interface {quack.Timestamp}. // // INTERVALOS DE MENSAGENS // // Alguns dos métodos a seguir (e em outras interfaces) permitem que o leitor // identifique opcionalmente um trecho de uma lista de mensagens, usuários ou contatos através // de três parâmetros: {start} (um inteiro), {dir} (que pode // ser {-1} ou {+1}), e {maxN} (um inteiro positivo). Esses parâmetros // podem vir no {request}. // // O trecho selecionado da lista consiste de {maxN} elementos, // começando com o elemento com índice {start} (se {dir == // +1}), ou terminando com esse elemento (se {dir == -1}). Se não // existirem todos os {maxN} elementos pedidos, retorna os que // houver. // // Se {dir} não for especificado no URL, os métodos a seguir supõe {dir=+1}. // Os índices válidos vão de 0 a {n-1} onde {n} é o comprimento da // lista completa. Se {start} estiver fora desse intervalo, ele // é ignorado e substituído por 0 (se {dir == +1}) ou {n-1} (se {dir // == -1}). // !!{ Corrigir convenção antiga com {startTime,endTime} }!! // // ---------------------------------------------------------------------- // INICIALIZAÇÃO public Server initialize(String dbLoginName, String dbName, String dbPassword, ServletContext context); // Inicializa uma instância recém-criada de {Server} e devolve a mesma inicializada. // Estabelece contato com o servidor do banco de dados persistente // {dbName} como usuário {loginName} com senha de acesso // {dbPassword}. Constrói as tabelas de usuários, contatos e // mensagens a partir dos dados armazenados no banco. Também // inicializa a tabela de sessões abertas, incialmente vazia. // // Se {dbName} for {null}, não carrega a base de dados, só incializa // todas as tabelas vazias. // ---------------------------------------------------------------------- // ESTADO DO SERVIDOR public long getNumUsers(); public long getNumContacts(); public long getNumMessages(); // Retornam os contadores totais dos principais elementos da rede {Quack}. public long getNumSessions(); // Retorna o número de sessões abertas no momento. public long currentTime(); // Retorna a datahora atual no formato interno. // ---------------------------------------------------------------------- // PROCESSAMENTO DE PEDIDOS HTTP // // Os métodos abaixo são ativados pelo servidor HTTP ao receber // certos comandos GET ou POST do browser do usuário. // // Cada método tem parâmetros {request}, {response}, e {context}. // O parâmetro {request} é basicamente uma tabelas de pares // {chave,valor}, extraídos do commando GET ou POST. // // O parâmetro {response} é um objeto onde cada método deve // escrever o resultado do GET ou POST, uma página HTML que // é passada ao servidor HTTP e devolvida por este ao usuário. // Em caso de erro, geralmente a página contém uma mensagem // explicativa. // // ??{ Descrever o parâmetro {context} e quando {IOException} é levantada. }?? // // public void processHomePageReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de vista da home page da // rede {Quack} // // Supõe que o URL é "http://{host}/Quack", opcionalmente com "/" no fim. // Este método pode ser chamado mesmo por leitores não logados. // // Nessa página haverá botões/campos para fazer login e cadastrar novo // usuário, listar as mensagens públicas ou o perfil de qualquer usuário, // busca de mensagens e usuários pelo conteúdo, etc. public void processListAllUsersReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido para listar todos os usuários da // rede {Quack}. // // Supõe que o URL é "http://{host}/Quack/ShowUsers", opcionalmente // sequido de "?" e parâmetros "start", "dir" e "maxN" // indicando o trecho desejado da lista. // // Coloca em {response} uma página HTML com o trecho especificado da // lista dos usuários, em ordem alfabética ??{ por enquanto }?? // // Este método pode ser chamado mesmo por leitores não logados. // Porém, se o {request} tiver um cookie identificando uma sessão // aberta de um usuário {u}, a lista pode mostrar mais informações // (como o estado do contato entre {u} e cada usuário), e ter mais // botões, por exemplo para enviar mensagens ou alterar o estado de // contatos. public void processRegistrationReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de cadastramento de novo // usuário no {Quack}. // // Supõe que o URL é "http://{host}/Quack/Registration", obrigatoriamente // sequido de "?" e parâmetros "loginName", "email", "fullName", // e "password". // // Cria um novo usuário com os dados do {request}. // Acrescenta-o ao cadastro {this.userTable} (e à base de dados // persistente). // // Por enquanto, o cadastramento não faz o login automático. Se o // cadastramento tiver sucesso, devolve uma página em {response} // que mostra o perfil público do usuário recém-criado. // // Este método pode ser chamado mesmo por leitores não logados. public void processLoginReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de login de um usuário // existente da rede {Quack}. // // Supõe que o URL é "http://{host}/Quack/Login", obrigatoriamente // sequido de "?" e parâmetros "loginName" e "password". // // Este método pode ser chamado mesmo por leitores não logados; // se o {request} tiver um cookie de uma sessão aberta, ela será // automaticamente fechada. !!{ Verificar se isso ocorre. }!! // // Se o login tiver sucesso, a sessão é criada e acrescentada à // tabela de sessões abertas. O resultado, devolvido em // {response}, é uma página mostrando o perfil do usuario. // Essa página enviará um cookie ao browser para associar // futuros acessos dessa instância do browser à sessão aberta. public void processLogoutReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de logout do usuário. // // Supõe que o URL é "http://{host}/Quack/Logout". // // O {request} deve conter um cookie que identifica uma sessão aberta. // Essa sessão será fechada. // // Em caso de sucesso, o parâmetro {response} conterá a homepage do sistema {Quack}, // como vista por usuários não logados. public void processShowUserProfileReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido para mostrar o perfil de // um usuário da rede {Quack}. // // Supõe que o URL é "http://{host}/Quack/{loginName}", opcionalmente com "/" no fim; // ou http://{host}/Quack/ShowUserProfile", obrigatoriamente // sequido de "?" e parâmetro "loginName" que identifica o usuário {u} a exibir. // // Em caso de sucesso, o parâmetro {response} mostrará o perfil do usuario. // // Este método pode ser chamado mesmo por leitores não logados. Porém, se o {request} // tiver um cookie de uma sessão aberta, e o dono dessa sessão for o usuário {u}, // a página terá mais dados e botões. public void processSendMessageReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor Quack recebe um pedido para enviar // uma mensagem. // // Supõe que o URL é "http://{host}/Quack/SendMessage", // sequido obrigatoriamente de "?" e do parâmetro "messageText" que contem // o corpo da mensagem. // // O {request} deve conter também um campo {cookie} que deve // identificar uma sessão aberta. O dono {u} dessa sessão será // considerado o autor da mensagem. // // Em caso de sucesso, coloca no parâmetro {response} uma página mostrando a // a mensagem postada. public void processRepostMessageReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor Quack recebe um pedido para repostar // uma mensagem. // // Supõe que o URL é "http://{host}/Quack/SendMessage", // sequido obrigatoriamente de "?" e dos parâmetros "loginName" e "timestamp" que identificam // a mensagem a respostar. // // O {request} deve haver também um campo {cookie} que deve identificar uma // sessão aberta. O dono dessa sessão será considerado o re-postador da mensagem. // // Em caso de sucesso, coloca no parâmetro {response} uma página mostrando // a mesnagem repostada. public void processShowPostedMessagesReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido para listar um trecho das mensagens enviadas ou // reenviadas por um usuário da rede {Quack}. // // Supõe que o URL é "http://{host}/Quack/ShowPostedMessages", // sequido obrigatoriamente de "?" e do parâmetro "loginName", e // opcionalmente de parâmetros "start", "dir" e "maxN", // indicando o trecho desejado da lista. // // Em caso de sucesso, o resultado é uma página com o trecho especificado das mensagens enviadas ou // reenviadas pelo usuário {u} identificado pelo {loginName}. A página terá botões para acessar outros blocos de // mensagens. // // Este método pode ser chamado mesmo por leitores não logados. Porém, se o {request} // tiver um cookie de uma sessão aberta, as mensagens terão botões de reply e repost. // Se, além disso, o dono dessa sessão for o usuário {u}, as mensagens terão também // botões de delete. public void processShowReceivedMessagesReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido para listar as mensagens recebidas por // um usuário (a /timeline/ do usuário). // // Supõe que o URL é "http://{host}/Quack/ShowReceivedMessages", // sequido opcionalmente de "?" e dos parâmetros "start", "dir" e "maxN", // indicando o trecho desejado da lista. // // O {request} deve haver também um campo {cookie} que deve identificar uma // sessão aberta. As mensagens listadas serão todas as que tiverem sido enviadas // pelos usuários que {w} segue, mais todas as mensagens que mencionam {w} // enviadas por usuários que não são bloqueados por {w}. Essas mensagens // estarão em ordem cronologica inversa. // // ??{ No futuro haverá também mensagens privadas e replies... }?? // // Em caso de sucesso, o resultado é uma página com as mensagens em // questão. A página terá botões para acessar outras mensagens // vizinhas a essas. public void processModifyContactReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de alteracao de contato // entre dois usuarios do sistema {Quack}. // // Supõe que o URL é "http://{host}/Quack/ModifyContact", sequido // obrigatoriamente de "?" e dos parâmetros "loginName" que // especifica o usuário alvo {v}, e "status" cujo valor é o novo // estado do contato ("Follow","Block" ou "Inactive") do contato. // // O parâmetro {request} deve também conter um cookie que especifica // uma sessão aberta; o dono {u} da sessão é por definição a origem do contato. // // Em caso de sucesso, o parâmetro {response} conterá a pagina inicial do usuario alvo. // A alteração é gravada na base de dados persistente. public void processShowContactsReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor Quack recebe um pedido para mostrar // os contatos diretos (usuários seguidos, bloqueados, etc.) de um determinado usuario. // // Supõe que o URL é "http://{host}/Quack/ShowContacts", sequido // opcionalmente de "?" e dos parâmetros "start", "dir" e "maxN", // indicando o trecho desejado da lista. // // Em {request} deve haver um {cookie} que deve identificar uma // sessão aberta. Serão mostrados os contatos cuja origem // é o usuário {w} que é dono da lista. // // Em caso de sucesso, o parâmetro {response} conterá uma página com // os contatos especificados. A página terá botões para acessar outros trechos // da lista. public void processShowReverseContactsReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor Quack recebe um pedido para mostrar // os contatos inversos (usuários que seguem, bloqueiam, etc.) um usuário do sistema. // // Supõe que o URL é "http://{host}/Quack/ShowReverseContacts", sequido // opcionalmente de "?" e dos parâmetros "start", "dir" e "maxN", // indicando o trecho desejado da lista. // // Em {request} deve haver um {cookie} que deve identificar uma // sessão aberta. Serão mostrados os contatos cujo alvo // é o usuário {w} que é dono da lista. // // Em caso de sucesso, o parâmetro {response} conterá uma página // os contatos especificados. A página terá botões para acessar outros trechos // da lista. public void processModifyUserReq ( HttpServletRequest request, HttpServletResponse response, ServletContext context ) throws IOException, ServletException; // Chamado quando o servidor HTTP recebe um pedido de alteracao de dados de um // usuario do sistema {Quack}. // // O parâmetro {request} deve especificar uma sessão aberta; o dono {u} da sessão // é o usuario a ser mudado. O {request} deve conter também // um campo {fullName} cujo valor é o novo fullName do usuário {u}, // um campo {newPassword} cujo valor é a nova senha do usuario {u}, e um campo // {oldPassword} com a senha atual do usuário {u}. // // Em caso de sucesso, o parâmetro {response} conterá a pagina de perfil do usuario. // A alteração é gravada na base de dados persistente. }