Difference between revisions of "Programação com Objectos/Projecto de Programação com Objectos/Enunciado do Projecto de 2018-2019 (rascunho random)"

From Wiki**3

< Programação com Objectos‎ | Projecto de Programação com Objectos
(Inquéritos)
 
(254 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
<!--'''<font color="red">ÉPOCA NORMAL</font>'''-->
 
<!--'''<font color="red">ÉPOCA NORMAL</font>'''-->
  
O objectivo do projecto é criar uma aplicação que gere os itinerários de passageiros que usam comboios.
+
O objectivo do projecto é criar uma aplicação que gere parte da actividade dos cursos de uma universidade. Em particular, a aplicação faz a gestão de inquéritos aos projectos realizados pelos alunos nas várias disciplinas do curso.
  
Os itinerários são constituídos por um ou mais segmentos, realizados por comboios que cumprem serviços pré-definidos.
+
Neste texto, o tipo '''negrito''' indica um literal (i.e., é exactamente como apresentado); o símbolo <amsmath>\verb*| |</amsmath> indica um espaço; e o tipo ''itálico'' indica uma parte variável (i.e., uma descrição).
 +
 
 +
= Conceitos e Relações do Modelo =
 +
 
 +
Existem vários conceitos importantes neste contexto: universidade, curso, aluno, professor, funcionário, projecto, inquérito.
 +
 
 +
Os conceitos listados não são os únicos possíveis no modelo e as suas relações (assim como relações com outros conceitos não mencionados) podem depender das escolhas do projecto.
 +
 
 +
== Universidade, Cursos, Disciplinas ==
 +
 
 +
Uma universidade tem um nome e pode ter vários cursos, tendo ainda funcionários, docentes e alunos. Os alunos estão exclusivamente associados a um curso. Os funcionários e os docentes podem estar associados a vários cursos.
 +
 
 +
Cada curso tem um nome (único no contexto da universidade) e é constituído por várias disciplinas. Cada curso tem ainda um conjunto de alunos que podem inscreverem-se nas várias disciplinas do curso. Cada aluno pode inscrever-se, no máximo, em 6 disciplinas.
 +
 
 +
Cada disciplina tem um nome e apenas pertence a um curso. O nome da disciplina é o identificador único dentro do curso respectivo. Cada disciplina é leccionada por um ou mais docentes e tem 0 ou mais alunos inscritos. Os alunos inscritos numa disciplina têm que pertencer ao curso da disciplina. Existe uma capacidade máxima relativamente aos alunos que se podem inscrever numa disciplina. Um docente pode estar associado a várias disciplinas.
 +
 
 +
== Pessoas ==
 +
 
 +
Os utilizadores da aplicação correspondem aos vários tipos de pessoa que existem na universidade: alunos, docentes e funcionários. Alunos, docentes e funcionários têm nome (cadeia de caracteres), número de telefone (cadeia de caracteres) e um identificador único (inteiro com 6 dígitos). Este identificador é atribuído automaticamente (de forma incremental) e começa em 100000. Um aluno pode ainda ser delegado do curso em que o aluno está inscrito. O número máximo de delegados de um curso é 7. Em qualquer instante, um aluno pode tornar-se delegado ou deixar de ser delegado.
 +
 
 +
== Projectos ==
 +
 
 +
Os docentes podem criar projectos associados às disciplinas que leccionam. Cada projecto tem um nome e descrição. O nome deve ser único no contexto da disciplina. Quando o projecto é criado fica automaticamente aberto.
 +
 
 +
Um aluno pode submeter a sua versão do projecto desde que o projecto ainda esteja aberto e o aluno esteja inscrito na disciplina do projecto.
 +
Os alunos podem realizar várias submissões no mesmo projecto, sendo preservada apenas a última. Por razões de simplificação, a submissão é representada por uma cadeia de caracteres introduzida pelo aluno.
  
Neste texto, o tipo '''negrito''' indica um literal (i.e., é exactamente como apresentado); o símbolo <amsmath>\verb*| |</amsmath> indica um espaço; e o tipo ''itálico'' indica uma parte variável (i.e., uma descrição).
+
== Inquéritos ==
  
= Estrutura dos serviços, dos passageiros e dos itinerários =
+
A cada projecto não fechado pode ser associado, no máximo, um inquérito.
  
Existem três conceitos básicos: serviços, passageiros e itinerários.
+
O inquérito recolhe informação sobre o número de horas gastas na execução do projecto (número inteiro) e um comentário livre por parte do aluno que responde (cadeia de caracteres).
  
== Estrutura de um serviço ==
+
Um inquérito pode estar em várias situações: criado, aberto, fechado e finalizado. O comportamento do inquérito dependa desta situação. A mudança de situação é explícita, excepto quando o projecto associado é fechado: neste caso, o inquérito passa automaticamente de criado para aberto. Esta é a única mudança implícita: as outras mudanças são explícitas e da exclusiva responsabilidade de um delegado. O delegado tem de pertencer ao mesmo curso da disciplina no contexto do qual o inquérito é realizado.
  
Um serviço é um percurso realizado por um comboio ao longo de várias estações. A cada estação de um serviço está associado o momento de partida do comboio. Assume-se que todos os serviços se realizam em todos os dias. Além das informações anteriores, o serviço tem ainda um identificador numérico único (definido na criação do serviço).
+
É possível realizar várias operações sobre um inquérito: cancelar, abrir, fechar, finalizar, submeter resposta e obter resultados.  
  
{{CollapsedCode|Exemplo de serviço: Serviço 850: Valença >> Porto - Campanhã|
+
Cancelar um inquérito criado ou aberto (e sem respostas) corresponde a remover o inquérito. Se o inquérito estiver aberto, mas já tiver pelo menos uma resposta, então não pode ser removido e deve ser assinalado um erro. Cancelar um inquérito fechado corresponde a abri-lo novamente. Finalmente, cancelar um inquérito finalizado é impossível, pelo que deve ser assinalado um erro.
  Serviço #850 - 10.95
 
  07:36 Valença
 
  07:47 Vila Nova de Cerveira
 
  07:56 Caminha
 
  08:03 Âncora Praia
 
  08:16 Viana do Castelo
 
  08:20 Areia-Darque
 
  08:30 Barroselas
 
  08:37 Tamel
 
  08:53 Barcelos
 
  09:05 Nine
 
  09:13 Famalicão
 
  09:21 Trofa
 
  09:35 Ermesinde
 
  09:45 Porto - Campanhã
 
}}
 
  
Cada segmento de um serviço tem um custo base, que depende da distância entre estações. A distância entre estações corresponde ao tempo gasto na viagem entre essas estações. Assim, considerando que a totalidade do custo do serviço 850 (no exemplo acima) é de €10.95 (para 129 minutos), o custo do segmento Viana do Castelo >> Nine (para 49 minutos) é de 10.95 * 49 / 129.
+
Um inquérito criado é aberto quando o projecto que lhe está associado é fechado. Caso se tente abrir um inquérito que não obedeça a estas duas restrições deve ser assinalado um erro.  
  
O preço pago pelo passageiro depende ainda da sua categoria, que pode ser normal ou outra (a adição de novas categorias deve ter impacto reduzido no código da aplicação).
+
Um inquérito aberto pode ser fechado. Se estiver fechado, a operação de fecho não tem efeito. Em qualquer outra situação deve dar um erro.  
  
Considera-se que apenas existem as estações que aparecem em, pelo menos, um serviço.
+
Um inquérito fechado pode ser finalizado, impedindo futuras alterações. Finalizar um inquérito previamente finalizado não tem qualquer efeito. Finalizar inquéritos noutras situações corresponde a um erro.
  
== Estrutura de um passageiro ==
+
Só os alunos que entregaram o projecto (ou seja, realizaram pelo menos uma submissão) podem responder ao inquérito.  Cada aluno só pode responder uma vez. As respostas devem ser anónimas, ou seja, não deve guardada informação que permita saber qual a resposta de um dado aluno a um inquérito.
  
Um passageiro tem um identificador único e um nome (cadeia de caracteres). O identificador único é  atribuído automaticamente e de forma sequencial no momento do registo do passageiro, sendo atribuído o identificador 0 (zero) ao primeiro passageiro.
+
Os alunos podem submeter uma resposta a um inquérito aberto. Em qualquer outra situação, esta operação deve assinalar um erro. Alunos, docentes e delegados podem obter o resultado de um inquérito que esteja finalizado. Nas restantes situações, apenas se indica qual é o estado do inquérito.
  
Os passageiros são categorizados como normais, frequentes ou especiais. Um passageiro é considerado frequente enquanto o valor dos últimos 10 itinerários for superior a €250. Volta a ser normal se esta condição deixar de se verificar. Um cliente é considerado especial enquanto tiver gasto mais de €2500 nos últimos 10 itinerários. Deixa de ser especial se esta condição deixar de se verificar. Se se verificarem simultâneamente as condições para ser um cliente frequente e especial, o cliente é considerado especial. Aplicam-se as seguintes condições para atribuição de descontos em itinerários: passageiros normais, 0%; passageiros frequentes, 15%; passageiros especiais, 50%.
+
Note-se que tas operações indicadas anteriormente estão disponíveis apenas para pessoas que estejam associadas à disciplina à qual pertence o projecto com o inquérito em causa.
  
== Estrutura de um itinerário ==
+
== Notificações ==
  
Um itinerário corresponde a uma viagem realizada num dado dia, com base num conjunto de segmentos lógicos, correspondentes a partes de serviços, i.e., partidas (ou chegadas) agendadas para cada estação. <!-- Cada segmento tem uma estação e hora de partida e uma estação e hora de chegada.-->É possível saber, através do serviço associado, qual o percurso a realizar nesse segmento.  
+
Deve existir um mecanismo de mensagens que permita avisar determinados utilizadores quando os inquéritos associados a uma dada disciplina ficam em determinadas situações:
 +
* Quando um inquérito de um projecto de uma disciplina abre, quer-se enviar uma mensagem a todos os alunos, delegados e docentes da disciplina.
 +
* Quando um inquérito de um projecto de uma disciplina finaliza, quer-se enviar uma mensagem a todos os alunos, delegados e docentes da disciplina.
  
O custo base do itinerário é a soma dos custos parciais de cada serviço que o constitui, correspondentes aos segmentos realizados nesses serviços. Dependendo da categoria do passageiro, podem ser realizados descontos.
+
Nota: dado que um aluno pode também ser delegado, o mecanismo de envio de mensagens deve tratar este como se fosse uma única entidade. Assim, um aluno de uma disciplina que seja também delegado deve receber apenas uma mensagem e não duas cada vez que o sistema tem que enviar uma mensagem.
  
Os itinerários são identificados por um número de ordem (com início em 1) no contexto de cada passageiro. Não é possível remover itinerários já registados.
+
A apresentação das mensagens enviadas para um dado utilizador deve ser feita quando o utilizador faz login no sistema. Após o login ter sido realizado com sucesso devem ser apresentadas todas as mensagens que tenham sido  enviadas para o utilizador em causa desde a última vez que se registou no sistema.  Após esta visualização considera-se que o utilizador fica sem mensagens. As mensagens devem ser apresentadas pela mesma ordem em que enviadas pelo sistema.
  
{{CollapsedCode|Exemplo de itinerário: Évora >> Loulé|
+
= Requisitos de Desenho =
<text>
+
Itinerário 3 para 2017-10-18 @ 25.84
+
Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Assim:
Serviço #690 @ 6.37
+
* A determinação da descrição de um utilizador deve estar realizada de forma a evitar a duplicação de código comum, facilitando assim a introdução de novos tipos de utilizadores.
07:06 Évora
+
* A concretização da entidade inquérito deve ser feita por forma aumentar a legibilidade do código relacionado com esta entidade por forma a que caso se queira alterar a lógica de cada situação em que o inquérito possa estar, isso possa ser feito facilmente.
07:17 Casa Branca
+
* O mecanismo de envio das mensagens deve ser suficientemente flexível para suportar outras entidades que queiram também receber as mensagens. Deve ainda permitir que os destinatários das mensagens possam dizer se querem ou não ser notificados relativamente a cada disciplina. Por exemplo, um aluno de uma disciplina pode dizer que já não quer receber mensagens relativas a abrir e finalizar um inquérito associado à disciplina.
07:31 Vendas Novas
+
<!--
07:53 Pinhal Novo
+
Quer-se uma solução que permita a diferentes entidades poderem receber uma mensagem quando os resultados de um inquérito ficam disponíveis ou quando um novo aluno responde ao inquérito. No primeiro caso a mensagem deve indicar que o inquérito tem os resultados disponíveis enquanto que o segundo deve indicar que existe uma nova resposta registada no inquérito e o número total de respostas até ao momento.
Serviço #180 @ 19.47
+
-->
09:06 Pinhal Novo
 
10:54 Tunes
 
11:01 Albufeira - Ferreiras
 
11:13 Loulé
 
</text>
 
}}
 
  
 
= Funcionalidade da aplicação =
 
= Funcionalidade da aplicação =
  
A aplicação permite manter informação sobre serviços. Permite ainda registar e gerir passageiros e criar novos itinerários para eles. Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).
+
A aplicação permite manter informação sobre as entidades do modelo, permitindo, em particular, gerir projectos e inquéritos. Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).
  
