Sumário 1. Papyrus UML2 Modeler... 1 2. Criando o Perfil GeoProfile... 2 3. Adicionando Restrições OCL... 11 4. Adicionando Ícones aos Estereótipos... 15 5. Aplicando o Perfil GeoProfile... 17 1. Papyrus UML2 Modeler A ferramenta CASE Papyrus UML2 Modeler (PAPYRUS UML, 2010) mostrou-se uma opção interessante pelo fato de ser uma ferramenta de código aberto (opensource). Ela é baseada no ambiente Eclipse, e está sob a licença EPL (Eclipse Public License). Entre outros recursos interessantes para modelagem de sistemas utilizando o padrão UML2, a ferramenta dá suporte à criação de perfis UML, que é o nosso objetivo. O perfil é criado selecionando-se os estereótipos a serem utilizados e as metaclasses que serão estendidas por esses estereótipos. Na Figura abaixo é possível notar parte dos estereótipos do GeoProfile sendo especificados na ferramenta. Área de trabalho da ferramenta Papyrus 1
2. Criando o Perfil GeoProfile Para criarmos nosso perfil nesta ferramenta primeiro devemos criar um novo projeto. Nomeie o novo projeto GeoProfile e salve em um diretório qualquer. Agora vamos criar o Perfil em si. Clique com o botão direito no novo projeto e vá em: New -> Create an empty profile. Nomeie o seu perfil GeoProfile e na janela que aparece, selecione o projeto criado anteriormente. Veja que do lado esquerdo, no Navigator, deverá aparecer o perfil criado anteriormente e a barra Palette com os elementos do lado direito, como mostrado na figura abaixo. 2
Clicando com o botão direito do mouse encima do projeto na aba Outline, teremos a opção Add an element que nos possibilita adicionar os elementos contidos nessa ferramenta, os principais que iremos utilizar aqui serão: Metaclass, Stereotype, Extension e Enumeration, alguns destes e os demais podem ser encontrados na Paleta do lado direito: Generalization, ImportMetaclass, Stereotype, Extension. Primeiro vamos criar os estereótipos do GeoProfile, vamos começar com os estereótipos para objetos de rede: NetworkObj, Arc, Node, UnidirectionalArc e BidirectionalArc. Adicione os elementos Stereotype, como mostrados na figura abaixo. Perceba que os estereótipos NetworkObj e Arc são abstratos. Para colocar um 3
estereótipo como abstrato basta selecioná-lo no modelo e marcar a opção Abstract na aba inferior General. Depois use o elemento Generalization, de forma a deixar o perfil como mostrado abaixo. Obs: Caso esteja inserindo os elementos pela aba Outline, o elemento não aparecerá no diagrama, para que um elemento se torne visível, basta arrastá-lo da barra Outline para a área de diagramas. 4
O próximo passo é estender a metaclasse Class da UML utilizando os estereótipos criados, para isso adicione o elemento ImportMetaclass, na janela que aparece selecione a metaclasse Class, adicione ao projeto e dê OK. A metaclasse Class irá aparecer no diagrama, agora vamos estender a metaclasse utilizando o estereótipo criado, basta utilizar o elemento Extension. Agora vamos estender a metaclasse Association, criando os estereótipos que lida com os relacionamentos topológicos entre as classes geográficas. Existem seis tipos diferentes de relacionamentos topológicos no GeoProfile, vamos criar apenas um para exemplo. Primeiro, crie um elemento Stereotype e dê a ele o nome Temporal, como mostra a figura abaixo. 5
Agora inclua um elemento ImportMetaclass, mas desta vez selecione a metaclasse Association. Utilize agora o elemento Extension para estender a metaclasse Association com o estereótipo criado. 6
Um estereótipo pode possuir propriedades, as quais podem ser referidas como tag definitions. Quando um estereótipo é aplicado em um elemento do modelo, os valores das propriedades podem ser referidos como tagged values. O próximo passo é criar o estereótipo TemporalObject e suas enumerações (tagged values). O GeoProfile define dois tipos de enumeração, TemporalPrimitive e TemporalType. Inclua no esquema dois elementos do tipo Enumeration e nomeie-os como TemporalPrimitive e TemporalType. Adicione os EnumerationLiterals (instant e interval) em TemporalPrimitive e (valid_time, transaction_time e bitemporal) em TemporalType, veja figura abaixo. 7
Agora, adicione ao esquema o estereótipo TemporalObj e inclua dois atributos (Property) com tipos das enumerações criadas anteriormente: temporalprimitive do tipo TemporalPrimitive e temporaltype do tipo TemporalType. Para adicionar o tipo do atributo, basta selecioná-lo dentro do estereótipo ou na aba Outline, e na barra inferior General clique no botão + à frente do campo Type e selecione o tipo na janela que aparece, veja na figura abaixo. 8
Basta agora estendermos a metaclasse Class novamente para o estereótipo criado; inclua mais um elemento Extension do estereótipo TemporalObj para a metaclasse Class. Com isso já é possível criar o diagrama do perfil para os estereótipos do GeoProfile totalmente de acordo com sua especificação. Inclua os demais Stereotypes, Generalizations e Extensions que faltam de forma a deixar o modelo como se segue: 9
Esquema do GeoProfile Salve o esquema. Uma janela de dialogo irá aparecer para decidir se o perfil deve ser definido ou não. A definição é requerida de forma a utilizar o perfil. Aperte Yes e uma janela aparecerá para adicionar número da versão e outras informações sobre o perfil, estas informações podem ser vistas usando o UML2 tree editor. 10
3. Adicionando Restrições OCL A ferramenta Papyrus oferece suporte à linguagem OCL para definição de constraints, sendo as mesmas utilizadas para validar o esquema conceitual gerado. Dessa forma, as restrições OCL descritas nesta seção sempre possuem como contexto um estereótipo do GeoProfile, além de serem invariantes. As restrições especificadas para o GeoProfile basicamente evitam a ocorrência de três tipos de erros: adição de estereótipos incompatíveis a um mesmo elemento; má construção de redes; e adição de relacionamentos topológicos impossíveis de acontecer entre dois elementos (ex.: relacionamento Cross entre dois objetos geográficos com representação de ponto). Estes três grupos de restrições são analisados a seguir. Para declarar Constraints, primeiro temos que selecionar o estereótipo ao qual a restrição será adicionada, depois no painel Properties vá na aba Constraints, então clicar no botão + para adicionar uma constraint. A parte direita do painel é onde adicionamos a restrição OCL. A imagem abaixo mostra a inserção de uma constraint no estereótipo GeoField. 11
A próxima imagem mostra a restrição OCL adicionada e validada no perfil. Basta entrar com a restrição e depois clicar no botão Evaluate, se a expressão estiver correta então a mensagem Successfully Parsed irá aparecer. Depois de avaliada, a restrição deve ser salva, para isto basta clicar no botão Save. 12
As restrições do GeoProfile serão descritas abaixo, adicione-as ao perfil criado. O campo context refere-se a qual estereótipo a restrição será aplicada. Restrições OCL para verificação da existência de estereótipos incompatíveis em uma mesma classe do esquema. A context GeoField B context Network C context NetworkObj D context Node E context UnidirectionalArc self.base_class.getappliedstereotypes() -> select(s s.name = 'Point' or s.name = 'Line' or s.name = 'Polygon' or s.name = 'ComplexSpatialObj') -> isempty() self.base_class.getappliedstereotypes() -> select(s s.name = 'Point' or s.name = 'Line' or s.name = 'Polygon' or s.name = 'ComplexSpatialObj' or s.name = 'TIN' or s.name = 'Isolines' or s.name = 'GridOfCells' or s.name = 'AdjPolygons' or s.name = 'GridOfPoints' or s.name = 'IrregularPoints' or s.name = 'Node' or s.name = 'UnidirectionalArc' or s.name = 'BidirectionalArc') -> isempty() self.base_class.getappliedstereotypes() -> select(s s.name = 'TIN' or s.name = 'Isolines' or s.name = 'GridOfCells' or s.name = 'AdjPolygons' or s.name = 'GridOfPoints' or s.name = 'IrregularPoints') -> isempty() self.base_class.getappliedstereotypes() -> select(s s.name = 'UnidirectionalArc' or s.name = 'BidirectionalArc') -> isempty() self.base_class.getappliedstereotypes() -> select(s s.name = 'BidirectionalArc') -> isempty() Restrições OCL para verificação da existência de estereótipos incompatíveis em uma mesma associação do esquema. F context Cross G context Disjoint H context In I context Overlap J context Touch self.base_association.getappliedstereotypes() -> select(s s.name = 'Disjoint' or s.name = 'In' or s.name = 'Overlap' or s.name = 'Touch') -> isempty() self.base_association.getappliedstereotypes() -> select(s s.name = 'Cross' or s.name = 'In' or s.name = 'Overlap' or s.name = 'Touch') -> isempty() self.base_association.getappliedstereotypes() -> select(s s.name = 'Disjoint' or s.name = 'Cross' or s.name = 'Overlap' or s.name = 'Touch') -> isempty() self.base_association.getappliedstereotypes() -> select(s s.name = 'Disjoint' or s.name = 'Cross' or s.name = 'In' or s.name = 'Touch') -> isempty() self.base_association.getappliedstereotypes() -> select(s s.name = 'Disjoint' or s.name = 'Cross' or s.name = 'In' or s.name = 'Overlap') -> isempty() Restrições OCL para validação das redes definidas no esquema. K context Network L context Network M context Arc not self.base_class.ownedattribute.association.memberend.class.getappliedstereotyp es() -> select(s s.name = 'Node') -> isempty() not self.base_class.ownedattribute.association.memberend.class.getappliedstereotypes() -> select(s s.name = 'UnidirectionalArc' or s.name = 'BidirectionalArc') -> isempty() not self.base_class.ownedattribute.association.memberend.class.getappliedstereotypes() -> select(s s.name = 'Node') -> isempty() 13
N context Node not self.base_class.ownedattribute.association.memberend.class.getappliedstereotypes() -> select(s s.name = 'UnidirectionalArc' or s.name = 'BidirectionalArc') -> isempty() Restrições OCL para validação de relacionamentos topológicos do tipo In e Disjoint. O context In P context Disjoint self.base_association.memberend.class -> forall (c c.getappliedstereotypes() - > select(s s.name = 'Point' or s.name = 'Line' or s.name = 'Polygon') -> notempty()) self.base_association.memberend.class -> forall (c c.getappliedstereotypes() - > select(s s.name = 'Point' or s.name = 'Line' or s.name = 'Polygon') -> notempty()) Restrições OCL para validação de relacionamentos topológicos do tipo Cross, Overlap e Touch. Q context Cross R context Overlap S context Touch let classes : OrderedSet(Class) = self.base_association.memberend.class -> asorderedset() in ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) let classes : OrderedSet(Class) = self.base_association.memberend.class -> asorderedset() in ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() ) let classes : OrderedSet(Class) = self.base_association.memberend.class -> asorderedset() in ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Point') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Polygon') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Point') -> notempty() ) or 14
((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Point') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() ) or ((classes -> at(1)).getappliedstereotypes() -> select(s s.name = 'Line') -> notempty() and (classes -> at(2)).getappliedstereotypes() -> select(s s.name = 'Point') -> notempty() ) Lembrando que as restrições OCL do GeoProfile validam apenas o esquema conceitual, é válido dizer que um relacionamento topológico modelado entre classes que possuem múltipla representação está conceitualmente correto se o tipo deste relacionamento topológico puder existir para pelo menos uma representação geográfica das classes envolvidas. Neste caso, cabe à aplicação restringir qual representação geográfica da classe estará envolvida no relacionamento escolhido. 4. Adicionando Ícones aos Estereótipos Ícones podem ser associados aos estereótipos para uma representação mais clara dos elementos do diagrama. Para associar um ícone a um estereótipo qualquer, clique com o botão direito no estereótipo ao qual se deseja aplicar o ícone na janela Outline. No menu, vá em Add an element e adicione o elemento Image no estereótipo. 15
Vamos colocar um ícone no estereótipo Point. Veja que o elemento Image irá aparecer dentro da aba deste estereótipo. Agora selecione o elemento Image adicionado, e na janela Properties na aba General escolha as propriedades da imagem, no campo Kind selecione Icon, agora no botão + Content selecione o ícone que você deseja adicionar no estereótipo. 16
Veja que o ícone adicionado irá aparecer na frente do campo Content. Agora você já pode adicionar os outros ícones dos demais estereótipos: Point, Line, Polygon, ComplexSpatialObj, TemporalObj, TIN, Isolines, GridOfCells, GridOfPoints, IrregularPoints, AdjPolygons, Node, UniderctionalArc, BidirectionalArc, Touch, In, Cross, Overlap, Disjoint e Network. 5. Aplicando o Perfil GeoProfile Com o perfil criado, podemos utilizá-lo em nossa modelagem de classes geográficas. Para utilizar nosso perfil, comece criando um novo modelo: File -> New -> Create an empty model. 17
Dê um nome ao modelo e selecione onde ele será criado: Selecione o modelo (ou Package) na janela Outline, então na janela Properties vá na aba Profile e clique no botão + Apply profile. 18
Na janela que se segue, selecione o perfil que deseja aplicar ao modelo, no caso GeoProfile. Agora, com o perfil aplicado, é possível aplicarmos os estereótipos do GeoProfile nos elementos UML. Para testar o GeoProfile, crie uma classe, tenha ela selecionada e clique no botão + (Add a new element) no campo Applied Stereotypes na aba Profile. 19
Na janela que se segue selecione o estereótipo que se deseja aplicar. Vamos selecionar os estereótipos Point e Polygon. Depois clique em OK. Obs: podemos aplicar mais de um estereótipo para uma mesma classe, as restrições OCL descritas anteriormente impedem que estereótipos incompatíveis sejam aplicados a uma mesma classe. 20
Como definido no perfil GeoProfile, estereótipos também podem ser aplicados a relacionamentos. Adicione mais uma classe com um estereótipo qualquer e um elemento Association entre elas. 21
Selecione o objeto Association adicionado e adicione um estereótipo ao mesmo, proceda da mesma forma como mostrado para objetos do tipo Class. A visualização dos estereótipos pode ser feita na forma escrita, através de ícones ou ambos. Para mudar a aparência do estereótipo selecione a classe a qual se deseja modificar, e na aba Appearance da janela Properties selecione o tipo de visualização no campo Stereotype Appearance. Mude para Icon e veja o resultado. 22
Há ocorrências de problemas na visualização de mais de um estereótipo por classe. Caso seja aplicado mais de um estereótipo a uma classe, só será visualizado o ícone do primeiro estereótipo aplicado. Para contornar esse problema, deve-se optar pela visualização dos estereótipos na forma textual ou textual e ícone. 23
Outro tipo de objeto geográfico que pode ser encontrado em nossas aplicações são os objetos temporais, definidos no GeoProfile como TemporalObj. Para este tipo de objeto foram definidos dois tagged values, temporaltype e temporalprimitive. Para definirmos seus valores, primeiro devemos adicionar uma classe no modelo com o estereótipo TemporalObj. O valor de cada tagged value para este tipo de objeto pode ser definido na aba Profile da janela Properties. Para isto, selecione o campo que se deseja alterar, um novo campo Property values irá aparecer com o valor pré-definido para esta tag. A ferramenta Papyrus considera o primeiro valor declarado como sendo o valor default. 24
Para alterar este valor, basta um duplo clique sobre o valor já existente, e uma nova janela se abrirá para a escolha do novo valor do campo. Por se tratar de uma ferramenta voltada para a criação de modelos utilizando a UML, outros elementos UML também podem ser adicionados ao modelo como pacotes, atributos, operações, tipos de dados, etc. Para adicionar novos elementos ao modelo, pode-se utilizar a aba Palette, ou com um clique do botão direito sobre o modelo na aba Outline, no menu, escolha Add an element e todos os elementos possíveis de serem adicionados no modelo serão mostrados. 25
Com isso, já é possível se criar um modelo UML completo para modelagem de banco de dados geográficos na ferramenta Papyrus utilizando o GeoProfile. Um exemplo Escola utilizando este perfil é mostrado abaixo. Perceba que a as classes Cidade, Bairro e Escola possuem estereótipos do tipo <<point>> e <<polygon>>, isso mostra como a classe poderá ser representada em uma aplicação geográfica. Bairro, por exemplo, pode ser representada como ponto ou 26
polígono, dependendo da escala. A classe Aluno, por sua vez, não possui estereótipo, por se tratar de uma classe sem representação geográfica, logo, será criada como um objeto Class comum, sem aplicar nenhum estereótipo. Note que também foram aplicados estereótipos aos relacionamentos. O estereótipo <<in>> entre Bairro e Cidade mostra que topologicamente todo elemento Bairro está dentro de um elemento Cidade, o mesmo vale para o relacionamento entre Escola e Bairro. Não existe relacionamento topológico entre Aluno e Escola, logo, utilizamos apenas um relacionamento do tipo Association comum, sem aplicar nenhum estereótipo. O próximo passo agora é validar nosso modelo utilizando as restrições OCL do perfil GeoProfile. Para isso, abra o arquivo Escola.uml que aparece na janela Navigator. Na janela que se abre, clique com o botão direito do mouse sobre o modelo <Model>Escola e vá em: Validation -> Validate OCL constraints defined in Stereotypes. Uma janela de confirmação de validação irá aparecer. Caso haja alguma inconsistência no modelo uma mensagem de erro será mostrada. Mais informações a respeito desta ferramenta podem ser encontradas no sítio: http://www.papyrusuml.org/home/index.htm 27