Sumário 1. IBM Rational Software Modeler... 1 2. Criando o Perfil GeoProfile... 2 3. Adicionando Restrições OCL... 9 4. Adicionando Ícones aos Estereótipos... 13 5. Aplicando o Perfil GeoProfile... 14 1. IBM Rational Software Modeler O Rational Software Modeler (RSM) é uma ferramenta CASE comercial que nos permite criar digramas e perfis UML; atualmente o RSM faz parte do Rational Software Architect que está sobre licença da IBM. Esta ferramenta apresentou-se como uma ótima alternativa para a especificação de perfis, oferecendo recursos como o suporte à linguagem OCL para definição de constraints, inclusão de ícones nos estereótipos e possibilidade de importação e exportação em vários formatos incluindo XMI (XML Metadata Interchange). Ambiente de trabalho do Rational Sofware Architect 1
Outra vantagem desta ferramenta é ser multilinguagem. Este tutorial foi feito utilizando-se a versão 8.0 da ferramenta com idioma Português. 2. Criando o Perfil GeoProfile A criação de perfis UML na ferramenta RSM é realizada de forma bastante intuitiva. Para criar um novo projeto de perfil, basta clicar em: Arquivo -> Novo -> Projeto -> Modelagem -> Extensibilidade da UML -> Projeto de Perfil UML. Uma janela é então aberta para definir o nome do projeto. Ao clicar em Avançar uma nova janela é aberta, como ilustrado na figura abaixo, para se adicionar o nome e outras propriedades do perfil. Escreva GeoProfile no campo Nome do Perfil. 2
Feito isso, basta clicar em Concluir e o projeto com o perfil será criado e estará disponível para manipulação no Explorador de Projeto da ferramenta. A seguir, devem ser adicionados os elementos da UML ao perfil. Para isso, basta selecionar o perfil no Explorador de Projetos e clicar com o botão direito do mouse nele e depois em Incluir Diagrama -> Diagrama de Classes. 3
Com o diagrama de classes criado, é possível adicionar, de forma visual, os elementos de extensão da UML ao perfil como, por exemplo, os estereótipos, metaclasses e tagged values. 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 Estereótipo, como mostrados na figura abaixo. Perceba que os estereótipos NetworkObj e Arc são abstratos. Para colocar um estereótipo como abstrato basta selecioná-lo no modelo e marcar a opção Resumo na aba inferior Geral. 4
Depois use o elemento Generalização, de forma a deixar o perfil como mostrado abaixo. O próximo passo é estender a metaclasse Class da UML utilizando os estereótipos criados, para isso adicione o elemento Metaclasse, 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 Extensão. 5
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 Estereótipo e dê a ele o nome Temporal. Agora inclua um elemento Metaclasse, mas desta vez selecione a metaclasse Association e então utilize o elemento Extensão para estender a metaclasse Association com o estereótipo criado, como mostra a figura abaixo. 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, referidas no perfil como tagged values, podem ser manipuladas no modelo. O próximo passo é criar o estereótipo TemporalObject, que se refere a objetos geográficos com aspectos temporais, e suas enumerações (tagged values). O GeoProfile define dois tipos de enumeração, TemporalPrimitive e TemporalType. Inclua no esquema dois elementos do tipo Enumeração e nomeie-os como TemporalPrimitive e TemporalType. 6
Adicione os Literais de Enumeração (instant e interval) em TemporalPrimitive e (valid_time, transaction_time e bitemporal) em TemporalType, veja figura abaixo. Agora, adicione ao esquema o estereótipo TemporalObj e inclua dois atributos com tipos das enumerações criadas anteriormente: temporalprimitive do tipo TemporalPrimitive e temporaltype do tipo TemporalType. 7
Para adicionar o tipo do atributo, basta selecioná-lo dentro do estereótipo ou na aba Explorador de Projetos, e na barra inferior Geral clique no botão Selecionar Tipo e selecione o tipo na janela que aparece, veja na figura abaixo. Basta agora estendermos a metaclasse Class novamente para o estereótipo criado; inclua mais um elemento Extensão 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 Estereótipos, 8
Generalizações e Extensões que faltam de forma a deixar o modelo como se segue. Depois salve o modelo. Estereótipos do GeoProfile 3. Adicionando Restrições OCL A ferramenta RSM 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 clique com o botão direito sobre o estereótipo ao qual se deseja aplicar a restrição e, no menu, escolha Incluir UML -> Restrição. 9
Na caixa de edição que aparece, adicione a restrição OCL referente ao estereótipo. A adição das constraints também pode ser feita pelo Explorador de Projeto. As propriedades de cada restrição podem ser manipuladas na aba inferior Geral, selecionando-se o objeto. No campo Nome digite o nome da restrição, e no campo Idioma e corpo correspondente digite OCL. Caso haja algum erro na validação da restrição, uma mensagem der erro será mostrada. 10
As restrições do GeoProfile serão descritas abaixo, adicione-as ao perfil criado. O campo context refere-se à 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 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 11
context Disjoint H context In I context Overlap J context Touch 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 N context Node 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() 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 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 12
S context Touch ((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 ((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, selecione o estereótipo no modelo, ou no Explorador de Projeto, e na aba Geral clique no botão Procurar no campo Ícone para adicionar um ícone ao estereótipo. 13
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. Depois da especificação de todos os elementos do GeoProfile, ele poderá, então, ser utilizado na modelagem de banco de dados geográficos. Os arquivos relacionados a perfis na ferramenta serão salvos utilizando a extensão.epx. 5. Aplicando o Perfil GeoProfile Com o perfil criado, podemos utilizá-lo em nossa modelagem de classes geográficas. Para utilizar o GeoProfile, comece criando um novo modelo: Arquivo -> Novo -> Projeto de Modelo. 14
Para aplicar o GeoProfile a um modelo, basta selecioná-lo e ir até a guia Propriedades, e na aba Perfil clicar em Incluir Perfil.... Depois, selecione o perfil no espaço de trabalho. Feito isso, os elementos adicionados ao modelo poderão fazer uso dos estereótipos e constraints do GeoProfile. Agora, com o perfil aplicado, é possível aplicarmos os estereótipos do GeoProfile nos elementos UML. Ao incluir uma classe no modelo, por exemplo, basta ir à guia 15
Propriedades, clicar em Estereótipos e depois em Aplicar Estereótipos.... Será aberta uma janela com todos os estereótipos disponíveis. Basta selecionar o estereótipo desejado e clicar em OK. O estereótipo será, então, aplicado à classe correspondente. 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. 16
Com o estereótipo aplicado à classe, é possível alterar algumas propriedades como, por exemplo, a forma de visualização do mesmo. A ferramenta disponibiliza algumas formas de visualização de estereótipos, a saber: Decoração e Texto, Decoração, Imagem da Forma, Texto e Nenhum. Para realizar isso, basta selecionar a classe, clicar com o botão direito do mouse nela e depois em: Filtros -> Estilo de Estereótipo e Visibilidade e depois selecionar a forma desejada. Obs: Há ocorrências de problemas na visualização de mais de um estereótipo por classe. Caso sejam aplicados 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. 17
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 Associação entre elas. Selecione o objeto Associação adicionado e adicione um estereótipo ao mesmo, proceda da mesma forma como mostrado para objetos do tipo Classe. 18
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 Estereótipos da janela Propriedades. A ferramenta RSM considera o primeiro valor declarado como sendo o valor default. 19
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 Paleta, ou com um clique do botão direito sobre o modelo no Explorador de Projeto, no menu, escolha Incluir UML e todos os elementos possíveis de serem adicionados no modelo serão mostrados. 20
Com isso, já é possível se criar um modelo UML completo para modelagem de banco de dados geográficos na ferramenta RSM 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 21
aplicação geográfica. Bairro, por exemplo, pode ser representada como ponto ou 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 Classe 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 Associação comum, sem aplicar nenhum estereótipo. O próximo passo agora é validar nosso modelo utilizando as restrições OCL do perfil GeoProfile. Para isso, clique com o botão direito sobre o modelo no Explorador de Projeto e no menu clique em Validar. Caso haja algum erro na validação, uma mensagem de erro irá aparecer na aba Problemas. Do contrário, a confirmação de validação aparecerá na aba Console. 22
A ferramenta RSM também permite a importação e exportação de modelos no formato XMI (XML Metadata Interchange) e outros formatos como Ecore, UML, etc. Para isso, vá ao menu: Arquivo -> Importar/Exportar. Para a opção Exportar, uma janela aparecerá mostrando os possíveis formatos para o qual o modelo pode ser exportado. 23
Mais informações a respeito desta ferramenta podem ser encontradas no sitio: http://www.ibm.com/developerworks/rational/products/rsm/ 24