A base de dados de serviços é [[#Leitura de Dados a Partir de Ficheiros Textuais|carregada no início da aplicação]]. Não é possível adicionar ou remover serviços durante a execução da aplicação.
+
A base de dados com os conceitos pré-definidos é [[#Leitura de Dados a Partir de Ficheiros Textuais|carregada no início da aplicação]]. Não é possível adicionar ou remover pessoas durante a execução da aplicação. Não é possível a um utilizador alterar a informação pessoal de outros utilizadores.
  
Todos os cálculos são realizados e os resultados armazenados sem arrendondamentos. Apenas na apresentação de resultados (e.g., preços) se apresentam valores com um número limitado de casas decimais (onde indicado).
+
A aplicação tem comportamento que depende do utilizador, pelo que deve permitir o estabelecimento de uma identidade inicial (''login''). Um utilizador que tenha estabelecido a sua identidade com sucesso é dito como estando registado. Em cada momento, a aplicação tem, no máximo, um utilizador registado.
  
 
{{Suggestion|Note-se que não é necessário implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da  funcionalidade do ''core'' da aplicação, tal como é visível pelos comandos da aplicação.}}
 
{{Suggestion|Note-se que não é necessário implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da  funcionalidade do ''core'' da aplicação, tal como é visível pelos comandos da aplicação.}}
{{CVSCode|A interface geral do ''core''  já está parcialmente implementada na classe '''mmt.TicketOffice''' e outras fornecdidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.}}
+
{{CVSCode|A interface geral do ''core''  já está parcialmente implementada na classe '''sth.SchoolManager''' e outras fornecidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.}}
 +
 
 +
== Gestão de informação sobre pessoas ==
  
== Consultas de Serviços ==
+
Um utilizador registado pode ver todos os utilizadores ou só um dado utilizador,  procurar um utilizador e actualizar o seu número de telefone.
  
É possível fazer várias consultas sobre serviços (ver também abaixo). É possível ver todos os serviços, inspeccionar um serviço particular e inspeccionar serviços com base na especificação de estações. Podem ser definidas, no futuro, outras formas de pesquisa e de apresentação de serviços.
+
== Gestão de actividades dos alunos ==
  
== Manipulação de Passageiros ==
+
Um utilizador registado que seja aluno pode realizar as seguintes tarefas: entregar um projecto, preencher um inquérito e ver resultados de um inquérito.
  
A aplicação permite realizar várias operações sobre passageiros. É possível obter a lista completa de passageiros conhecidos, assim como informação detalhada sobre passageiros individuais. É ainda possível registar novos passageiros e alterar o nome dos passageiros.
+
== Gestão de actividades dos delegados ==
  
== Manipulação de Itinerários ==
+
Um utilizador registado que seja delegado tem à sua disposição as seguinte funcionalidade: criar inquéritos, cancelar inquéritos, abrir inquéritos, fechar inquéritos, finalizar inquéritos e mostrar inquéritos de uma disciplina.
  
A aplicação permite obter informações sobre todos os itinerários já comprados ou, em pormenor, sobre os itinerários de passageiros específicos. Permite ainda criar novos itinerários.
+
== Gestão de actividades dos professores ==
  
Os passageiros são creditados com o valor monetário de cada itinerário comprado e com o tempo decorrido nesses itinerários (medido entre os pontos extremos). <!--O crédito destes valores depende da categoria do passageiro.-->
+
Um utilizador registado que seja um docente pode realizar as seguintes actividades: criar projectos, fechar projectos, ver as submissões de um projecto, ver os alunos de uma disciplina leccionada e ver resultados de inquéritos.
  
 
== Serialização ==
 
== Serialização ==
  
É possível reiniciar (ou seja, mantendo a informação sobre serviços, eliminar a informação sobre passageiros e itinerários), guardar e recuperar o estado actual da aplicação, preservando todos a informação sobre serviços, passageiros  e itinerários.
+
É possível guardar e recuperar o estado actual da aplicação, preservando toda a informação relacionada com a universidade e que foi descrita [[#Conceitos e Relações do Modelo|acima]].
  
 
= Interacção com o utilizador =
 
= Interacção com o utilizador =
Line 105: Line 112:
 
Descreve-se nesta secção a '''funcionalidade máxima''' da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de proceder à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção '''Sair''' (fecha o menu).
 
Descreve-se nesta secção a '''funcionalidade máxima''' da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de proceder à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção '''Sair''' (fecha o menu).
  
As operações de pedido e apresentação de informação ao utilizador '''devem''' realizar-se através dos objectos ''form'' e ''display'', respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das [[Programação com Objectos/Projecto de Programação com Objectos/Material de Apoio ao Desenvolvimento|bibliotecas de suporte]] ('''po-uuilib''' e '''mmt-app'''). As mensagens não podem ser usadas no núcleo da aplicação ('''mmt-core'''). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.
+
As operações de pedido e apresentação de informação ao utilizador '''devem''' realizar-se através dos objectos ''form'' e ''display'', respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das [[Programação com Objectos/Projecto de Programação com Objectos/Material de Apoio ao Desenvolvimento|bibliotecas de suporte]] ('''po-uuilib''' e '''sth-app'''). As mensagens não podem ser usadas no núcleo da aplicação ('''sth-core'''). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.
  
 
As excepções usadas na interacção, excepto se indicado, são subclasses de '''pt.tecnico.po.ui.DialogException''', são lançadas pelos comandos e tratadas por '''pt.tecnico.po.ui.Menu'''. Outras excepções não devem substituir as fornecidas nos casos descritos.
 
As excepções usadas na interacção, excepto se indicado, são subclasses de '''pt.tecnico.po.ui.DialogException''', são lançadas pelos comandos e tratadas por '''pt.tecnico.po.ui.Menu'''. Outras excepções não devem substituir as fornecidas nos casos descritos.
  
{{CVSCode|Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcialmente implementados nas ''packages'' '''mmt.app''', '''mmt.app.main''', '''mmt.app.service''', '''mmt.app.passenger''' e '''mmt.app.itinerary'''. Estas classes são de uso obrigatório e estão disponíveis no [[Programação com Objectos/Projecto de Programação com Objectos/Repositório CVS|CVS]] (módulo '''mmt-app''').}}
+
{{CVSCode|Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcialmente implementados nas ''packages'' '''sth.app''', '''sth.app.main''', '''sth.app.person''', '''sth.app.teaching''', '''sth.app.student'''  e '''sth.app.representative'''. Estas classes são de uso obrigatório e estão disponíveis no [[Programação com Objectos/Projecto de Programação com Objectos/Repositório CVS|CVS]] (módulo '''sth-app''').}}
  
 
== Menu Principal ==
 
== Menu Principal ==
  
As acções do menu permitem gerir a salvaguarda do estado da aplicação e abrir submenus. A lista completa é a seguinte: [[#Salvaguarda do estado actual da aplicação|Reiniciar]], [[#Salvaguarda do estado actual da aplicação|Abrir]], [[#Salvaguarda do estado actual da aplicação|Guardar]] e [[#Gestão e consulta de dados da aplicação|Consulta de Serviços]], [[#Gestão e consulta de dados da aplicação|Manipulação de Passageiros]] e [[#Gestão e consulta de dados da aplicação|Manipulação de Itinerários]]. Inicialmente, a aplicação apenas tem informação sobre os serviços que foram carregados no arranque.
+
As acções deste menu permitem gerir a salvaguarda do estado da aplicação e abrir submenus. A lista completa é a seguinte: [[#Salvaguarda do estado actual da aplicação|Reiniciar]], [[#Salvaguarda do estado actual da aplicação|Abrir]], [[#Salvaguarda do estado actual da aplicação|Guardar]] e [[#Gestão e consulta de dados da aplicação|Portal Pessoal]], [[#Gestão e consulta de dados da aplicação|Portal do Docente]], [[#Gestão e consulta de dados da aplicação|Portal do Estudante]] e [[#Gestão e consulta de dados da aplicação|Portal do Delegado]]. Inicialmente, a aplicação apenas tem informação sobre as pessoas, cursos e disciplinas que foram carregados no arranque. Note-se que nem todas as opções do menu estão disponíveis para todos os utilizadores (ver abaixo).
  
As etiquetas das opções deste menu estão definidas na classe '''mmt.app.main.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''mmt.app.main.Message'''.
+
As etiquetas das opções deste menu estão definidas na classe '''sth.app.main.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.main.Message'''.
  
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''mmt.app.main''' (disponível no CVS), respectivamente: '''DoReset''', '''DoOpen''', '''DoSave''', '''DoOpenServicesMenu''', '''DoOpenPassengersMenu''', '''DoOpenItinerariesMenu'''.}}
+
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''sth.app.main''' (disponível no CVS), respectivamente: <!--'''DoReset''', -->'''DoOpen''', '''DoSave''', '''DoOpenPersonelMenu''', '''DoOpenTeachingMenu''', '''DoOpenStudentMenu''', '''DoOpenRepresentativeMenu'''.}}
  
 
=== Salvaguarda do estado actual da aplicação ===
 
=== Salvaguarda do estado actual da aplicação ===
  
O conteúdo da aplicação (inclui todos os serviços, passageiros e itinerários actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: '''java.io.Serializable'''). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:
+
O conteúdo da aplicação (toda a informação detida pela universidade actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: '''java.io.Serializable'''). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:
  
* '''Reiniciar''' -- Reinicia a aplicação: destrói toda a informação sobre passageiros e itinerários; mantém toda a informação sobre serviços. Destrói ainda a associação a ficheiro de salvaguarda.
+
<!--* '''Reiniciar''' -- Reinicia a aplicação: destrói toda a informação da universidade. Destrói ainda a associação a ficheiro de salvaguarda.-->
* '''Abrir''' -- Carrega os dados de uma sessão anterior a partir de um ficheiro (ficando associado à aplicação). A informação a carregar compreende serviços, passageiros e itinerários. Pede-se o nome do ficheiro a abrir ('''openFile()'''). Caso o ficheiro não exista, é apresentada a mensagem '''fileNotFound()'''.
+
* '''Abrir''' -- Carrega os dados de uma sessão anterior a partir de um ficheiro previamente guardado (ficando este ficheiro associado à aplicação, para futuras operações de salvaguarda). Pede-se o nome do ficheiro a abrir ('''openFile()'''). Caso o ficheiro não exista, é apresentada a mensagem '''fileNotFound()'''. Esta operação não permite leitura de ficheiros de texto (estes apenas são utilizados na inicialização da aplicação). Esta opção substitui toda a informação da aplicação.
* '''Guardar''' -- Guarda o estado actual da aplicação (serviços, passageiros e itinerários) no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado. Esta interacção realiza-se através do método '''newSaveAs()'''. Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.
+
* '''Guardar''' -- Guarda o estado actual da aplicação no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado. Esta interacção realiza-se através do método '''newSaveAs()'''. Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.
 
 
As opções '''Reiniciar''' e '''Abrir''' substituem a informação na aplicação nas condições indicadas acima.
 
  
 +
<!--As opções '''Reiniciar''' e '''Abrir''' substituem a informação na aplicação nas condições indicadas acima.
 +
-->
 
A opção '''Sair''' nunca guarda o estado da aplicação, mesmo que existam alterações.
 
A opção '''Sair''' nunca guarda o estado da aplicação, mesmo que existam alterações.
  
 
=== Gestão e consulta de dados da aplicação ===
 
=== Gestão e consulta de dados da aplicação ===
  
* '''Consulta de Serviços''' -- Abre o menu de consulta de serviços (se existirem serviços registados).
+
* '''Portal Pessoal''' -- Abre o menu de consulta de informações sobre pessoas.
* '''Gestão de Passageiros''' -- Abre o menu de gestão de passageiros (se existirem passageiros registados).
+
* '''Portal do Docente''' -- Abre o menu de gestão de actividades dos professores (esta opção apenas está disponível para professores).
* '''Gestão de Itinerários''' -- Abre o menu de gestão de itinerários (se existirem itinerários registados).
+
* '''Portal do Estudante''' -- Abre o menu de gestão de actividades dos alunos (esta opção apenas está disponível para alunos).
 +
* '''Portal do Delegado''' -- Abre o menu de gestão de actividades dos delegados (esta opção apenas está disponível para delegados).
 +
 
 +
== Portal Pessoal ==
 +
 
 +
Este menu permite efectuar operações sobre a base de dados de pessoal da universidade, estando disponível para todos os utilizadores. A lista completa é a seguinte: [[#Mostrar pessoa|Mostrar pessoa]], [[#Alterar número de telefone|Alterar número de telefone]], [[#Mostrar pessoas|Mostrar pessoas]], [[#Procurar pessoa|Procurar pessoa]].
  
== Menu de Consulta de Serviços ==
+
As etiquetas das opções deste menu estão definidas na classe '''sth.app.person.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.person.Message'''.
  
Este menu permite efectuar consultas sobre a base de dados de serviços. A lista completa é a seguinte: [[#Mostrar todos os serviços|Mostrar todos os serviços]], [[#Mostrar serviço com um dado número|Mostrar serviço com um dado número]], [[#Mostrar serviços com origem numa estação dada|Mostrar serviços com origem numa estação dada]], [[#Mostrar serviços com término numa estação dada|Mostrar serviços com término numa estação dada]].
+
Sempre que for pedido o identificador de uma pessoa ('''requestPersonId()''') e a pessoa não existir, é lançada a excepção '''sth.app.NoSuchPersonException'''.
  
As etiquetas das opções deste menu estão definidas na classe '''mmt.app.service.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''mmt.app.service.Message'''.
+
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''sth.app.person''' (disponível no CVS), respectivamente: '''DoShowPerson''', '''DoChangePhoneNumber''', '''DoShowAllPersons''', '''DoSearchPerson'''.}}
  
Sempre que for pedido o identificador de um serviço ('''requestServiceId()''') e o serviço não existir, é lançada a excepção '''mmt.app.NoSuchServiceException'''.
+
=== Mostrar pessoa ===
Sempre que for pedido o nome de uma estção ('''requestStationName()''') e a estação não existir, é lançada a excepção '''mmt.app.NoSuchStationException'''.
+
 
 +
Apresenta as informações sobre a pessoa especificada pela identificação fornecida pelo processo de ''login'', de acordo com o seguinte formato (e variações descritas abaixo).
 +
{{CollapsedCode|Formato de apresentação (cabeçalho)|
 +
''TIPO''<nowiki>|</nowiki>''identificador''<nowiki>|</nowiki>''telefone''<nowiki>|</nowiki>''nome''
 +
}}
  
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''mmt.app.service''' (disponível no CVS), respectivamente: '''DoShowAllServices''', '''DoShowServiceByNumber''', '''DoShowServicesDepartingFromStation''', '''DoShowServicesArrivingAtStation'''.}}
+
Dependendo do tipo de pessoa, ''TIPO'' pode tomar os valores '''FUNCIONÁRIO''', '''DOCENTE''', '''ALUNO''' e '''DELEGADO''' (para alunos que são delegados). Se os utilizadores forem do tipo '''DOCENTE''', então à linha de identificação devem seguir-se as linhas com os nomes dos cursos e das disciplinas que lecciona nesses cursos, ordenados por ordem alfabética do nome do curso e da disciplina (dentro do curso). Se os utilizadores forem do tipo '''ALUNO''' ou '''DELEGADO''', então à linha de identificação devem seguir-se as linhas com os nomes das disciplinas em que está inscrito, ordenados por ordem alfabética do nome da disciplina.
 +
{{CollapsedCode|Exemplo de apresentação (professor)|
 +
DOCENTE<nowiki>|</nowiki>100050<nowiki>|</nowiki>987 654 321<nowiki>|</nowiki>Maria João
 +
* Informática - Análise e Síntese de Algoritmos
 +
* Matemática - Algebra
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (aluno)|
 +
ALUNO<nowiki>|</nowiki>101090<nowiki>|</nowiki>123 456 789<nowiki>|</nowiki>João Maria
 +
* Informática - Análise e Síntese de Algoritmos
 +
* Informática - Inteligência Artificial
 +
* Informática - Sistemas Operativos
 +
* Informática - Fundamentos da Programação
 +
* Informática - Programação com Objectos
 +
}}
  
=== Mostrar todos os serviços ===
+
=== Alterar número de telefone ===
  
Apresenta informações sobre todos os serviços conhecidos. A lista é ordenada pelo identificador do serviço e o formato é o descrito em [[#Mostrar serviço com um dado número|Mostrar serviço com um dado número]].
+
Pede o novo número de telefone ('''requestPhoneNumber()'''). De seguida, altera o número de telefone da pessoa registada e apresenta as informações da pessoa (tal como descrito em [[#Mostra pessoa|Mostrar pessoa]]).
  
=== Mostrar serviço com um dado número ===
+
=== Mostrar pessoas ===
  
Apresenta informações sobre um serviço. Depois de pedir o identificador do serviço ('''requestServiceId()'''), apresenta a informação sobre o serviço, tal como indicado no formato seguinte, para um serviço com N paragens (HH;MM representa o tempo em horas e minutos). O preço deve ser apresentado com duas casas decimais.
+
Apresenta informações sobre todas as pessoas conhecidas.
  
Serviço #<font color="brown">''número-do-serviço''</font> @ <font color="brown">''preço''</font>
+
A lista é ordenada pelo identificador da pessoa e o formato é o descrito em [[#Mostrar pessoa|Mostrar pessoa]].
<font color="brown">''HH:MM''</font> <font color="brown">''nome-de-estação-1''</font>
 
...
 
<font color="brown">''HH:MM''</font> <font color="brown">''nome-de-estação-N''</font>
 
  
{{CollapsedCode|Exemplo de apresentação de serviço: Serviço 180: Porto >> Faro|
+
=== Procurar pessoa ===
<text>
 
Serviço #180 @ 51.50
 
05:47 Porto - Campanhã
 
05:52 Vila Nova de Gaia-Devesas
 
06:21 Aveiro
 
06:46 Coimbra-B
 
08:23 Lisboa - Oriente
 
08:31 Lisboa - Entrecampos
 
09:06 Pinhal Novo
 
10:54 Tunes
 
11:01 Albufeira - Ferreiras
 
11:13 Loulé
 
11:23 Faro
 
</text>
 
}}
 
  
=== Mostrar serviços com origem numa estação dada ===
+
Pede o nome da pessoa a procurar (requestName()). A operação apresenta a lista de pessoas (ordenadas por ordem alfabética do nome) cujo nome satisfaz a procura (o nome da pessoa deve conter a cadeia de caracteres em questão).
 +
O formato de apresentação é o descrito em [[#Mostrar pessoa|Mostrar pessoa]].
 +
<!--
 +
== Portal do Funcionário Administrativo ==
  
Apresenta os números e estações terminais dos serviços com origem na estação indicada como resposta a '''requestStationName()''', ordenado por hora de partida do serviço.
+
Este menu apresenta as operações disponíveis para funcionários administrativos, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: [[#Criar disciplina|Criar criar disciplina]], [[#Remover disciplina|Remover disciplina]], [[#Registar docente|Registar docente]], [[#Remover docente|Remover docente]], [[#Associar docente a disciplina|Associar docente a disciplina]], [[#Remover docente de disciplina|Remover docente de disciplina]], [[#Registar aluno|Registar aluno]], [[#Remover aluno|Remover aluno]], [[#Inscrever aluno em disciplina|Inscrever aluno em disciplina]], [[#Remover aluno de disciplina|Remover aluno de disciplina]].
  
O formato de apresentação é o descrito em [[#Mostrar serviço com um dado número|Mostrar serviço com um dado número]].
+
As etiquetas das opções deste menu estão definidas na classe '''sth.app.admin.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.admin.Message'''.
  
=== Mostrar serviços com término numa estação dada ===
+
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''sth.app.admin''' (disponível no CVS), respectivamente: '''DoCreateCourse''', '''DoRemoveCourse''', '''DoRegisterTeacher''', '''DoRemoveTeacher''', '''DoAssignCourseTeacher''', '''DoRemoveCourseTeacher''', '''DoRegisterStudent''', '''DoRemoveStudent''', '''DoEnrollStudentInCourse''', '''DoRemoveStudentFromCourse'''.}}
  
Apresenta os números e estações de origem dos serviços com término na estação indicada como resposta a '''requestStationName()''', ordenado por hora de chegada do serviço.
+
=== Criar disciplina ===
  
O formato de apresentação é o descrito em [[#Mostrar serviço com um dado número|Mostrar serviço com um dado número]].
+
=== Remover disciplina ===
  
== Menu de Gestão de Passageiros ==
+
=== Registar docente ===
  
Este menu permite efectuar operações sobre um passageiro. A lista completa é a seguinte: [[#Mostrar passageiros|Mostrar passageiros]], [[#Mostrar passageiro|Mostrar passageiro]], [[#Registar passageiro|Registar passageiro]], [[#Alterar nome de passageiro|Alterar nome de passageiro]].
+
=== Remover docente ===
  
As etiquetas das opções deste menu estão definidas na classe '''mmt.app.passenger.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''mmt.app.passenger.Message'''.
+
=== Associar docente a disciplina ===
  
Sempre que for pedido o identificador de um passageiro ('''requestPassengerId()''') e o passageiro não existir, é lançada a excepção '''mmt.app.NoSuchPassengerException'''.
+
=== Remover docente de disciplina ===
  
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''mmt.app.passenger''' (disponível no CVS), respectivamente: '''DoShowAllPassengers''', '''DoShowPassengerById''', '''DoRegisterPassenger''', '''DoChangePassengerName'''.}}
+
=== Registar aluno ===
  
=== Mostrar passageiros ===
+
=== Remover aluno ===
  
Apresenta informações sobre todos os passageiros conhecidos. A lista é ordenada pelo identificador e o formato é o descrito em [[#Mostrar passageiro|Mostrar passageiro]].
+
=== Inscrever aluno em disciplina ===
  
=== Mostrar passageiro ===
+
=== Remover aluno de disciplina ===
 +
-->
  
Apresenta informações sobre um passageiro. Depois de pedir o identificador do passageiro ('''requestPassengerId()'''), apresenta o nome, a categoria do passageiro ('''NORMAL''', '''FREQUENTE''', '''ESPECIAL'''), o número de itinerários adquiridos, o tempo acumulado (formato HH:MM) correspondente aos itinerários adquiridos e o valor pago por esses itinerários (o valor pago deve ser apresentado com duas casas decimais).
+
== Portal do Docente ==
  
Formato:
+
Este menu apresenta as operações disponíveis para docentes, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: [[#Criar projecto|Criar projecto]], [[#Fechar projecto|Fechar projecto]], [[#Ver submissões de um projecto|Ver submissões de um projecto]], [[#Ver alunos de disciplina leccionada|Ver alunos de disciplina leccionada]], [[#Ver resultados de um inquérito|Ver resultados de um inquérito]].
''id'' | ''nome'' | ''categoria'' | ''número-de-itinerários'' | ''valor-pago'' | ''tempo-acumulado''
 
  
Exemplo:
+
As etiquetas das opções deste menu estão definidas na classe '''sth.app.teaching.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.teaching.Message'''.
1234|John Doe|NORMAL|123|9876.54|123:45
 
  
=== Registar passageiro ===
+
{{CVSCode|Estes comandos já estão implementados  nas classes da ''package'' '''sth.app.teaching''' (disponível no CVS), respectivamente: '''DoCreateProject''', '''DoCloseProject''', '''DoShowProjectSubmissions''', '''DoShowCourseStudents''', '''DoShowSurveyResults'''.}}
  
Permite registar um passageiro no sistema. É pedido o nome do passageiro ('''requestPassengerName()'''). O novo passageiro é categorizado como '''NORMAL'''.
+
=== Criar projecto ===
  
=== Alterar nome de passageiro ===
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''), e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e '''DuplicateProjectException''', se o projecto já existir. Em caso de identificação bem sucedida, o projecto é criado.
  
Permite alterar o nome do passageiro. Para tal, pede-se o identificador do passageiro cujo nome deve ser alterado ('''requestPassengerId()''') e o novo nome ('''requestPassengerName()''').
+
=== Fechar projecto ===
  
== Menu de Gestão de Itinerários ==
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''), e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e '''NoSuchProjectException''', se o projecto não existir. Em caso de identificação bem sucedida, o projecto é fechado.
  
Este menu permite efectuar operações sobre itinerários. A lista completa é a seguinte: [[#Mostrar todos os itinerários|Mostrar todos os itinerários]], [[#Mostrar itinerários associados a um passageiro|Mostrar itinerários associados a um passageiro]], [[#Registar itinerário para um passageiro|Registar itinerário para um passageiro]]<!--, [[#Mostrar histogramas por serviço|Mostrar histogramas por serviço]]-->.
+
Se o projecto já estiver fechado, o comando não executa nenhuma acção.
  
As etiquetas das opções deste menu estão definidas na classe '''mmt.app.itinerary.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''mmt.app.itinerary.Message'''.
+
=== Ver submissões de um projecto ===
  
{{CVSCode|Estes comandos já estão parcialmente implementados  nas classes da ''package'' '''mmt.app.itinerary''' (disponível no CVS), respectivamente: '''DoShowAllItineraries''', '''DoShowPassengerItineraries''', '''DoRegisterItinerary'''.}}
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''), e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e '''NoSuchProjectException''', se o projecto não existir. Em caso de identificação bem sucedida, as submissões do projecto são apresentadas, ordenadas pelo número de aluno que realizou a submissão, e com o seguinte formato.
  
=== Mostrar todos os itinerários ===
+
{{CollapsedCode|Formato de apresentação|
 +
''Nome da Disciplina - Nome do Projecto''
 +
* ''Identificador do 1º aluno - submissão do 1º aluno''
 +
...
 +
* ''Identificador do Nº aluno - submissão do Nº aluno''
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação|<text>
 +
Programação com Objectos - Gatos Simples
 +
* 0234 - Gato.java
 +
* 6789 - Cat.java
 +
* 7912 - Tigre.java
 +
</text>
 +
}}
 +
Este comando pode operar, tanto sobre projectos abertos, como sobre projectos fechados.
  
Apresenta todos os itinerários registados para todos os passageiros.  O formato de apresentação é como para os serviços, mas apenas se apresenta o segmento percorrido e o respectivo custo. A informação é apresentada para cada passageiro, sendo os passageiros apresentados por ordem crescente do seu número de identificação. <!-- e, para cada passageiro, pela estação de origem do itinerário.-->
+
=== Ver alunos de disciplina leccionada ===
  
O formato de apresentação é como definido para a [[#Mostrar itinerários associados a um passageiro|apresentação dos itinerários de um passageiro]], mas apresenta-se a informação relativamente a todos os passageiros.
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa. Em caso de identificação bem sucedida, é apresentada a lista de alunos, ordenada pelo identificador de aluno, no formato definido em [[#Mostrar pessoa|Mostrar pessoa]].
  
Note-se que a apresentação de itinerários apenas tem significado quando existem itinerários para mostrar, i.e., não se devem apresentar passageiros que não têm itinerários.
+
=== Ver resultados de um inquérito ===
  
=== Mostrar itinerários associados a um passageiro ===
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''), o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, '''NoSuchProjectException''', se o projecto não existir, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa. Em caso de identificação bem sucedida, os resultados do inquérito são apresentados de acordo com o formato seguinte, ordenados por ordem de resposta.
  
Apresenta os itinerários do passageiro cujo identificador é pedido através de '''requestPassengerId()'''. A lista é ordenada pela data dos itinerários.
+
{{CollapsedCode|Formato de apresentação para inquéritos criados (por abrir)|
 +
''Nome da disciplina'' - ''Nome do projecto'' (por abrir)
 +
}}
 +
{{CollapsedCode|Formato de apresentação para inquéritos abertos|
 +
''Nome da disciplina'' - ''Nome do projecto'' (aberto)
 +
}}
 +
{{CollapsedCode|Formato de apresentação para inquéritos fechados|
 +
''Nome da disciplina'' - ''Nome do projecto'' (fechado)
 +
}}
 +
{{CollapsedCode|Formato de apresentação para inquéritos finalizados|
 +
''Nome da disciplina - Nome do projecto''
 +
  * Número de submissões: ''Número de submissões''
 +
  * Número de respostas: ''Número de respostas''
 +
  * Tempos (mínimo, médio, máximo): ''Tempo mínimo de resolução do projecto'', ''Tempo médio de resolução do projecto'', ''Tempo máximo de resolução do projecto''
 +
}}
 +
{{CollapsedCode|Exemplos de apresentação (aberto)|<text>
 +
Programação com Objectos - Coisas Estranhas (aberto)
 +
</text>
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (fechado)|<text>
 +
Programação com Objectos - Gatos Sofisticados (fechado)
 +
</text>
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (finalizado)|<text>
 +
Programação com Objectos - Gatos Simples
 +
* Número de submissões: 30
 +
* Número de respostas: 20
 +
* Tempos de resolução (horas) (mínimo, médio, máximo): 10, 16, 20
 +
</text>
 +
}}
 +
<!--Se um inquérito tiver sido cancelado, a aplicação deve comportar-se como se ele não existisse, mesmo que continue na memória da aplicação.-->
  
Se o passageiro não tiver itinerários, deve ser apresentada a mensagem '''noItineraries()'''.
+
== Portal do Estudante ==
  
O formato de apresentação é análogo ao dos serviços, iniciado com uma linha com o identificador do passageiro, à qual se segue a lista de itinerários, cada um precedido da linha com o número de ordem do itinerário (no contexto de cada passageiro) e da data correspondente:
+
Este menu apresenta as operações disponíveis para alunos, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: [[#Entregar projecto|Entregar projecto]], [[#Preencher inquérito|Preencher inquérito]], [[#Ver resultados de inquérito|Ver resultados de inquérito]].
  
  <nowiki>==</nowiki> Passageiro <font color="brown">''identificador-do-passageiro''</font>: <font color="brown">''nome-do-passageiro''</font> <nowiki>==</nowiki>
+
As etiquetas das opções deste menu estão definidas na classe '''sth.app.student.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.student.Message'''.
  Itinerário <font color="brown">''número-de-ordem-do-itinerário''</font> para <font color="brown">''data''</font> @ <font color="brown">''preço-total-do-itinerário''</font>
 
  
O preço associado a cada serviço no itinerário é o da fracção do tempo do serviço nesse itinerário, com duas casas decimais. O preço do itinerário é a soma (sem arredondamentos) dos preços dos segmentos que o formam, apresentado com duas casas decimais.
+
{{CVSCode|Estes comandos já estão parcialmente implementados  nas classes da ''package'' '''sth.app.student''' (disponível no CVS), respectivamente: '''DoDeliverProject''', '''DoAnswerSurvey''', '''DoShowSurveyResults'''.}}
  
{{CollapsedCode|Exemplo de apresentação de itinerários para um passageiro|
+
=== Entregar projecto ===
<text>
+
 
== Passageiro 2: José Simão ==
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''), o nome do projecto no contexto dessa disciplina ('''requestProjectName()''') e o texto relativo à sumissão ('''requestDeliveryMessage()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o aluno não estiver inscrito, e '''NoSuchProjectException''', se o projecto não existir ou não estiver aberto.
 +
 
 +
Em caso de identificação bem sucedida, a submissão é registada no projecto.<!-- Para tal, é pedida uma mensagem de registo da entrega do projecto ('''requestDeliveryMessage()''').-->
 +
<!--
 +
Deve ser lançada a excepção '''ProjectClosedException''', quando se tenta realizar uma entrega para um projecto fechado.
 +
-->
 +
 
 +
=== Preencher inquérito ===
 +
 
 +
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()''').
 +
É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o aluno não estiver inscrito, '''NoSuchProjectException''', se o projecto não existir ou o aluno não tiver feito nenhuma submissão, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa ou não estiver aberto.
 +
 
 +
Em caso de identificação bem sucedida, a resposta ao inquérito é registada. Para tal, é pedido o número de horas gasto a realizar o projecto ('''requestProjectHours()''') e o comentário ao projecto ('''requestComment()''').
 +
 
 +
=== Ver resultados de inquérito ===
  
Itinerário 1 para 2017-10-18 @ 20.03
+
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se o aluno não estiver inscrito, '''NoSuchProjectException''', se o projecto não existir, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa. Em caso de identificação bem sucedida, os resultados do inquérito são apresentados de acordo com o formato seguinte, ordenados por ordem de resposta.
Serviço #692 @ 6.37
 
09:06 Évora
 
09:17 Casa Branca
 
09:31 Vendas Novas
 
09:53 Pinhal Novo
 
Serviço #570 @ 13.66
 
10:48 Pinhal Novo
 
11:19 Grândola
 
11:33 Ermidas-Sado
 
11:55 Funcheira
 
12:24 Santa Clara-Sabóia
 
12:52 Messines-Alte
 
13:02 Tunes
 
  
Itinerário 2 para 2017-10-25 @ 22.57
+
{{CollapsedCode|Formato de apresentação para inquéritos criados (por abrir)|
Serviço #184 @ 16.41
+
''Nome da disciplina'' - ''Nome do projecto'' (por abrir)
15:35 Tunes
+
}}
17:23 Pinhal Novo
+
{{CollapsedCode|Formato de apresentação para inquéritos abertos|
Serviço #596 @ 6.17
+
''Nome da disciplina'' - ''Nome do projecto'' (aberto)
17:48 Pinhal Novo
+
}}
18:10 Vendas Novas
+
{{CollapsedCode|Formato de apresentação para inquéritos fechados|
18:24 Casa Branca
+
''Nome da disciplina'' - ''Nome do projecto'' (fechado)
18:35 Évora
+
}}
 +
{{CollapsedCode|Formato de apresentação para inquéritos finalizados|
 +
''Nome da disciplina - Nome do projecto''
 +
  * Número de respostas: ''Número de respostas''
 +
  * Tempo médio (horas): ''Tempo médio''
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (aberto)|<text>
 +
Programação com Objectos - Coisas Estranhas (aberto)
 +
</text>
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (fechado)|<text>
 +
Programação com Objectos - Gatos Sofisticados (fechado)
 +
</text>
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação (finalizado)|<text>
 +
Programação com Objectos - Gatos Simples
 +
* Número de respostas: 30
 +
* Tempo médio (horas): 12
 
</text>
 
</text>
 
}}
 
}}
 +
<!--Se um inquérito tiver sido cancelado, a aplicação deve comportar-se como se ele não existisse, mesmo que continue na memória da aplicação.-->
 +
 +
== Portal do Delegado ==
 +
 +
Este menu apresenta as operações disponíveis para delegado, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: [[#Criar inquérito|Criar inquérito]], [[#Apagar inquérito|Apagar inquérito]], [[#Abrir inquérito|Abrir inquérito]], [[#Fechar inquérito|Fechar inquérito]], [[#Finalizar inquérito|Finalizar inquérito]], [[#Mostrar inquéritos de uma disciplina|Mostrar inquéritos de uma disciplina]].
 +
 +
As etiquetas das opções deste menu estão definidas na classe '''sth.app.representative.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''sth.app.representative.Message'''.
 +
 +
{{CVSCode|Estes comandos já estão parcialmente implementados  nas classes da ''package'' '''sth.app.representative''' (disponível no CVS), respectivamente: '''DoCreateSurvey''', '''DoRemoveSurvey''', '''DoOpenSurvey''', '''DoCloseSurvey''', '''DoFinishSurvey''', '''DoShowSurveys'''.}}
 +
 +
=== Criar inquérito ===
 +
 +
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado, '''NoSuchProjectException''', se o projecto não existir, e '''DuplicateSurveyException''', se o inquérito já existir. Em caso de identificação bem sucedida, o novo inquérito é criado.
  
=== Registar itinerário para um passageiro ===
+
=== Cancelar inquérito ===
  
Esta acção permite registar um novo itinerário para um passageiro.  
+
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado, '''NoSuchProjectException''', se o projecto não existir, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa.
  
Para tal, pede-se o identificador do passageiro ('''requestPassengerId()'''), a nome da estação de partida ('''requestDepartureStationName()'''), o nome da estação de destino ('''requestArrivalStationName()'''), a data da partida, no formato [https://en.wikipedia.org/wiki/ISO_8601 YYYY-MM-DD] ('''requestDepartureDate()'''), e a hora mínima para a partida, no formato HH:MM ('''requestDepartureTime()''').
+
Se o inquérito estiver aberto e já tiver pelo menos uma resposta, não pode ser removido, devendo ser lançada a excepção '''NonEmptySurveyException'''.
  
Se a data não estiver num formato correcto, é lançada a excepção '''mmt.app.BadDateException''', não sendo realizada nenhuma acção.
+
Não é possível cancelar inquéritos finalizados, pelo que, neste caso, deve ser lançada a excepção '''SurveyFinishedException'''.
  
Se a hora não estiver num formato correcto, é lançada a excepção '''mmt.app.BadTimeException''', não sendo realizada nenhuma acção.
+
Em caso de identificação bem sucedida, a operação é executada.
 +
<!--Se o inquérito estiver criado ou aberto e não tiver respostas, esta operação remove o inquérito. Se o inquérito estiver fechado, então esta operação abre-o novamente.-->
  
Se não for possível fazer uma reserva, i.e., o número de candidatos é nulo, é apresentada a mensagem '''noItinerariesBetween()''', não sendo realizada nenhuma acção.
+
=== Abrir inquérito ===
  
Em caso de sucesso, como resultado, o sistema apresenta uma lista com todos os candidatos encontrados (ordenados hierarquicamente pelos seguintes critérios: hora de partida, hora de chegada e tempo de viagem). Se forem encontradas múltiplas alternativas com o mesmo serviço de partida, apenas se apresenta a que chega mais cedo (excepto se existir uma ligação directa nesse serviço, mesmo que mais lenta). De seguida, o sistema pede o número da alternativa ('''requestItineraryChoice()''') a guardar (1 para a primeira alternativa, etc.) no registo dos itinerários adquiridos pelo passageiro, actualizando-se o estado correspondente.
+
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa.
  
Se a escolha for 0 (zero), não é realizada nenhuma acção e os itinerários candidatos são descartados.
+
Em caso de identificação bem sucedida, o inquérito é aberto. Erros de operação causam o lançamento da excepção '''OpeningSurveyException'''.
  
Se a escolha corresponder a um número de itinerário inválido, é lançada a excepção '''mmt.app.NoSuchItineraryException''', não sendo realizada nenhuma acção (são descartados eventuais itinerários candidatos).
+
=== Fechar inquérito ===
  
O formato de apresentação das escolhas é como definido para os itinerários, mas sem a linha relativa ao passageiro.
+
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa.
  
{{CollapsedCode|Exemplo de apresentação de hipótese de itinerário: Évora >> Tunes (opção #3)|
+
Em caso de identificação bem sucedida, o inquérito é fechado. Erros de operação causam o lançamento da excepção '''ClosingSurveyException'''.
<text>
+
 
Itinerário 3 para 2017-11-21 @ 20.38
+
=== Finalizar inquérito ===
Serviço #694 @ 6.65
+
 
16:57 Évora
+
É pedido o identificador da disciplina ('''requestDisciplineName()''') e o nome do projecto no contexto dessa disciplina ('''requestProjectName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado, e '''NoSurveyException''', se o inquérito não tiver sido criado para o projecto em causa.
17:08 Casa Branca
+
 
17:22 Vendas Novas
+
Em caso de identificação bem sucedida, o inquérito é finalizado. Erros de operação causam o lançamento da excepção '''FinishingSurveyException'''.
17:29 São João das Craveiras
+
 
17:33 Pegoes
+
=== Mostrar inquéritos de uma disciplina ===
17:38 Fernando Pó
+
 
17:43 Poceirão
+
É pedido o identificador da disciplina ('''requestDisciplineName()'''). É lançada a excepção '''NoSuchDisciplineException''', se a disciplina indicada não existir ou se não for do curso do delegado. Em caso de identificação bem sucedida, os inquéritos são apresentados de acordo com o formato seguinte, ordenados por ordem alfabética de nome de projecto.
17:51 Pinhal Novo
+
 
Serviço #574 @ 13.73
+
{{CollapsedCode|Formato de apresentação para inquéritos criados (por abrir)|
18:18 Pinhal Novo
+
''Nome da disciplina'' - ''Nome do projecto'' (por abrir)
18:46 Grândola
+
}}
19:01 Ermidas-Sado
+
{{CollapsedCode|Formato de apresentação para inquéritos abertos|
19:29 Funcheira
+
''Nome da disciplina'' - ''Nome do projecto'' (aberto)
19:57 Santa Clara-Sabóia
+
}}
20:24 Messines-Alte
+
{{CollapsedCode|Formato de apresentação para inquéritos fechados|
20:34 Tunes
+
''Nome da disciplina'' - ''Nome do projecto'' (fechado)
 +
}}
 +
{{CollapsedCode|Formato de apresentação para inquéritos finalizados|
 +
''Nome da disciplina'' - ''Nome do projecto'' - ''Número de respostas'' respostas - ''Tempo médio de execução'' horas
 +
}}
 +
{{CollapsedCode|Exemplo de apresentação|<text>
 +
Programação com Objectos - Coisas Estranhas (aberto)
 +
Programação com Objectos - Gatos Simples - 30 respostas - 13 horas
 +
Programação com Objectos - Gatos Sofisticados - 40 respostas - 20 horas
 +
Programação com Objectos - Mais Gatos - 10 respostas - 2 horas
 +
Programação com Objectos - Zap to it! (fechado)
 
</text>
 
</text>
 
}}
 
}}
 +
 +
Caso uma disciplina não tenha projectos ou projectos com inquéritos, não deve ser apresentada nenhuma saída.
  
 
= Leitura de Dados a Partir de Ficheiros Textuais =
 
= Leitura de Dados a Partir de Ficheiros Textuais =
Line 331: Line 430:
 
== Exemplo de ficheiro a importar ==
 
== Exemplo de ficheiro a importar ==
  
O formato é como exemplificado a seguir. A notação "..." significa repetição de formato. Nos itinerários, o primeiro número indica o identificador único do passageiro e as outras entradas (a seguir à data) indicam o serviço e as estações correspondentes de início e fim do troço que faz parte do itinerário.
+
Cada utilizador tem uma descrição distinta mas que segue o seguinte formato geral.
 +
 
 +
''TIPO''|''identificador''|''telefone''|''nome''
 +
 
 +
Dependendo do tipo de pessoa, ''TIPO'' pode tomar os valores '''FUNCIONÁRIO''', '''DOCENTE''', '''ALUNO''' e '''DELEGADO''' (para alunos que são delegados).
 +
 
 +
A seguir à linha da descrição, podem seguir-se outras (iniciadas pelo carácter '''#''') que acrescentam informação adicional para o utilizador em causa. A informação adicional para os alunos (delegados ou não) e para os docentes é uma lista de cursos e disciplinas (uma por linha): para os alunos, são as disciplinas que frequentam; para os docentes, são as disciplinas que leccionam. Para os funcionários, não há informação adicional a processar.
 +
 
 +
# ''Nome do curso''|''Nome da disciplina''
 +
 
 +
{{CollapsedCode|Exemplo de ficheiro de entrada textual|
 
<text>
 
<text>
SERVICE|180|51.5|05:47|Porto - Campanhã|...|11:23|Faro
+
FUNCIONÁRIO|100001|123789456|Maria José
SERVICE|694|12.2|16:57|Évora|17:08|Casa Branca|...|18:36|Lisboa - Oriente
+
DELEGADO|100010|123456789|João Maria
SERVICE|420|11.45|08:36|Valença|09:09|Viana do Castelo|09:50|Nine|10:18|Porto - Campanhã
+
# Informática|Fundamentos da Programação
SERVICE|5500|11.35|15:48|Elvas|...|18:25|Entroncamento
+
# Informática|Algoritmos e Estruturas de Dados
PASSENGER|Obi-Wan
+
# Informática|Programação com Objectos
PASSENGER|Yoda
+
# Informática|Análise e Síntese de Algoritmos
ITINERARY|0|2017-10-18|690/Évora/Pinhal Novo|180/Pinhal Novo/Tunes|5904/Tunes/Silves
+
DELEGADO|100011|123456789|João Manuel
 +
# Informática|Fundamentois da Programação
 +
# Informática|Algoritmos e Estruturas de Dados
 +
# Informática|Programação com Objectos
 +
# Informática|Análise e Síntese de Algoritmos
 +
DELEGADO|100012|123456789|João Miguel
 +
# Matemática|Álgebra Linear
 +
# Matemática|Probabilidades e Estatística
 +
# Matemática|Cálculo I
 +
# Matemática|Métodos Numéricos
 +
ALUNO|100013|123456789|José Manuel
 +
# Matemática|Álgebra Linear
 +
# Matemática|Probabilidades e Estatística
 +
# Matemática|Cálculo I
 +
# Matemática|Métodos Numéricos
 +
DOCENTE|100100|987654321|Ana Maria
 +
# Informática|Análise e Síntese de Algoritmos
 +
# Matemática|Álgebra Linear
 +
FUNCIONÁRIO|101010|789456123|José Carlos
 
</text>
 
</text>
<!--
+
}}
Embora o interpretador de expressões tenha de assinalar problemas relativos à interpretação de expressões mal especificadas, a-->Assume-se que não existem entradas mal-formadas nestes ficheiros.<!-- (embora tenham de ser detectadas).-->
+
A codificação dos ficheiros a ler é garantidamente [[wp:UTF-8|UTF-8]].
 
 
= Considerações sobre Flexibilidade e Eficiência =
 
 
Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Assim:
 
* A aplicação deve permitir a adição de novas categorias de passageiro sem alterações no código já realizado.
 
* A aplicação deve permitir a adição de novas procuras de serviços com baixo impacto no código já realizado (em termos do código para suportar a nova procura).
 
  
 
= Execução dos Programas e Testes Automáticos =
 
= Execução dos Programas e Testes Automáticos =
  
Usando os ficheiros '''test.import''', '''test.in''' e '''test.out''', é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável '''CLASSPATH''' (ou da opção equivalente '''-cp''' do comando '''java'''), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação ('''mmt.app.App.main'''). As propriedades são tratadas automaticamente pelo código de apoio.
+
Usando os ficheiros '''test.import''', '''test.in''' e '''test.out''', é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável '''CLASSPATH''' (ou da opção equivalente '''-cp''' do comando '''java'''), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação ('''sth.app.App.main'''). As propriedades são tratadas automaticamente pelo código de apoio.
  
         java -Dimport=test.import -Din=test.in -Dout=test.outhyp mmt.app.App
+
         java -Dimport=test.import -Din=test.in -Dout=test.outhyp sth.app.App
  
 
Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída '''test.outhyp'''. Em caso de sucesso, os ficheiros das saídas esperada ('''test.out''') e obtida ('''test.outhyp''') devem ser iguais. A comparação pode ser feita com o comando:
 
Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída '''test.outhyp'''. Em caso de sucesso, os ficheiros das saídas esperada ('''test.out''') e obtida ('''test.outhyp''') devem ser iguais. A comparação pode ser feita com o comando:
Line 367: Line 488:
  
 
A serialização Java usa as classes da ''package'' '''[https://docs.oracle.com/javase/8/docs/api/java/io/package-summary.html java.io]''', em particular, a interface '''[https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html java.io.Serializable]''' e as classes de leitura '''[https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html java.io.ObjectInputStream]''' e escrita '''[https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html java.io.ObjectOutputStream]''' (entre outras).
 
A serialização Java usa as classes da ''package'' '''[https://docs.oracle.com/javase/8/docs/api/java/io/package-summary.html java.io]''', em particular, a interface '''[https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html java.io.Serializable]''' e as classes de leitura '''[https://docs.oracle.com/javase/8/docs/api/java/io/ObjectInputStream.html java.io.ObjectInputStream]''' e escrita '''[https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html java.io.ObjectOutputStream]''' (entre outras).
 
+
<!--
 
A representação e manipulação de datas e tempos deve ser realizada através das classes da ''package'' '''[https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html java.time]''', em particular, através das classes '''[https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html java.time.LocalDate]''' e '''[https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html java.time.LocalTime]'''. Diferenças entre tempos são representadas pela classe '''[https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html java.time.Duration]'''.
 
A representação e manipulação de datas e tempos deve ser realizada através das classes da ''package'' '''[https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html java.time]''', em particular, através das classes '''[https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html java.time.LocalDate]''' e '''[https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html java.time.LocalTime]'''. Diferenças entre tempos são representadas pela classe '''[https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html java.time.Duration]'''.
 
+
-->
 
<!--[[category:Ensino]]
 
<!--[[category:Ensino]]
 
[[category:PO]]
 
[[category:PO]]
 
[[category:Projecto de PO]]
 
[[category:Projecto de PO]]
 
[[en:Object-Oriented Programming]]-->
 
[[en:Object-Oriented Programming]]-->

Latest revision as of 00:33, 4 October 2018

AVISOS - Avaliação em Época Normal

Esclarecimento de dúvidas:

  • Consultar sempre o corpo docente atempadamente: presencialmente ou através do endereço oficial da disciplina [1].
  • Não utilizar fontes de informação não oficialmente associadas ao corpo docente (podem colocar em causa a aprovação à disciplina).
  • Não são aceites justificações para violações destes conselhos: quaisquer consequências nefastas são da responsabilidade do aluno.

Requisitos para desenvolvimento, material de apoio e actualizações do enunciado (ver informação completa em Projecto de Programação com Objectos):

  • O material de apoio é de uso obrigatório e não pode ser alterado.
  • Verificar atempadamente (mínimo de 48 horas antes do final de cada prazo) os requisitos exigidos pelo processo de desenvolvimento.

Processo de avaliação (ver informação completa em Avaliação do Projecto):

  • Datas: 2018/10/19 12:00 (inicial); 2018/11/16 12:00 (intercalar); 2018/12/07 12:00 (final); 2018/12/10-2018/12/14 (teste prático).
  • Todas as entregas são cruciais para o bom desenvolvimento do projecto, sendo obrigatórias: a não realização de uma entrega implica a exclusão da avaliação do projecto e, por consequência, da avaliação da disciplina.
  • Verificar atempadamente (até 48 horas antes do final de cada prazo) os requisitos exigidos pelo processo de avaliação, incluindo a capacidade de acesso ao repositório.
  • Apenas se consideram para avaliação os projectos existentes no repositório oficial. Apenas se considera para avaliação o ramo 'main'.
  • Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório ou de outros materiais, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho.
  • A avaliação do projecto pressupõe o compromisso de honra de que o trabalho correspondente foi realizado pelos alunos correspondentes ao grupo de avaliação.
  • Fraudes na execução do projecto terão como resultado a exclusão dos alunos implicados do processo de avaliação.
Material de Uso Obrigatório
As bibliotecas po-uuilib e o conteúdo inicial do CVS são de uso obrigatório:
  • po-uuilib (classes de base) po-uuilib-201708311009.tar.bz2 (não pode ser alterada) - javadoc
  • sth-core (classes do "core") (via CVS) (deve ser completada -- os nomes das classes fornecidas não podem ser alterados)
  • sth-app (classes de interacção) (via CVS) (deve ser completada -- os nomes das classes fornecidas não podem ser alterados)
A máquina virtual, fornecida para desenvolvimento do projecto, já contém todo o material de apoio.
Uso Obrigatório: Repositório CVS
Apenas se consideram para avaliação os projectos existentes no repositório CVS oficial.

Trabalhos não presentes no repositório no final do prazo têm classificação 0 (zero) (não são aceites outras formas de entrega). Não são admitidas justificações para atrasos em sincronizações do repositório. A indisponibilidade temporária do repositório, desde que inferior a 24 horas, não justifica atrasos na submissão de um trabalho.

O objectivo do projecto é criar uma aplicação que gere parte da actividade dos cursos de uma universidade. Em particular, a aplicação faz a gestão de inquéritos aos projectos realizados pelos alunos nas várias disciplinas do curso.

Neste texto, o tipo negrito indica um literal (i.e., é exactamente como apresentado); o símbolo indica um espaço; e o tipo itálico indica uma parte variável (i.e., uma descrição).

Conceitos e Relações do Modelo

Existem vários conceitos importantes neste contexto: universidade, curso, aluno, professor, funcionário, projecto, inquérito.

Os conceitos listados não são os únicos possíveis no modelo e as suas relações (assim como relações com outros conceitos não mencionados) podem depender das escolhas do projecto.

Universidade, Cursos, Disciplinas

Uma universidade tem um nome e pode ter vários cursos, tendo ainda funcionários, docentes e alunos. Os alunos estão exclusivamente associados a um curso. Os funcionários e os docentes podem estar associados a vários cursos.

Cada curso tem um nome (único no contexto da universidade) e é constituído por várias disciplinas. Cada curso tem ainda um conjunto de alunos que podem inscreverem-se nas várias disciplinas do curso. Cada aluno pode inscrever-se, no máximo, em 6 disciplinas.

Cada disciplina tem um nome e apenas pertence a um curso. O nome da disciplina é o identificador único dentro do curso respectivo. Cada disciplina é leccionada por um ou mais docentes e tem 0 ou mais alunos inscritos. Os alunos inscritos numa disciplina têm que pertencer ao curso da disciplina. Existe uma capacidade máxima relativamente aos alunos que se podem inscrever numa disciplina. Um docente pode estar associado a várias disciplinas.

Pessoas

Os utilizadores da aplicação correspondem aos vários tipos de pessoa que existem na universidade: alunos, docentes e funcionários. Alunos, docentes e funcionários têm nome (cadeia de caracteres), número de telefone (cadeia de caracteres) e um identificador único (inteiro com 6 dígitos). Este identificador é atribuído automaticamente (de forma incremental) e começa em 100000. Um aluno pode ainda ser delegado do curso em que o aluno está inscrito. O número máximo de delegados de um curso é 7. Em qualquer instante, um aluno pode tornar-se delegado ou deixar de ser delegado.

Projectos

Os docentes podem criar projectos associados às disciplinas que leccionam. Cada projecto tem um nome e descrição. O nome deve ser único no contexto da disciplina. Quando o projecto é criado fica automaticamente aberto.

Um aluno pode submeter a sua versão do projecto desde que o projecto ainda esteja aberto e o aluno esteja inscrito na disciplina do projecto. Os alunos podem realizar várias submissões no mesmo projecto, sendo preservada apenas a última. Por razões de simplificação, a submissão é representada por uma cadeia de caracteres introduzida pelo aluno.

Inquéritos

A cada projecto não fechado pode ser associado, no máximo, um inquérito.

O inquérito recolhe informação sobre o número de horas gastas na execução do projecto (número inteiro) e um comentário livre por parte do aluno que responde (cadeia de caracteres).

Um inquérito pode estar em várias situações: criado, aberto, fechado e finalizado. O comportamento do inquérito dependa desta situação. A mudança de situação é explícita, excepto quando o projecto associado é fechado: neste caso, o inquérito passa automaticamente de criado para aberto. Esta é a única mudança implícita: as outras mudanças são explícitas e da exclusiva responsabilidade de um delegado. O delegado tem de pertencer ao mesmo curso da disciplina no contexto do qual o inquérito é realizado.

É possível realizar várias operações sobre um inquérito: cancelar, abrir, fechar, finalizar, submeter resposta e obter resultados.

Cancelar um inquérito criado ou aberto (e sem respostas) corresponde a remover o inquérito. Se o inquérito estiver aberto, mas já tiver pelo menos uma resposta, então não pode ser removido e deve ser assinalado um erro. Cancelar um inquérito fechado corresponde a abri-lo novamente. Finalmente, cancelar um inquérito finalizado é impossível, pelo que deve ser assinalado um erro.

Um inquérito criado é aberto quando o projecto que lhe está associado é fechado. Caso se tente abrir um inquérito que não obedeça a estas duas restrições deve ser assinalado um erro.

Um inquérito aberto pode ser fechado. Se estiver fechado, a operação de fecho não tem efeito. Em qualquer outra situação deve dar um erro.

Um inquérito fechado pode ser finalizado, impedindo futuras alterações. Finalizar um inquérito previamente finalizado não tem qualquer efeito. Finalizar inquéritos noutras situações corresponde a um erro.

Só os alunos que entregaram o projecto (ou seja, realizaram pelo menos uma submissão) podem responder ao inquérito. Cada aluno só pode responder uma vez. As respostas devem ser anónimas, ou seja, não deve guardada informação que permita saber qual a resposta de um dado aluno a um inquérito.

Os alunos podem submeter uma resposta a um inquérito aberto. Em qualquer outra situação, esta operação deve assinalar um erro. Alunos, docentes e delegados podem obter o resultado de um inquérito que esteja finalizado. Nas restantes situações, apenas se indica qual é o estado do inquérito.

Note-se que tas operações indicadas anteriormente estão disponíveis apenas para pessoas que estejam associadas à disciplina à qual pertence o projecto com o inquérito em causa.

Notificações

Deve existir um mecanismo de mensagens que permita avisar determinados utilizadores quando os inquéritos associados a uma dada disciplina ficam em determinadas situações:

  • Quando um inquérito de um projecto de uma disciplina abre, quer-se enviar uma mensagem a todos os alunos, delegados e docentes da disciplina.
  • Quando um inquérito de um projecto de uma disciplina finaliza, quer-se enviar uma mensagem a todos os alunos, delegados e docentes da disciplina.

Nota: dado que um aluno pode também ser delegado, o mecanismo de envio de mensagens deve tratar este como se fosse uma única entidade. Assim, um aluno de uma disciplina que seja também delegado deve receber apenas uma mensagem e não duas cada vez que o sistema tem que enviar uma mensagem.

A apresentação das mensagens enviadas para um dado utilizador deve ser feita quando o utilizador faz login no sistema. Após o login ter sido realizado com sucesso devem ser apresentadas todas as mensagens que tenham sido enviadas para o utilizador em causa desde a última vez que se registou no sistema. Após esta visualização considera-se que o utilizador fica sem mensagens. As mensagens devem ser apresentadas pela mesma ordem em que enviadas pelo sistema.

Requisitos de Desenho

Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código já produzido para a aplicação. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Assim:

  • A determinação da descrição de um utilizador deve estar realizada de forma a evitar a duplicação de código comum, facilitando assim a introdução de novos tipos de utilizadores.
  • A concretização da entidade inquérito deve ser feita por forma aumentar a legibilidade do código relacionado com esta entidade por forma a que caso se queira alterar a lógica de cada situação em que o inquérito possa estar, isso possa ser feito facilmente.
  • O mecanismo de envio das mensagens deve ser suficientemente flexível para suportar outras entidades que queiram também receber as mensagens. Deve ainda permitir que os destinatários das mensagens possam dizer se querem ou não ser notificados relativamente a cada disciplina. Por exemplo, um aluno de uma disciplina pode dizer que já não quer receber mensagens relativas a abrir e finalizar um inquérito associado à disciplina.

Funcionalidade da aplicação

A aplicação permite manter informação sobre as entidades do modelo, permitindo, em particular, gerir projectos e inquéritos. Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).

A base de dados com os conceitos pré-definidos é carregada no início da aplicação. Não é possível adicionar ou remover pessoas durante a execução da aplicação. Não é possível a um utilizador alterar a informação pessoal de outros utilizadores.

A aplicação tem comportamento que depende do utilizador, pelo que deve permitir o estabelecimento de uma identidade inicial (login). Um utilizador que tenha estabelecido a sua identidade com sucesso é dito como estando registado. Em cada momento, a aplicação tem, no máximo, um utilizador registado.

Note-se que não é necessário implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da funcionalidade do core da aplicação, tal como é visível pelos comandos da aplicação.
A interface geral do core já está parcialmente implementada na classe sth.SchoolManager e outras fornecidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.

Gestão de informação sobre pessoas

Um utilizador registado pode ver todos os utilizadores ou só um dado utilizador, procurar um utilizador e actualizar o seu número de telefone.

Gestão de actividades dos alunos

Um utilizador registado que seja aluno pode realizar as seguintes tarefas: entregar um projecto, preencher um inquérito e ver resultados de um inquérito.

Gestão de actividades dos delegados

Um utilizador registado que seja delegado tem à sua disposição as seguinte funcionalidade: criar inquéritos, cancelar inquéritos, abrir inquéritos, fechar inquéritos, finalizar inquéritos e mostrar inquéritos de uma disciplina.

Gestão de actividades dos professores

Um utilizador registado que seja um docente pode realizar as seguintes actividades: criar projectos, fechar projectos, ver as submissões de um projecto, ver os alunos de uma disciplina leccionada e ver resultados de inquéritos.

Serialização

É possível guardar e recuperar o estado actual da aplicação, preservando toda a informação relacionada com a universidade e que foi descrita acima.

Interacção com o utilizador

Descreve-se nesta secção a funcionalidade máxima da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de proceder à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção Sair (fecha o menu).

As operações de pedido e apresentação de informação ao utilizador devem realizar-se através dos objectos form e display, respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das bibliotecas de suporte (po-uuilib e sth-app). As mensagens não podem ser usadas no núcleo da aplicação (sth-core). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.

As excepções usadas na interacção, excepto se indicado, são subclasses de pt.tecnico.po.ui.DialogException, são lançadas pelos comandos e tratadas por pt.tecnico.po.ui.Menu. Outras excepções não devem substituir as fornecidas nos casos descritos.

Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcialmente implementados nas packages sth.app, sth.app.main, sth.app.person, sth.app.teaching, sth.app.student e sth.app.representative. Estas classes são de uso obrigatório e estão disponíveis no CVS (módulo sth-app).

Menu Principal

As acções deste menu permitem gerir a salvaguarda do estado da aplicação e abrir submenus. A lista completa é a seguinte: Reiniciar, Abrir, Guardar e Portal Pessoal, Portal do Docente, Portal do Estudante e Portal do Delegado. Inicialmente, a aplicação apenas tem informação sobre as pessoas, cursos e disciplinas que foram carregados no arranque. Note-se que nem todas as opções do menu estão disponíveis para todos os utilizadores (ver abaixo).

As etiquetas das opções deste menu estão definidas na classe sth.app.main.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe sth.app.main.Message.

Estes comandos já estão implementados nas classes da package sth.app.main (disponível no CVS), respectivamente: DoOpen, DoSave, DoOpenPersonelMenu, DoOpenTeachingMenu, DoOpenStudentMenu, DoOpenRepresentativeMenu.

Salvaguarda do estado actual da aplicação

O conteúdo da aplicação (toda a informação detida pela universidade actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: java.io.Serializable). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:

  • Abrir -- Carrega os dados de uma sessão anterior a partir de um ficheiro previamente guardado (ficando este ficheiro associado à aplicação, para futuras operações de salvaguarda). Pede-se o nome do ficheiro a abrir (openFile()). Caso o ficheiro não exista, é apresentada a mensagem fileNotFound(). Esta operação não permite leitura de ficheiros de texto (estes apenas são utilizados na inicialização da aplicação). Esta opção substitui toda a informação da aplicação.
  • Guardar -- Guarda o estado actual da aplicação no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado. Esta interacção realiza-se através do método newSaveAs(). Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.

A opção Sair nunca guarda o estado da aplicação, mesmo que existam alterações.

Gestão e consulta de dados da aplicação

  • Portal Pessoal -- Abre o menu de consulta de informações sobre pessoas.
  • Portal do Docente -- Abre o menu de gestão de actividades dos professores (esta opção apenas está disponível para professores).
  • Portal do Estudante -- Abre o menu de gestão de actividades dos alunos (esta opção apenas está disponível para alunos).
  • Portal do Delegado -- Abre o menu de gestão de actividades dos delegados (esta opção apenas está disponível para delegados).

Portal Pessoal

Este menu permite efectuar operações sobre a base de dados de pessoal da universidade, estando disponível para todos os utilizadores. A lista completa é a seguinte: Mostrar pessoa, Alterar número de telefone, Mostrar pessoas, Procurar pessoa.

As etiquetas das opções deste menu estão definidas na classe sth.app.person.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe sth.app.person.Message.

Sempre que for pedido o identificador de uma pessoa (requestPersonId()) e a pessoa não existir, é lançada a excepção sth.app.NoSuchPersonException.

Estes comandos já estão implementados nas classes da package sth.app.person (disponível no CVS), respectivamente: DoShowPerson, DoChangePhoneNumber, DoShowAllPersons, DoSearchPerson.

Mostrar pessoa

Apresenta as informações sobre a pessoa especificada pela identificação fornecida pelo processo de login, de acordo com o seguinte formato (e variações descritas abaixo).

Formato de apresentação (cabeçalho)
TIPO|identificador|telefone|nome

Dependendo do tipo de pessoa, TIPO pode tomar os valores FUNCIONÁRIO, DOCENTE, ALUNO e DELEGADO (para alunos que são delegados). Se os utilizadores forem do tipo DOCENTE, então à linha de identificação devem seguir-se as linhas com os nomes dos cursos e das disciplinas que lecciona nesses cursos, ordenados por ordem alfabética do nome do curso e da disciplina (dentro do curso). Se os utilizadores forem do tipo ALUNO ou DELEGADO, então à linha de identificação devem seguir-se as linhas com os nomes das disciplinas em que está inscrito, ordenados por ordem alfabética do nome da disciplina.

Exemplo de apresentação (professor)
DOCENTE|100050|987 654 321|Maria João
* Informática - Análise e Síntese de Algoritmos
* Matemática - Algebra
Exemplo de apresentação (aluno)
ALUNO|101090|123 456 789|João Maria
* Informática - Análise e Síntese de Algoritmos
* Informática - Inteligência Artificial
* Informática - Sistemas Operativos
* Informática - Fundamentos da Programação
* Informática - Programação com Objectos

Alterar número de telefone

Pede o novo número de telefone (requestPhoneNumber()). De seguida, altera o número de telefone da pessoa registada e apresenta as informações da pessoa (tal como descrito em Mostrar pessoa).

Mostrar pessoas

Apresenta informações sobre todas as pessoas conhecidas.

A lista é ordenada pelo identificador da pessoa e o formato é o descrito em Mostrar pessoa.

Procurar pessoa

Pede o nome da pessoa a procurar (requestName()). A operação apresenta a lista de pessoas (ordenadas por ordem alfabética do nome) cujo nome satisfaz a procura (o nome da pessoa deve conter a cadeia de caracteres em questão). O formato de apresentação é o descrito em Mostrar pessoa.

Portal do Docente

Este menu apresenta as operações disponíveis para docentes, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: Criar projecto, Fechar projecto, Ver submissões de um projecto, Ver alunos de disciplina leccionada, Ver resultados de um inquérito.

As etiquetas das opções deste menu estão definidas na classe sth.app.teaching.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe sth.app.teaching.Message.

Estes comandos já estão implementados nas classes da package sth.app.teaching (disponível no CVS), respectivamente: DoCreateProject, DoCloseProject, DoShowProjectSubmissions, DoShowCourseStudents, DoShowSurveyResults.

Criar projecto

É pedido o identificador da disciplina (requestDisciplineName()), e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e DuplicateProjectException, se o projecto já existir. Em caso de identificação bem sucedida, o projecto é criado.

Fechar projecto

É pedido o identificador da disciplina (requestDisciplineName()), e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e NoSuchProjectException, se o projecto não existir. Em caso de identificação bem sucedida, o projecto é fechado.

Se o projecto já estiver fechado, o comando não executa nenhuma acção.

Ver submissões de um projecto

É pedido o identificador da disciplina (requestDisciplineName()), e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, e NoSuchProjectException, se o projecto não existir. Em caso de identificação bem sucedida, as submissões do projecto são apresentadas, ordenadas pelo número de aluno que realizou a submissão, e com o seguinte formato.

Formato de apresentação
Nome da Disciplina - Nome do Projecto
* Identificador do 1º aluno - submissão do 1º aluno
...
* Identificador do Nº aluno - submissão do Nº aluno
Exemplo de apresentação
<text>

Programação com Objectos - Gatos Simples

  • 0234 - Gato.java
  • 6789 - Cat.java
  • 7912 - Tigre.java

</text>

Este comando pode operar, tanto sobre projectos abertos, como sobre projectos fechados.

Ver alunos de disciplina leccionada

É pedido o identificador da disciplina (requestDisciplineName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa. Em caso de identificação bem sucedida, é apresentada a lista de alunos, ordenada pelo identificador de aluno, no formato definido em Mostrar pessoa.

Ver resultados de um inquérito

É pedido o identificador da disciplina (requestDisciplineName()), o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o docente não leccionar a disciplina em causa, NoSuchProjectException, se o projecto não existir, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa. Em caso de identificação bem sucedida, os resultados do inquérito são apresentados de acordo com o formato seguinte, ordenados por ordem de resposta.

Formato de apresentação para inquéritos criados (por abrir)
Nome da disciplina - Nome do projecto (por abrir)
Formato de apresentação para inquéritos abertos
Nome da disciplina - Nome do projecto (aberto)
Formato de apresentação para inquéritos fechados
Nome da disciplina - Nome do projecto (fechado)
Formato de apresentação para inquéritos finalizados
Nome da disciplina - Nome do projecto
 * Número de submissões: Número de submissões
 * Número de respostas: Número de respostas
 * Tempos (mínimo, médio, máximo): Tempo mínimo de resolução do projecto, Tempo médio de resolução do projecto, Tempo máximo de resolução do projecto
Exemplos de apresentação (aberto)
<text>

Programação com Objectos - Coisas Estranhas (aberto) </text>

Exemplo de apresentação (fechado)
<text>

Programação com Objectos - Gatos Sofisticados (fechado) </text>

Exemplo de apresentação (finalizado)
<text>

Programação com Objectos - Gatos Simples

* Número de submissões: 30
* Número de respostas: 20
* Tempos de resolução (horas) (mínimo, médio, máximo): 10, 16, 20

</text>

Portal do Estudante

Este menu apresenta as operações disponíveis para alunos, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: Entregar projecto, Preencher inquérito, Ver resultados de inquérito.

As etiquetas das opções deste menu estão definidas na classe sth.app.student.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe sth.app.student.Message.

Estes comandos já estão parcialmente implementados nas classes da package sth.app.student (disponível no CVS), respectivamente: DoDeliverProject, DoAnswerSurvey, DoShowSurveyResults.

Entregar projecto

É pedido o identificador da disciplina (requestDisciplineName()), o nome do projecto no contexto dessa disciplina (requestProjectName()) e o texto relativo à sumissão (requestDeliveryMessage()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o aluno não estiver inscrito, e NoSuchProjectException, se o projecto não existir ou não estiver aberto.

Em caso de identificação bem sucedida, a submissão é registada no projecto.

Preencher inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o aluno não estiver inscrito, NoSuchProjectException, se o projecto não existir ou o aluno não tiver feito nenhuma submissão, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa ou não estiver aberto.

Em caso de identificação bem sucedida, a resposta ao inquérito é registada. Para tal, é pedido o número de horas gasto a realizar o projecto (requestProjectHours()) e o comentário ao projecto (requestComment()).

Ver resultados de inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se o aluno não estiver inscrito, NoSuchProjectException, se o projecto não existir, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa. Em caso de identificação bem sucedida, os resultados do inquérito são apresentados de acordo com o formato seguinte, ordenados por ordem de resposta.

Formato de apresentação para inquéritos criados (por abrir)
Nome da disciplina - Nome do projecto (por abrir)
Formato de apresentação para inquéritos abertos
Nome da disciplina - Nome do projecto (aberto)
Formato de apresentação para inquéritos fechados
Nome da disciplina - Nome do projecto (fechado)
Formato de apresentação para inquéritos finalizados
Nome da disciplina - Nome do projecto
 * Número de respostas: Número de respostas
 * Tempo médio (horas): Tempo médio
Exemplo de apresentação (aberto)
<text>

Programação com Objectos - Coisas Estranhas (aberto) </text>

Exemplo de apresentação (fechado)
<text>

Programação com Objectos - Gatos Sofisticados (fechado) </text>

Exemplo de apresentação (finalizado)
<text>

Programação com Objectos - Gatos Simples

* Número de respostas: 30
* Tempo médio (horas): 12

</text>

Portal do Delegado

Este menu apresenta as operações disponíveis para delegado, estando apenas disponível para estes utilizadores. A lista completa é a seguinte: Criar inquérito, Apagar inquérito, Abrir inquérito, Fechar inquérito, Finalizar inquérito, Mostrar inquéritos de uma disciplina.

As etiquetas das opções deste menu estão definidas na classe sth.app.representative.Label. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe sth.app.representative.Message.

Estes comandos já estão parcialmente implementados nas classes da package sth.app.representative (disponível no CVS), respectivamente: DoCreateSurvey, DoRemoveSurvey, DoOpenSurvey, DoCloseSurvey, DoFinishSurvey, DoShowSurveys.

Criar inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado, NoSuchProjectException, se o projecto não existir, e DuplicateSurveyException, se o inquérito já existir. Em caso de identificação bem sucedida, o novo inquérito é criado.

Cancelar inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado, NoSuchProjectException, se o projecto não existir, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa.

Se o inquérito estiver aberto e já tiver pelo menos uma resposta, não pode ser removido, devendo ser lançada a excepção NonEmptySurveyException.

Não é possível cancelar inquéritos finalizados, pelo que, neste caso, deve ser lançada a excepção SurveyFinishedException.

Em caso de identificação bem sucedida, a operação é executada.

Abrir inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa.

Em caso de identificação bem sucedida, o inquérito é aberto. Erros de operação causam o lançamento da excepção OpeningSurveyException.

Fechar inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa.

Em caso de identificação bem sucedida, o inquérito é fechado. Erros de operação causam o lançamento da excepção ClosingSurveyException.

Finalizar inquérito

É pedido o identificador da disciplina (requestDisciplineName()) e o nome do projecto no contexto dessa disciplina (requestProjectName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado, e NoSurveyException, se o inquérito não tiver sido criado para o projecto em causa.

Em caso de identificação bem sucedida, o inquérito é finalizado. Erros de operação causam o lançamento da excepção FinishingSurveyException.

Mostrar inquéritos de uma disciplina

É pedido o identificador da disciplina (requestDisciplineName()). É lançada a excepção NoSuchDisciplineException, se a disciplina indicada não existir ou se não for do curso do delegado. Em caso de identificação bem sucedida, os inquéritos são apresentados de acordo com o formato seguinte, ordenados por ordem alfabética de nome de projecto.

Formato de apresentação para inquéritos criados (por abrir)
Nome da disciplina - Nome do projecto (por abrir)
Formato de apresentação para inquéritos abertos
Nome da disciplina - Nome do projecto (aberto)
Formato de apresentação para inquéritos fechados
Nome da disciplina - Nome do projecto (fechado)
Formato de apresentação para inquéritos finalizados
Nome da disciplina - Nome do projecto - Número de respostas respostas - Tempo médio de execução horas
Exemplo de apresentação
<text>

Programação com Objectos - Coisas Estranhas (aberto) Programação com Objectos - Gatos Simples - 30 respostas - 13 horas Programação com Objectos - Gatos Sofisticados - 40 respostas - 20 horas Programação com Objectos - Mais Gatos - 10 respostas - 2 horas Programação com Objectos - Zap to it! (fechado) </text>

Caso uma disciplina não tenha projectos ou projectos com inquéritos, não deve ser apresentada nenhuma saída.

Leitura de Dados a Partir de Ficheiros Textuais

Além das opções de manipulação de ficheiros descritas no menu principal, é possível iniciar a aplicação com um ficheiro de texto especificado pela propriedade Java import.

Exemplo de ficheiro a importar

Cada utilizador tem uma descrição distinta mas que segue o seguinte formato geral.

TIPO|identificador|telefone|nome

Dependendo do tipo de pessoa, TIPO pode tomar os valores FUNCIONÁRIO, DOCENTE, ALUNO e DELEGADO (para alunos que são delegados).

A seguir à linha da descrição, podem seguir-se outras (iniciadas pelo carácter #) que acrescentam informação adicional para o utilizador em causa. A informação adicional para os alunos (delegados ou não) e para os docentes é uma lista de cursos e disciplinas (uma por linha): para os alunos, são as disciplinas que frequentam; para os docentes, são as disciplinas que leccionam. Para os funcionários, não há informação adicional a processar.

# Nome do curso|Nome da disciplina
Exemplo de ficheiro de entrada textual

<text> FUNCIONÁRIO

A codificação dos ficheiros a ler é garantidamente UTF-8.

Execução dos Programas e Testes Automáticos

Usando os ficheiros test.import, test.in e test.out, é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável CLASSPATH (ou da opção equivalente -cp do comando java), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação (sth.app.App.main). As propriedades são tratadas automaticamente pelo código de apoio.

       java -Dimport=test.import -Din=test.in -Dout=test.outhyp sth.app.App

Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída test.outhyp. Em caso de sucesso, os ficheiros das saídas esperada (test.out) e obtida (test.outhyp) devem ser iguais. A comparação pode ser feita com o comando:

        diff -b test.out test.outhyp

Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade.

Notas de Implementação

Tal como indicado acima, algumas classes fornecidas como material de apoio, são de uso obrigatório e não podem ser alteradas. Outras dessas classes são de uso obrigatório e têm de ser alteradas.

A serialização Java usa as classes da package java.io, em particular, a interface java.io.Serializable e as classes de leitura java.io.ObjectInputStream e escrita java.io.ObjectOutputStream (entre outras).