SlideShare uma empresa Scribd logo
Revista programar 28
Editorial

EDITORIAL
  EQUIPA PROGRAMAR                                         FMI - Fim da Maravilhosa Internet?
                                    Coordenadores          Aconteceu. O ICANN (Internet Corporation for Assigned Names and
                                      António Silva        Numbers) distribuiu o último bloco de endereços IPV4 pelos 5 RIRs
                                  Fernando Martins         (Regional Internet Registries). Ou seja após esses endereços serem
                                                           atribuídos aos ISP, poderá estar em causa a aceitação de novos clientes por
                                              Editor       parte dos ISP e não haverá no IPV4 mais lugar a expansão. Ou haverá? O
                                       António Silva       facto é que a norma IPV6 já está preparada (foi descrito como um standard
                                                           da Internet num documento publicado em Dezembro de 2008), e já em
                                        Design             Agosto de 2008, na edição #1 5 da Revista PROGRAMAR, foi publicado um
                 Sérgio Alves (@scorpion_blood)            artigo que falava um pouco sobre esta nova norma. Contudo a verdade é
                                                           que parece não existir uma vontade comercial muito grande para adoptar
                                      Redacção             esta nova norma, porque é financeiramente desagradável, uma vez que é
      André Vala, Augusto Manzano, Fernando                necessário aos ISP fazerem a actualização do seu hardware de rede, aos
     Martins, Jorge Paulino, Pedro Silva, Pedro            programadores actualizarem as suas aplicações…
  Veloso, Ricardo Rodrigues, Ricardo Trindade,
                    Sara Silva, Virgílio Esteves           No dia 8 de Junho, algumas empresas do sector da Internet e não só
                                                           disponibilizarão durante 24 horas os seus serviços em IPV6, para o
                                         Staff             utilizador testar os seus serviços com esta nova norma e para pressionar
        António Santos, Fábio Domingos, Jorge              um pouco os ISP a fazerem a migração. Pode testar a sua ligação neste
                      Paulino, Marco Marques               site: http://test-ipv6.com/

                                    Contacto               Nos EUA existem já soluções que tentam contornar este problema, sem no
   revistaprogramar@portugal-a-programar.info              entanto ser necessário passar a usar o IPV6. Tecnicamente dois ou mais
                                                           clientes de um ISP estarão numa rede mais pequena (possivelmente
                                         Website           ligados pela central mais próxima), e existirá um router, e esse sim terá o
                http://www.revista-programar.info          verdadeiro endereço IP da internet, enquanto os PCs dos clientes têm
                                                           apenas endereços de redes internas. Na prática dois ou mais clientes
                                                ISSN       podem ter o mesmo IP ao mesmo tempo (algo idêntico ao que acontece nos
                                          1 647-071 0      hotspots). Mas não será isto simplesmente um remedeio? O ser humano
                                                           tem tendências para rejeitar mudanças, prolongando até ao limite em que já
                                                           não pode adiar mais essa mudança.

                                                           Um estudo mundial recente mostra que uma grande parte dos jovens dos
                                                           denominados países desenvolvidos está dependente de dispositivos com
                                                           acesso à Internet, sofrendo sintomas de abstinência comuns quando estão
                                                           afastados muito tempo desses dispositivos. Traduzindo não podem viver
                                                           sem a Internet. Mas e se os ISP não derem “o salto” para que a Internet
                                                           continue a existir como a conhecemos? E se os programadores não
                                                           adaptarem as suas aplicações a este salto? Poderá isto matar a Internet,
                                                           pelo facto de o utilizador deixar de confiar nela?

                                                           António Silva <antonio.silva@revista-programar.info>

A revista PROGRAMAR é um projecto voluntário, sem fins lucrativos. Todos os artigos são da responsabilidade dos autores, não podendo a revista ou a
comunidade ser responsabilizada por alguma imprecisão ou erro. Para qualquer dúvida ou esclarecimento poderá sempre contactar-nos.

                                                                         2
Índice

                                                                                        INDICE
 TEMA DE CAPA
             6    Business Connectivity Services



 A PROGRAMAR
             17   Lua – Linguagem de Programação (Parte 8)
             21   jQuery 1 .5 e AJAX
             27   Datagrid em Windows Presentation Foundation
             37   Planos de Execução em ORACLE
             47   Smarty PHP Template Engine



 COLUNAS
             48   CORE DUMP - O X No Quadrado Certo
             50   VISUAL (NOT) BASIC - Entity Framework 4.0: Model-First e Code-First



 COMUNIDADES
             58   AndroidIPC - Inter Process-Communication
             62   Automatização de deployments em Windows Azure




 EVENTOS
1 5 Abr.   SQL Saturday - Portugal 2011
1 5 Abr.   6º Encontro Nacional de Estudantes de Informática ENEI’2011
1 6 Abr.   SharePointPT - 1 0ª Reunião da SPUGPT
1 6 Abr.   1 9ª Reunião Presencial da Comunidade NetPonto - Lisboa
03 Mai.    Fim das Inscrições ONI'2011
06 Mai.    Microsoft WebCamp Portugal - Lisboa
06 Mai.    Prova de Qualificação na Internet ONI'2011
09 Mai.    CLOUD para DEVELOPERS
1 3 Mai.   StopNplay Lan Party 2011
27 Mai.    Final Nacional ONI'2011
Para mais informações/eventos: http://bit.ly/PAP_Eventos



                                                           3
NOTICIAS                                        Noticias



 R e s u l ta d o s s o b re o Pa n o ra m a                       La n ç a m e n to d o G N O M E 3 . 0
 N a c i o n a l Te c n o l ó gi c o
O Sapo Developers Blog fez recentemente um inquérito              O GNOME 3.0 é o principal marco na história do projeto
sobre um conjunto de questões sobre o Panorama Nacional           GNOME. O lançamento introduz um excitante novo
Tecnológico. Responderam 421 pessoas sendo a maioria              ambiente de trabalho que foi desenhado para utilizadores
dos inquiridos jovens com idades entre os 21 e os 35 anos.        comuns e adequado para uma grande quantidade de
Os resultado apresentados, revelam que os recursos online         modernos dispositivos computacionais. As tecnologias de
mais influentes são:                                              desenvolvimento do GNOME foram substancialmente
                                                                  melhoradas para o GNOME 3.0. Modernizadas e
  Portugal a Programar                                            padronizadas, elas irão permitir aos desenvolvedores
  Aberto até de Madrugada                                         promover melhorias na experiência do utilizador com
  SAPO Tek                                                        menos tempo e esforço. E o GNOME 3.0 vem com as
  Zwame                                                           mesmas aplicações GNOME que os utilizadores conhecem
  Planet Geek                                                     e confiam, muitos dos quais receberam melhorias
  Pplware                                                         significantes.
  Exame Informática
  SAPO Developers Blog                                            Mais info
   Globais: Engadget, Gizmodo, Mashable, ReadWriteWeb,
outras.
Mais info



 Le i d a s N o rm a s a b e rta s                                 Wi n d o ws 8 p o d e rá te r Ap p
 a p ro va d a n a AR                                              Sto re
Foi votada no Plenário da Assembleia da República a Lei           om a disponibilização da primeira versão do Windows 8
das Normas Abertas, uma proposta que já tinha passado na          para os RTM’s, começaram a surgir as primeiras imagens
especialidade e prevê a garantia de interoperabilidade e          do que será o novo sistema operativo da Microsoft. Estas
adopção de normas abertas nos sistemas informáticos do            imagens, não oficiais mostram um sistema operativo que
Estado.                                                           seguirá a continuidade do que o Windows 7 nos trouxe,
                                                                  mas também novidades que farão as delicias de todos os
Depois de já ter conseguido gerar consenso, e muitas              que o forem usar.
vezes unanimidade, na discussão na especialidade, a Lei           As últimas imagens que surgiram mostram que o Windows
foi aprovada com votos a favor do PEV, PCP, BE, CDS e             8 poderá ter uma store incorporada e onde os utilizadores
PS, abstendo-se o PSD.                                            poderão aceder às aplicações que pretenderem. Ainda não
                                                                  existem muitas informações sobre que software esta store
Bruno Dias, deputado do PCP, já tinha adiantado que "este         conterá e se apenas existirá software gratuito ou se existirá
foi um processo legislativo de enorme abertura e espírito         a possibilidade de os utilizadores adquirem aplicações.
construtivo de todas as partes. Não houve "ideias fixas"          O conceito de store dentro do sistema operativo não é
porque as opiniões que foram surgindo contribuíam para            novo, mas nos últimos tempos tem ganho uma importancia
aperfeiçoar o texto, e dessa maneira foram tidas em conta".       grande, com a disponibilização da Apple Store dentro do
                                                                  Mac OS e até com o Ubuntu Software Center.



                                                              4
TEMA DE CAPA
Business Connectivity Services
TEMA DE CAPA

B u s i n e s s C o n n e c ti vi ty S e rvi c e s
O SharePoint 201 0 é uma plataforma complexa e com um
impressionante conjunto de funcionalidades nativas que lhe          Arquitectura
permitem adaptar-se a uma enorme variedade de
situações. Uma das novas funcionalidades com mais                   A tecnologia BCS não se limita a apenas um serviço ou API
potencial designa-se Business Connectivity Services e este          dentro do SharePoint 201 0. É, na realidade, um conjunto de
artigo é uma introdução a esta tecnologia e às suas                 componentes, serviços e ferramentas tal como apresentado
potencialidades.                                                    no esquema abaixo.


O que são os Business Connectivity
Services e para que servem?
Business Connectivity Services (BCS) é o nome da
tecnologia integrada no SharePoint 201 0 que permite ler e
escrever informação em sistemas externos a partir do
SharePoint 201 0 e do Office 201 0. Trata-se de uma
evolução da tecnologia Business Data Catalog (BDC)                  Figura 1 - Arquitectura dos Business Connectivity Services
introduzida no SharePoint 2007, e sobre a qual foram feitas
várias melhorias, nomeadamente:
                                                                    Business Data Connectivity (BDC) Service
  • Possibilidade de leitura e escrita sobre a fonte de dados
externa;                                                            O Business Data Connectivity Service é uma das peças
  • Suporte para cenários de autenticação mais complexos;           mais importantes dos BCS. Trata-se do componente que
  • Suporte para múltiplas fontes de dados;                         permite, através do seu repositório central de
  • Integração com aplicações Office;                               metainformação, guardar as descrições da informação à
  • Novas e melhores formas de apresentar a informação;             qual se pretende aceder bem como do próprio sistema
   • Ferramentas destinadas à criação e manipulação dos             externo onde esta está armazenada.
modelos;
  • Extensibilidade através de assemblies .Net.
                                                                    Metadata Store
O objectivo desta tecnologia é permitir a integração de
informação proveniente de sistemas externos e apresentá-            O repositório de metainformação é a base de dados
la em SharePoint e aplicações Office com o mínimo de                utilizada pelo Business Data Connectivity Service para
esforço possível e, idealmente, sem ser necessário                  armazenar as descrições da informação e dos sistemas
escrever qualquer linha de código. Há, de facto, um                 externos onde esta está armazenada. Este repositório não
conjunto de cenários em que é possível a utilização da              contém qualquer informação proveniente dos sistemas
tecnologia BCS apenas por configuração mas é a sua                  externos, apenas a metainformação necessária para a
extensibilidade que lhe permite adequar-se a praticamente           obter.
qualquer necessidade de integração.



                                                                6
TEMA DE CAPA
                                                                                       B u s i n e s s C o n n e c ti vi ty S e rvi c e s


Connectors                                                        modo offline sejam replicadas assim que o sistema externo
                                                                  fica disponível.
Os connectors são as peças que permitem ao Business
Data Connectivity Service ligar-se às fontes de dados
externas descritas nos modelos armazenados no seu                 Principais Conceitos
Metadata Store. São fornecidos três conectores com o
produto:                                                          Uma vez conhecida a arquitectura dos Business
    • Database Connector – permite a ligação a bases de           Connectivity Services, é importante que se perceba em
dados SQL Server.                                                 que consiste a metainformação que é armazenada na
    • WCF/Web Services Connector – permite a ligação a            Metadata Store pelo Business Data Connectivity Service.
serviços WCF ou web services.
   • .Net Assembly Connector – permite a ligação utilizando
um assembly .Net desenvolvido à medida. Uma vez que se            Modelo
trata de um assembly desenvolvido à medida, este conector
permite a ligação a virtualmente qualquer fonte de dados          A metainformação utilizada pelo BDC Service e
externa, incluindo até a ligação a múltiplas fontes em            armazenada na Metadata Store materializa-se em ficheiros
simultâneo.                                                       XML que descrevem Modelos, normalmente designados
Este mecanismo de connectors é extensível, sendo ainda            por BDC Metadata Models. No SharePoint 2007, estes
possível desenvolver conectores à medida, para casos em           ficheiros de metainformação eram designados por
que os conectores existentes não são suficientes.                 application definition files.
                                                                  Um modelo contém, de forma declarativa, toda a
                                                                  informação necessária para que os BCS consigam ligar-se
BDC Client Runtime                                                a um sistema externo e obter a informação que se encontra
                                                                  armazenado no mesmo.
As aplicações cliente que fazem parte do Office 201 0
conseguem também expor informação proveniente de
sistemas externos através dos BCS. Isso é possível porque         Lob System
o Office 201 0 inclui o BDC Client Runtime, um componente
que faz no contexto da aplicação cliente o que o BDC              No contexto dos BCS, o Lob System (ou Line-of-Business
Service faz no contexto do                                        System) refere-se ao sistema externo no qual está
servidor SharePoint, ou seja, acede ao repositório de             armazenada a informação a que se pretende aceder. Este
metainformação e, através das definições que este contém,         sistema pode ser uma base de dados relacional, ou
acede à informação propriamente dita.                             qualquer outro sistema que exponha essa informação
                                                                  através de web services ou serviços WCF.

Client Data Cache
                                                                  External Content Type
No sentido de acelerar o acesso à informação, bem como
para suportar cenários de acesso offline à informação, os         O External Content Type (ECT) é o conceito central e mais
BCS utilizam uma cache para guardar a informação externa          importante dos BCS, uma vez que descreve uma entidade
obtida através dos mesmos. Esta cache é baseada numa              de negócio, ou seja, descreve a estrutura e comportamento
base de dados SQL Server 2005 Compact Edition e possui            da informação a que se pretende aceder. Exemplos de
um mecanismo de sincronização automático que permite              ECTs podem ser Cliente, Factura ou Colaborador.
que todas as alterações efectuadas sobre a informação em          Na definição de um ECT é especificada a estrutura e o

                                                              7
TEMA DE CAPA
B u s i n e s s C o n n e c ti vi ty S e rvi c e s


comportamento da entidade, ou seja:                                   a uma relação entre duas entidades (External Content
  • Os campos que constituem uma instância da entidade, e             Types). No entanto, uma vez que não há garantia que a
respectivo tipo de dados. Por exemplo: Nome, Morada ou                fonte de dados seja uma base de dados relacional, a
País.                                                                 associação requer a existência de métodos que permitam
   • O mapeamento destes campos para objectos utilizados              obter, a partir de uma entidade, elementos da entidade
pelas aplicações Office cliente. Por exemplo: o campo                 relacionada.
Nome da entidade corresponde ao campo FullName no
Outlook.
  • Os métodos que devem ser invocados pelos BCS para                 Exemplo de Modelo
ler, criar, actualizar e apagar instâncias da entidade. Estes
métodos pode corresponder, por exemplo, a stored                      Felizmente, na grande maioria dos casos, não precisamos
procedures, queries SQL ou web services.                              de editar o modelo manualmente já que as ferramentas
No contexto de um Modelo, podem ser definidas várias                  fornecidas pela Microsoft permitem fazer grande parte da
entidades, ou seja, vários External Content Types.                    configuração de forma visual. No entanto, apenas a título
                                                                      de exemplo, um ficheiro de modelo tem o aspecto
                                                                      apresentado abaixo.
Métodos
Os métodos são abstracções da API do sistema externo e
permitem ao BDC Service saber que stored procedures ou
web services devem ser chamados para manipular a
informação. A definição de um método é feita no contexto
de uma entidade e baseia-se sempre num dos estereótipos
disponibilizados pelos BCS. Existem cerca de 20
estereótipos possíveis, como sejam, Updater (para
actualizar um item), Finder (para listar itens), SpecificFinder
(para obter um item específico), Deleter (para apagar um
item) entre outros.
                                                                              Figura 2 - Exemplo parcial de modelo BDC

Filtros
Os filtros descrevem os parâmetros que podem ser                      Apresentar Informação Externa
passados para os métodos na definição de cada entidade.               Mas toda esta complexidade tem um objectivo – o de
Existem 1 8 tipos de filtros que podem ser utilizados nos             permitir apresentar e manipular a informação armazenada
métodos e que indicam ao BDC Service que informação                   em sistemas externos – por isso não faltam várias
deve ser passada para os mesmos. Exemplos de filtros são              alternativas para o fazer.
o UserName que permite passar o username do utilizador
em contexto, ou o Limit que define o número máximo de
itens a retornar numa chamada.                                        External List
                                                                      A External List é um novo tipo de lista no SharePoint 201 0
                                                                      que, através da associação a um External Content Type,
Associação                                                            permite visualizar e manipular a informação desse ECT
                                                                      como se esta estivesse armazenada numa lista de
Uma associação, designada por association, corresponde                SharePoint normal. Na realidade, a informação continua a

                                                                  8
TEMA DE CAPA
                                                                                          B u s i n e s s C o n n e c ti vi ty S e rvi c e s


residir no sistema externo e é lida e manipulada em tempo           funcionamento é semelhante ao de uma coluna lookup,
real.                                                               permitindo ao utilizador seleccionar um dos itens
                                                                    retornados pelo ECT.




                                                                                  Figura 4 - External Data Column

                                                                    Uma das vantagens das External Data Columns é a
                                                                    possibilidade de serem utilizadas também pelo Word 201 0,
                                                                    permitindo ao utilizador seleccionar um item exposto
                                                                    através de BCS e utilizando essa informação nos
                   Figura 3 - External List                         documentos.
                                                                    Tal como para as External Lists, para utilizar um ECT numa
A grande vantagem das External Lists é que se parecem e             External Data Column este tem que definir, pelo menos, os
comportam exactamente como listas normais e,                        métodos Finder e SpecificFinder.
adicionalmente, o object model do SharePoint trata-as
como se assim fossem, permitindo aos developers ler e
escrever itens como se estes estivessem armazenados no              Business Data Web Parts
próprio SharePoint.
Por outro lado, nem tudo funciona exactamente como nas              As Business Data Web Parts são, como o nome indica, um
listas tradicionais. Em particular:                                 conjunto de web parts que conseguem ligar-se a fontes de
   • Workflows                                                      dados externas através de um ECT e apresentar essa
   • Alertas                                                        informação no SharePoint. Estas web parts também já
   • Pastas (folders)                                               existiam no SharePoint 2007 mas foram melhoradas no
   • Anexos (attachments)                                           SharePoint 201 0, nomeadamente permitindo fazer cache
   • Feeds RSS                                                      da informação externa para melhorar o desempenho.
   • Exportação para Excel
Para que um ECT possa ser utilizado numa External List
este tem que definir, pelo menos, os métodos Finder (listar
itens) e SpecificFinder (obter um item específico). Isto
permitirá à External List apresentar a lista de itens e ver o
detalhe de cada um. Adicionalmente, se o ECT possuir
métodos Updater (actualizar um item), Deleter (eliminar um
item) e Creator (criar um novo item), a External List                           Figura 5 - Business Data Web Parts
disponibilizará as acções correspondentes.
                                                                    As Business Data Web Parts utilizam XSLT para apresentar
                                                                    a informação, o que lhes dá uma enorme flexibilidade no
External Data Column                                                que respeita ao seu aspecto gráfico bem como a
                                                                    possibilidade de edição através do SharePoint Designer
A External Data Column já existia no SharePoint 2007 e,             201 0.
embora tenha sido ligeiramente melhorada no SharePoint              As web parts incluídas neste pacote são:
201 0, o seu objectivo é o mesmo – permitir utilizar                  • Business Data List – permite listar instâncias (itens) de
informação externa numa coluna de uma lista. O                      uma entidade (ECT).

                                                                9
TEMA DE CAPA
B u s i n e s s C o n n e c ti vi ty S e rvi c e s


    • Business Data Item – permite apresentar o detalhe de          Administration, acedendo à gestão do Business Data
uma instância (item) de uma entidade (ECT).                         Connectivity Service. A única informação que precisamos
  • Business Data Item Builder – permite utilizar parâmetros        de fornecer é o endereço URL do site onde estas páginas
da query string para criar uma instância (item) de uma              serão automaticamente criadas e o SharePoint fará o resto
entidade (ECT) que pode depois ser utilizada para                   por nós.
alimentar outras web parts, nomeadamente a Business                 Neste ponto, basta-nos apenas dizer ao Search Service
Data Item web part.                                                 que deve indexar uma nova Content Source do tipo Line of
   • Business Data Related List – permite listar instâncias         Business Data e efectuar um Full Crawl. Após a conclusão
(itens) de uma entidade (ECT) relacionada. É                        do crawl a informação externa passa a estar disponível
especialmente útil para apresentar informação em cenários           para ser pesquisada e a informação de cada item será
de Master/Detail.                                                   apresentada na respectiva Profile Page.
    • Business Data Connectivity Filter – permite filtrar a
informação proveniente de um ECT antes que seja
consumida por outra web part, como a Business Data List             User Profiles
web part.
      • Business Data Actions – apresenta as acções                 Utilizando os BCS, o SharePoint 201 0 consegue utilizar
disponíveis para uma instância (item) de uma entidade               fontes de dados externas para complementar a informação
(ECT).                                                              dos User Profiles. Para isso basta que seja possível
                                                                    mapear User Profiles com itens de um ECT, utilizando um
                                                                    campo de cada lado.
Pesquisa                                                            Não é possível configurar um ECT como fonte principal
                                                                    para a sincronização de perfis, mas é possível que uma
Um dos maiores benefícios oferecidos pelos BCS é a                  sincronização com Active Directory seja complementada
possibilidade de indexar e realizar pesquisas sobre a               com informação proveniente de um ECT.
informação externa exposta através dos ECTs como se se
tratasse de informação armazenada em listas no                      Integração com Office Client
SharePoint.
Para que um ECT seja indexável é necessário que defina,             A integração da informação externa nas aplicações do
pelo menos, os métodos IDEnumerator e SpecificFinder. O             Office 201 0 é outra das novidades do SharePoint 201 0
primeiro permitirá ao SharePoint obter os IDs de todos os           relacionada com os Business Connectivity Services. Até
itens e o segundo obter o detalhe de cada um.                       agora, este tipo de funcionalidade só era possível com
Adicionalmente, o modelo tem que ter a propriedade                  desenvolvimentos à medida de razoável complexidade.
ShowInSearchUI para que o SharePoint o consiga indexar.             Com os BCS é possível apresentar a informação externa
Mas isto é para que a informação seja indexada. Para que,           nas aplicações Office, utilizá-la em cenários offline e, em
ao realizar uma pesquisa, o utilizador consiga clicar sobre         determinados casos, actualizar a informação directamente
um dos resultados e visualizar informação detalhada sobre           na fonte de dados externa. Contudo, nem todas as
o resultado que seleccionou, precisamos também de                   aplicações incluídas no Office 201 0 suportam esta
configurar a Profile Page de cada ECT indexado.                     integração nativamente. De momento apenas o Outlook
Uma Profile Page não é mais que uma página em                       201 0, o Word 201 0, o Access 201 0, o InfoPath 201 0 e o
SharePoint com algumas web parts que recebe o                       SharePoint Workspace 201 0 conseguem fazê-lo, sendo que
identificador de um item na query string e apresenta                cada uma das aplicações utiliza esta tecnologia de forma
informação detalhada sobre esse item, incluíndo itens de            diferente.
ECT relacionados (através de Associations).
As Profile Pages são configuradas na Central

                                                               10
TEMA DE CAPA
                                                                                           B u s i n e s s C o n n e c ti vi ty S e rvi c e s


Outlook 201 0                                                          Figura 6 - Informação adicional (não mapeada) do ECT

O Outlook 201 0 é uma das aplicações que tira melhor                 Tal com as restantes aplicações Office, o Outlook tira
partido das funcionalidades cliente dos BCS. Para que seja           partido de um mecanismo de cache e sincronização da
possível visualizar a informação exposta através de um               informação permitindo ao utilizador trabalhar sobre esta em
ECT no Outlook 201 0 são necessários dois passos na                  offline e sincronizando-a automaticamente assim que o
configuração desse ECT:                                              acesso ao sistema externo fica disponível.
   1 . Definir qual o tipo de informação exposto pelo ECT, de
entre os tipos de informação manipulados pelo Outlook:
Contactos (Contacts), Tarefas (Tasks), Eventos                       Word 201 0
(Appointments) ou Artigos (Posts). Esta configuração pode
ser feita através do SharePoint Designer ou directamente             O Word 201 0 é outras das aplicações Office que tem
no XML do Modelo.                                                    suporte nativo para os BCS. No entanto, os cenários para
  2. Mapear os campos do ECT com os campos do Outlook                aplicação desta tecnologia são diferentes dos disponíveis
para esse tipo de informação. Por exemplo, indicar quais os          para Outlook. A utilização dos BCS em Word 201 0 limita-se
campos do ECT que correspondem aos campos Last                       à inserção de informação proveniente de fontes de dados
Name, First Name, E-mail Address e outros, no Outlook.               externas em documentos através de Quick Parts.
Existindo uma External List que exponha a informação do              Para quem não conhece, as Quick Parts são uma
                 ECT, passa a ser possível utilizar o botão          funcionalidade do Word que permite criar campos para
                 Connect to Outlook disponibilizado pela             preenchimento dinâmico da informação no meio do texto de
                 ribbon da lista. Ao pressionar o botão, o           um documento. Estes campos podem depois ser
                 SharePoint vai analisar a especificação do          preenchidos automaticamente com informação proveniente
ECT e vai incluí-lo num pacote de instalação Click Once              do content type do documento, no SharePoint. Isto inclui
que é imediatamente instalado no Outlook 201 0 do                    informação proveniente de uma External Data Column
utilizador como um Add-In.                                           existente na Biblioteca de Documentos em que o
Uma vez instalado o pacote, a lista aparece na interface do          documento está armazenado.
Outlook permitindo ao utilizador interagir com a informação          O funcionamento é simples:
externa como se fossem contactos, tarefas, eventos ou                   1 . Numa Biblioteca de Documentos, cria-se uma External
artigos normais. Caso o ECT defina os métodos                        Data Column configurando-a para expor a informação de
necessários, é ainda possível utilizar o Outlook para                um determinado ECT e definindo os campos do ECT que
actualizar a informação da fonte de dados externa. Todos             são expostos.
os campos expostos pelo ECT que não estejam mapeados                        2. Cria-se um novo documento nessa biblioteca,
em campos do objecto Outlook, são mostrados numa                     utilizando o botão New da ribbon.
secção própria do detalhe desse objecto e podem também                   3. Já no Word, através da ribbon Insert, inserimos uma
ser actualizados.                                                    (ou mais) Quick Part, seleccionando a(s) Document
                                                                     Property(s) que corresponde(m) à informação externa que
                                                                     queremos incluir no documento.




                                                                11
TEMA DE CAPA
B u s i n e s s C o n n e c ti vi ty S e rvi c e s


        Figura 7 - Quick Parts com informação externa
                                                                     SharePoint Workspace 201 0
    4. O Word passa então a permitir que o utilizador
seleccione um item do ECT, utilizando o Entity Data Picker,          O SharePoint Workspace 201 0 é a evolução do Groove
e popula automaticamente todos os campos relacionados.                                        2007 e posiciona-se como a
                                                                                              ferramenta de acesso offline à
                                                                                              informação guardada em SharePoint
                                                                                              201 0, incluindo External Lists. Tal
                                                                                              como para os restantes tipos de
                                                                     listas, basta clicar no botão Sync to SharePoint Workspace
                                                                     para que o conteúdo das mesmas seja descarregado para
                                                                     a máquina do utilizador ficando disponível quando este está
                                                                     desligado do servidor.
                                                                     No que respeita aos BCS, o que o SharePoint Workspace
                                                                     faz é descarregar a definição do ECT associado à External
                                                                     List e armazená-la localmente, bem como os forms de
                                                                     inserção, edição e consulta da informação que foram
                   Figura 8 - External Data Picker                   gerados para essa External List. Tal como as restantes
                                                                     aplicações Office descritas, o SharePoint Workspace utiliza
                                                                     a cache local para garantir a disponibilização da informação
Access 201 0                                                         externa quando o sistema externo não está disponível.

O Access 201 0 consegue importar um modelo Business
Data Connectivity (BDC) e apresentar a informação externa            Soluções e Ferramentas
sob a forma de tabelas. No entanto, as tabelas criadas são
read-only, ou seja, não é possível escrever de volta para a          Uma das grandes queixas de quem utilizou o Business
fonte de dados externa.                                              Data Catalog no SharePoint 2007, foi a falta de ferramentas
                                                                     que permitissem uma boa experiência na criação e
                                                                     manipulação da metainformação (modelos). A Microsoft
InfoPath 201 0                                                       ouviu essas queixas e brindou-nos com duas ferramentas
                                                                     fantásticas para utilizar com os Business Connectivity
Quando é criada uma External List, são também gerados                Services:
forms para inserção, edição e consulta da informação                   • SharePoint Designer 201 0
externa. Por omissão, estes forms são gerados como                     • Visual Studio 201 0
páginas ASP.NET normais mas, utilizando o SharePoint
Designer ou a ribbon da External List, é possível criar forms
mais inteligentes utilizando InfoPath. Os forms são gerados          SharePoint Designer 201 0
automaticamente, mas podem depois ser modificados
utilizando o InfoPath.                                               O SharePoint Designer 201 0 é uma ferramenta gratuita e
É ainda possível arrastar um External Data Picker para um            obrigatória para qualquer utilizador avançado ou developer
formulário InfoPath e definir uma External List como fonte           de SharePoint. Possui um enorme número de
de informação, permitindo a leitura e escrita de informação          funcionalidades focando-se principalmente na criação de
proveniente de fontes de dados externas.                             soluções sem código, ou seja, soluções de customização


                                                                12
TEMA DE CAPA
                                                                                        B u s i n e s s C o n n e c ti vi ty S e rvi c e s


do SharePoint sem necessidade de desenvolvimentos à
medida.




                                                                   Figura 1 0 - Editor visual de Modelos BDC no Visual Studio
                                                                                                201 0
  Figura 9 - Utilização do SharePoint Designer para gerir
                            ECTs
                                                                  Alguns dos casos de uso possibilitados pelo Visual Studio
                                                                  201 0 são:
No que respeita aos Business Connectivity Services, o
                                                                     • Criar e manipular External Content Types, utilizando o
SharePoint Designer 201 0 permite:
                                                                  novo template de projecto Business Data Connectivity
    • Criar e manipular External Content Types, incluindo
                                                                  Model. Este template inclui um conjunto de designers que
alterar configurações, criar novos métodos e mapear ECTs
                                                                  permite a edição visual do Modelo e respectivos ECTs, e
com objectos Office. Na criação de ECTs apenas é possível
                                                                  possibilita ainda o desenvolvimento de soluções utilizando
efectuar ligações a bases de dados SQL Server, Web
                                                                  código .Net para acesso a virtualmente qualquer fonte de
Services cujos schemas sejam suportados pelos BCS ou
                                                                  dados externa.
assemblies .Net existentes.
                                                                    • Criar componentes reutilizáveis para os BCS utilizando
   • Criar e configurar External Lists com base em ECTs já
                                                                  os vários pontos de extensibilidade da API dos BCS, como
criados.
                                                                  sejam Code Actions que podem ser utilizadas dentro do
     • Gerar e editar formulários InfoPath de suporte às
                                                                  Outlook, External Data Parts para utilização em task panes
External Lists.
                                                                  declarativas no Outlook, actividades para workflows e
  • Utilizar informação externa em workflows.
                                                                  outros.
  • Criar web part pages e profile pages
                                                                    • Criar Add-Ins para aplicações Office com suporte para
Estas funcionalidades permitem a utilização dos BCS sem
                                                                  BCS, utilizando o object model dos BCS.
qualquer desenvolvimento à medida e adaptam-se às
                                                                      • Criar workflows à medida que tiram partido de
necessidades mais simples e comuns.
                                                                  informação em External Lists ou utilizam o object model dos
                                                                  BCS.
Visual Studio 201 0
                                                                  Tipos de Solução por Ferramenta
Com o Visual Studio 201 0 podemos criar soluções mais
complexas para casos em que as funcionalidades do
                                                                  A tabela na página seguinte ajuda a seleccionar a
SharePoint Designer 201 0 não são suficientes.
                                                                  ferramenta ideal para cada necessidade.
Adicionalmente, com o Visual Studio 201 0 podemos criar
componentes reutilizáveis que depois poderão ser
incorporados em soluções através do SharePoint Designer.



                                                             13
TEMA DE CAPA
B u s i n e s s C o n n e c ti vi ty S e rvi c e s


                                                                  dados adicional para a sincronização de perfis do
                                                                  SharePoint.

                                                                        • Necessidade de sincronizar contactos que estão
                                                                  armazenados num sistema de negócio ou ERP. Utilizando
                                                                  os BCS é possível definir um ECT que expõe esses
                                                                  contactos através de uma External List e ligá-la ao Outlook
                                                                  onde serão geridos como contactos normais. Este cenário
                                                                  permite ainda que os utilizadores tenham acesso aos
                                                                  contactos mesmo quando estão fora do escritório, em modo
                                                                  offline.

Casos de Uso                                                         • Necessidade de apresentar informação proveniente de
                                                                  fontes de dados distintas. Utilizando o conector para
Uma das perguntas mais frequentes relacionadas com a              assemblies .Net e desenvolvendo um ECT com o Visual
utilização de Business Connectivity Services é quais os           Studio 201 0, podemos construir cenários de acesso a
casos de uso desta tecnologia ou, de outra maneira,               múltiplas fontes de dados com agregação dos mesmos
quando devo utilizar os BCS.                                      numa única entidade.
Alguns dos casos de uso mais comuns para a utilização de
BCS são:                                                              • Necessidade de indexar e pesquisar informação
                                                                  residente num sistema de negócio ou ERP. Os BCS
  • Necessidade de apresentar informação de uma base de           permitem ao serviço de pesquisa do SharePoint indexar
dados SQL Server. Utilizando BCS é possível apresentar e,         conteúdos expostos através de ECTs e pesquisá-los como
caso seja necessário, modificar a informação utilizando           se a informação estive armazenada no SharePoint.
External Lists sem ser preciso desenvolver uma única linha        Há muitos outros cenários onde os BCS podem ser úteis,
de código à medida. É um back-office instantâneo.                 por vezes apenas como um dos componentes da solução.

     • Necessidade de complementar os User Profiles dos
utilizadores do domínio com informação proveniente do             Funcionalidades por Versão do SharePoint
sistema de gestão de Recursos Humanos ou ERP. Tal
como já foi falado, os BCS permitem responder a este              A infraestrutura utilizada pelos Business Connectivity
requisito permitindo configurar um ECT como fonte de              Services está disponível em todas as versões do




                                                             14
TEMA DE CAPA
                                                                                          B u s i n e s s C o n n e c ti vi ty S e rvi c e s


SharePoint, incluíndo o SharePoint Foundation 201 0. No
entanto, nem tudo vem incluído na versão gratuita. A tabela         Connecting to a .NET Framework Source Using Business
abaixo ajuda a clarificar quais as funcionalidades que estão        Connectivity Services in Office 201 0
incluídas em cada uma das versões do SharePoint 201 0.              Visual How To sobre como desenvolver um ECT usando
                                                                    Visual Studio 201 0 para obter dados de uma fonte externa.
O suporte para Business Connectivity Services em                    http://msdn.microsoft.com/en-
aplicações Office requer o Microsoft Office 201 0                   us/library/ff394331 (office.1 4).aspx
Professional Plus, ou superior.
                                                                    Microsoft Business Connectivity Services
                                                                    Secção do SDK do SharePoint 201 0 dedicada aos
Links Úteis                                                         Business Connectivity Services.
Aqui ficam alguns links úteis para quem está agora a                http://msdn.microsoft.com/en-us/library/ee556826.aspx
começar e quer saber mais sobre Business Connectivity
Services.                                                           Business Connectivity Services Resource Center
                                                                    Resource Center dedicado aos Business Connectivity
Microsoft Business Connectivity Services Team Blog                  Services, no TechNet.
O blog official da equipa que desenvolveu os BCS, com               http://technet.microsoft.com/en-
imensos artigos com vários níveis de complexidade.                  us/sharepoint/ee51 8675.aspx
Obrigatório para todos os interessados nesta tecnologia.
http://blogs.msdn.com/b/bcs/                                        Business Connectivity Services: Technical Articles
                                                                    Artigos técnicos da MSDN relacionados com Business
BCS Team Channel                                                    Connectivity Services.
O canal no YouTube onde alguns vídeos foram publicados              http://msdn.microsoft.com/en-us/library/gg481 768.aspx
pela equipa de produto.
http://www.youtube.com/user/MOSSBCSTeam




                                                                    Link para o artigo: http://tinyurl.com/RPED28-04

 AUTOR

                    Escrito por André Vala
                    Licenciado e Mestre em Engenharia Informática e de Computadores pelo Instituto Superior Técnico, é
                    actualmente consultor sénior na |create|it| e co-fundador da Comunidade Portuguesa de SharePoint .
                    Autor do blog http://blogit.create.pt/blogs/andrevala, trabalha com SharePoint desde 2006, altura em que
                    surgiu a primeira versão beta do SharePoint 2007.
                    Tem participado em vários projectos nacionais e internacionais sobre SharePoint, e participa
                    frequentemente como orador em eventos da Microsoft relacionados com o mesmo tema.




                                                               15
A PROGRAMAR
Lua – Linguagem de Programação (Parte 8)
jQuery 1.5 e Ajax
Datagrid em Windows Presentation Foundation
Planos de Execução em ORACLE
Smarty PHP Template Engine
A PROGRAMAR

Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 )
Este artigo trata o uso de operações de aleatoriedade e a            valor estabelecido junto a parâmetro “n” e pode ainda ser
manipulação de cadeias (operações de detecção de                     usada com os parâmetros “n” e “m” para gerar valores
tamanho de cadeias – revisão, repetição de caracteres,               inteiros entre “n” e “m”.
separação de cadeias, busca e substituição de caracteres,            O programa seguinte efectua a acção de geração de
conversão em modo ASCII).                                            valores aleatórios da forma mais simples possível.

                                                                      -- inicio do programa ALEAT01
ERRATA
                                                                         math.randomseed(0)
Por falha pessoal no artigo anterior (Parte 7) ficou indicado
após a conclusão que esta parte trataria do tema: arquivo.               local function SORTEIO()
No entanto, este assunto fora apresentado na sexta parte                   N = math.random()
desta série de artigos.                                                    return N
                                                                         end


ALEATORIEDADE                                                            for I = 1, 5 do
                                                                           X = SORTEIO()
É sabido que aleatoriedade é a característica do que é                     print(X)
indeterminado ou incerto. Uma das possibilidades                         end
operativas de uma linguagem de programação é a
capacidade de “gerar” valores numéricos aleatórios. O                 -- fim do programa ALEAT01
termo: gerar é grafado entre aspas devido a característica
que os computadores possuem de fazer este trabalho de                Em seguida escreva o código de programa em um editor de
uma forma considerada não real, ou seja, por meio de uma             texto, gravando-o com o nome aleat01 .lua e execute-o com
acção considerada pseudo-aleatória.                                  a linha de comando lua 5.1 aleat01 .lua.
Para esta acção em linguagem Lua há as funções de                    A função math.randomseed() necessita ser usada a frente
geração de números aleatórios: math.randomseed() e                   da função math.random() para que math.random() consiga
math.rendom().                                                       gerar os valores aleatórios.
Os valores gerados por estas funções são valores pseudo-             Ao executar o programa várias vezes os valores
aleatórios, e necessitam ser usados com alguma cautela,              apresentados como saída sempre serão:
tanto que há no manual de referência da linguagem Lua a
advertência: Nenhuma garantia pode ser dada para suas                0.0011 597033600879
propriedades estatísticas.                                           0.23557237464522
A função math.randomseed(n) faz uso do valor “n” como                0.6481 521 04251 23
parâmetro de semente para a geração de valores                       0.074373607593005
aleatórios.                                                          0.270241 401 40996
A função math.random([n[,m]]) pode ser usada de três
formas diferentes: usada sem parâmetros o que fará a                 Os valores se repetem pelo fato de estar sendo utilizado o
geração de valores entre 0 e 1 , pode ser usada apenas               valor de semente “0” (zero). Se o valor de semente for
com o parâmetro “n” para gerar valores inteiros entre 1 e o          mudado para 1 , 2, 3 ou outro valor qualquer serão


                                                                17
A PROGRAMAR
Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 )


conseguidos valores diferentes. No entanto para um                Observe que uso da função os.time() como valor semente
mesmo valor de semente para mais de uma execução ter-             permite um comportamento de aleatoriedade mais
se-á a apresentação dos mesmos valores. Uma forma de              convincente.
mudar um pouco este comportamento é fazer uso da                  Agora imagine que se queira sortear valores numéricos
função os.time() como valor de semente. A função os.time()        entre 1 e 5. Assim sendo, observe o código seguinte:
retorna o valor do tempo corrente. Assim sendo, observe o
código de programa seguinte:                                       -- inicio do programa ALEAT03

 -- inicio do programa ALEAT02                                        math.randomseed(os.time())

    math.randomseed(os.time())                                        local function SORTEIO()
                                                                        N = math.random(1,5)
    local function SORTEIO()                                            return N
       N = math.random()                                              end
       return N
    end                                                               for I = 1, 5 do
                                                                        X = SORTEIO()
    for I = 1, 5 do                                                     print(X)
       X = SORTEIO()                                                  end
       print(X)
    end                                                            -- fim do programa ALEAT03

 -- fim do programa ALEAT02
                                                                  Em seguida escreva o código de programa em um editor de
Em seguida escreva o código de programa em um editor de           texto, gravando-o com o nome aleat03.lua e execute-o com
texto, gravando-o com o nome aleat02.lua e execute-o com          a linha de comando lua 5.1 aleat03.lua.
a linha de comando lua 5.1 aleat02.lua.                           Execute o programa algumas vezes. Note que o primeiro
Ao se executar o programa várias vezes notar-se-á que os          valor é sempre o mesmo em toda a execução, somente os
resultados apresentados são levemente diferentes. Por             demais valores são apresentados diferentemente. Este é
exemplo, a seguir apresenta-se os valores de saída de             um comportamento operativo da linguagem Lua que gera
duas execuções sequenciais do programa:                           dúvidas nos iniciantes no uso desta linguagem. Não se
                                                                  preocupe em seguida será mostrado como contornar este
0.85509811 700797                                                 tipo de ocorrência.
0.76201 66631 061 7                                               Observe que para gerar valores entre 1 e 5 fora usado: N =
0.21 799371 31 8705                                               math.random(1 ,5).
0.1 767021 6986602                                                O próximo programa mostra como contornar o problema de
0.249671 9260231 3                                                repetição do primeiro valor da sequência sorteada.

                                                                   -- inicio do programa ALEAT04
0.85558641 31 5958
0.402081 36234626
                                                                      math.randomseed(os.time())
0.943876461 07364
                                                                      math.random()
0.84850611 89611 5
0.82357249671 926
                                                                      local function SORTEIO()



                                                             18
A PROGRAMAR
                                                                         Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 )


                                                                  Nas operações de manipulação de cadeias há ainda a
      N = math.random(1,5)                                        possibilidade de separar partes de uma cadeia. Para este
      return N                                                    efeito faz-se uso da função string.sub(texto, início, [fim]),
    end                                                           onde texto é a indicação da cadeia que será separada,
                                                                  início é a indicação da posição de separação inicial que
    for I = 1, 5 do                                               pode ser positiva ou negativa e fim - indicação opcional da
      X = SORTEIO()                                               posição final de separação.
      print(X)                                                    Em seguida escreva o código de programa em um editor de
    end                                                           texto, gravando-o com o nome cadeia02.lua e execute-o
                                                                  com a linha de comando lua 5.1 cadeia02.lua.
 -- fim do programa ALEAT04

                                                                   -- inicio do programa CADEIA02
Em seguida escreva o código de programa em um editor de
texto, gravando-o com o nome aleat04.lua e execute-o com               X = "COMPUTADOR"
a linha de comando lua 5.1 aleat04.lua.
Execute o programa algumas vezes e note a diferença                    print(string.sub(X))
nesta versão. Observe o uso da função math.random() logo               print(string.sub(X, 1))
após o uso da função math.randomseed(os.time()). Este                  print(string.sub(X, 1, 3))
pequeno ajuste faz o acerto desejado.                                  print(string.sub(X, 4, 5))
                                                                       print(string.sub(X, 6, 7))
                                                                       print(string.sub(X, 8))
MAIS MANIPULAÇÃO DE CADEIAS                                            print(string.sub(X, -5))


No sexto artigo desta série fora apresentada uma forma de          -- fim do programa CADEIA02
detecção da quantidade de caracteres de uma cadeia com
o uso do operador # por meio da instrução de código               Após a execução serão apresentados os textos
print(#"Linguagem Lua") que mostra como resultado o valor         COMPUTADOR, COM, PU, TA, DOR e TADOR.
1 3.                                                              Outro factor de manipulação de cadeias de caracteres é a
Esta mesma acção pode ser efectuada por meio da função            realização de operações de substituição de caracteres de
string.len(texto) como apresentado no quinto artigo desta         uma cadeia. Para tanto, use a função de substituição
série, onde texto é a indicação da cadeia que terá contada        string.gsub(texto, busca, troca, vezes), onde texto é a
a quantidade de caracteres.                                       cadeia de texto definida, busca é o carácter a ser
Em seguida escreva o código de programa em um editor de           localizado, troca é o carácter que será substituído e vezes
texto, gravando-o com o nome cadeia01 .lua e execute-o            indica o número máximo de substituições a serem
com a linha de comando lua 5.1 cadeia01 .lua.                     efectuadas, sendo este último argumento opcional.
                                                                  Em seguida escreva o código de programa em um editor de
 -- inicio do programa CADEIA01                                   texto, gravando-o com o nome cadeia03.lua e execute-o
                                                                  com a linha de comando lua 5.1 cadeia03.lua.
     X = "Linguagem Lua"
                                                                   -- inicio do programa CADEIA03
     print(string.len(X))
                                                                       X = "A BOLA AZUL APARECEU"
                                                                       print(string.gsub(X,"A","4"))
 -- fim do programa CADEIA01
                                                                       print(string.gsub(X,"A","X",2))
                                                                   -- fim do programa CADEIA03


                                                             19
A PROGRAMAR
Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 )


Observe que após a execução, o programa mostra além da
troca realizada o número de trocas realizadas.                             print(string.byte(X, -5))

Outra acção para manipulação de cadeias é a função
string.rep(texto, vezes), onde texto é a cadeia a ser                  -- fim do programa CADEIA05

repetida e vezes é a definição do número de repetições.
Em seguida escreva o código de programa em um editor de               O programa apresenta os valores:
texto, gravando-o com o nome cadeia04.lua e execute-o                  - 65
com a linha de comando lua 5.1 cadeia04.lua.                           - 65 66 67
                                                                       - 68 69
 -- inicio do programa CADEIA04                                        - 65 66 67 68 69 70
                                                                       - 66
     X = "OBA "                                                       A acção inversa é conseguida com o uso da função
     print(string.rep(X,2))                                           string.char(código1 , código2, …, códigoN), onde cada
                                                                      argumento usado é um valor ASCII.
 -- fim do programa CADEIA04                                          Em seguida escreva o código de programa em um editor de
                                                                      texto, gravando-o com o nome cadeia06.lua e execute-o
Outro efeito com cadeias é a obtenção do código ASCII dos             com a linha de comando lua 5.1 cadeia06.lua.
caracteres que formam a cadeia com a função
string.byte(texto, início, [fim]), onde texto é a indicação da         -- inicio do programa CADEIA06
cadeia que terá seus caracteres convertidos em formato
ASCII, início é a indicação da posição de separação inicial                print(string.char(65))
que pode ser positiva ou negativa e fim - indicação opcional               print(string.char(65, 66, 67))
da posição final de separação.
Em seguida escreva o código de programa em um editor de                -- fim do programa CADEIA06
texto, gravando-o com o nome cadeia05.lua e execute-o
com a linha de comando lua 5.1 cadeia05.lua.
                                                                      CONCLUSÃO
 -- inicio do programa CADEIA05

                                                                      Neste artigo o enfoque foi o uso dos recursos de geração
     X = "ABCDEF"                                                     de valores aleatórios e alguns detalhes sobre a
     print(string.byte(X, 1))                                         manipulação de cadeias.
     print(string.byte(X, 1, 3))                                      No próximo artigo a ênfase será dada a criação e uso de
     print(string.byte(X, 4, 5))                                      módulos em linguagem Lua.
     print(string.byte(X, 1, 6))
                                                                      Link para o artigo: http://tinyurl.com/RPED28-06

 AUTOR

                     Escrito por Augusto Manzano
                     Natural da Cidade de São Paulo, tem experiência em ensino e desenvolvimento de programação de
                     software desde 1 986. É professor da rede federal de ensino no Brasil, no Instituto Federal de Educação,
                     Ciência e Tecnologia. É também autor, possuindo na sua carreira várias obras publicadas na área da
                     computação.




                                                                 20
A PROGRAMAR

j Qu e ry 1 . 5 e AJ AX
O objectivo deste artigo é expor a funcionalidade de AJAX            também iremos rever mais à frente) que aceitam uma
que o jQuery inclui, ao detalhe, e é também falar sobre as           função como parâmetro que é chamada quando o pedido
novas funcionalidades introduzidas pela versão 1 .5 da               terminar a sua execução, ou mesmo que estes callbacks
framework, neste caso, os Deferreds.                                 sejam assignados após o pedido AJAX ter sido executado,
Nesta nova versão toda a funcionalidade de AJAX foi                  estas são chamadas de qualquer modo, esta é uma das
redesenhada, pelo que iremos entrar no tema das novas                novidades deste interface de Promises, permite assignar
funcionalidades através da sua utilização no próprio AJAX e          callbacks à posteriori, o que não era possível nas versões
depois expandindo a outras alterações também com                     anteriores às 1 .5.
relevância.                                                          Podemos ver aqui o exemplo de como assignar estes
                                                                     callbacks, e verificar que mesmo após o pedido ser
Começando pelo princípio, o método mais simples de                   completamente executado, assignando novos callbacks,
efectuar um pedido AJAX em jQuery é utilizando a função              estes executam de qualquer modo:
jQuery.get:
                                                                      /*Assignar        handlers      imediatamente     após
 var     ajaxObj      =    $.get('ajax/mypage.aspx',                  executar o pedido e
 function(data) {                                                     guardar numa var o objecto jqXHR*/
    $('#ajaxDiv').html(data);                                             var xhrObj = $.get("ajax.aspx", function()
    alert('callback called!');                                        {
 });                                                                           alert("sucesso!");
                                                                          })
Este é o método mais simplificado, especificamos                               .success(function()     {   alert("novamente
unicamente que url irá retornar os dados, e a função de               sucesso"); })
callback retorna-nos os dados e aí poderemos adicionar                    .error(function() { alert("erro"); })
qualquer lógica necessária.                                                     .complete(function()       {   alert("pedido
Os dados que retornam do nosso pedido podem ser texto,                completo"); });
JSON, XML ou JavaScript, e a função infere o tipo, pois
neste caso não o estamos a especificar. Além da variável              //alguma lógica adicional (...)
data, poderíamos especificar outras duas variáveis na
função de callback, a segunda seria o textStatus do XHR               /*adicionar outro callback de complexão aqui,
(XMLHttpRequest) e a terceira seria o mesmo que o                     e   verificar     que   é    executado   mesmo   que   o
ajaxObj irá conter, um jqXHR (que passou a ser um jqXHR               pedido já tenha sido completamente efectuado
a partir da versão 1 .5, anteriormente era um XHR nativo).            anteriormente, devido às funcionalidades das
Neste exemplo caso retornássemos HTML seria adicionado                Promises*/
ao DOM como innerHTML do objecto com o id ajaxDiv e                       xhrObj.complete(function(){ alert("completo
mostraria um alert, depois do pedido retornar com sucesso.            novamente"); });
O objecto jqXHR implementa o interface de Promises (que
iremos descortinar mais à frente na funcionalidade
Deferreds do jQuery 1 .5) e inclui toda a sua funcionalidade,        Em versões anteriores do jQuery, no caso de utilizarmos
pelo que inclui os métodos error() success() e complete()            esta função get(), se existisse um erro não conseguiríamos
para acordar com os callbacks da função $.ajax (que                  assignar um callback a não ser através da função global


                                                                21
A PROGRAMAR
j Qu e ry 1 . 5 e AJ AX


ajaxError(), ou seja, não conseguiríamos ter um error               Também existe a possibilidade de enviar parâmetros, como
handling local e objectivo, a não utilizando uma função mais        o segundo parâmetro,à semelhança do get().
genérica com a ajax().                                              Existe também a função post() que funciona do mesmo
Uma ressalva, os pedido efectuados com a função get()               exacto modo que a get() mas ao invés de enviar os dados
que não sejam pedidos JSONP ou Script, não permitem                 por HTTP GET, envia precisamente por HTTP POST.
cross-domain, como é usual.
Se quisermos efectuar outro tipo de pedidos com a função            Caso o nosso objectivo seja exclusivamente obter JSON,
get() :                                                             existe uma função específica para tal, a getJSON(), que
                                                                    tem algumas especificidades, tais como no caso de
                                                                    especificarmos adicionar ao url o texto callback=? O pedido
  //fazer apenas o request e ignorar resultado
                                                                    passa a ser tratado com um pedido JSONP, e não JSON, o
  $.get("ajax.aspx");
                                                                    que permite pedidos cross domain sem qualquer problema.
  //passar       parâmetros       simples    e     ignorar
                                                                    O segundo parâmetro pode ser utilizado para enviar
  resultados
                                                                    parâmetros, como nas outras funções.
  $.get("ajax.aspx",          {    tipo:     "noticias",
  quantas: "10" } );                                                 $.getJSON('outputjson.json', function(data) {
  //passar arrays e ignorar resultados                                   $('.result').html('<p>' + data.foo + '</p>'
  $.get("ajax.aspx",        {     'valores[]':      ["10",                 + '<p>' + data.baz[1] + '</p>');
 "20"]} );                                                           });
  //combinar parâmetros com callback                                 //estrutura de JSON esperada:
  $.get("ajax.aspx",        {     param1:   "teste"      },          {
  function(data) {                                                       "foo": "The quick brown fox jumps over the
             alert("callback executado!");                           lazy dog.",
  });                                                                    "bar": "ABCDEFG",
  //receber um JSON já parsed                                            "baz": [52, 97]
  $.get("ajax.aspx",        {     param1:   "teste"      },          }
  function(data) {
         alert(data.prop1); // valor da variável
                                                                    Passando à função mais completa e talvez a mais utilizada,
  data: { "prop1": "valor1" }
                                                                    a função ajax(), podemos definir o url, e imensos settings,
  });
                                                                    vou passar aqui pelos mais importantes:

Outra das funcões para efectuar pedidos AJAX é a load():            async: permite definir se o pedido é ou não executado
                                                                    assíncronamente;
  //carrega      o   resultado    no/s   objecto   do   DOM         beforeSend(jqXHR, settings): este callback é executado
  especificado/s pelo selector                                      imediatamente antes do pedido ser executado, e caso
  $('#ajaxDiv').load('ajax.aspx', function() {                      retornemos false, o pedido não é executado;
    alert('HTML carregado');                                        complete(jqXHR, textStatus): este callback é executado
  });                                                               quando o pedido foi completamente executado, a partir da
  //carrega      o   resultado    no/s   objecto   do   DOM         versão 1 .5 podemos passar aqui um array de funções que
  especificado/s pelo selector, mas apenas o                        serão todas executadas;
  que faz match com o selector passado ao lado                      data: permite passar parâmetros no formato querystring
  do url                                                            (valor1 =X&valor2=y...);
  $('#ajaxDiv').load('ajax.aspx #mainContent');                     dataType: permite definir exactamente que tipo de dados
                                                                    iremos receber, json, script, text, html, jsonp, xml (podemos

                                                               22
A PROGRAMAR
                                                                                                             j Qu e ry 1 . 5 e AJ AX


passar múltiplos valores, por exemplo “jsonp xml”, para
                                                                    persista qualquer cache*/
efectuar um pedido jsonp e converter para XML);
                                                                    $.ajax({
error(jqXHR, textStatus, error): callback em caso de erro;
                                                                      url: "teste.html",
statusCode: definir um callback conforme o HTTP error
                                                                      cache: false,
code:
                                                                      success: function(html){
 $.ajax({                                                                     $("#resultado").append(html);
    statusCode: {404: function() {                                    }
            alert('page not found');                                });
    }
 });                                                                /*efectuar um pedido que ao estando o seu
                                                                    resultado a ser utilizado de imediato para
                                                                    assignar à  variável html, devemos especifica
success(data, textStatus, jqXHR): callback executado
                                                                    que        não    pode    ser    assíncrono,     pois   caso
quando o pedido é retornado com sucesso;
                                                                    contrário poderíamos tentar usar a variável
type: tipo de pedido “GET” ou “POST”;
                                                                    html e esta não iria ter o valor esperado.*/
url: URL do pedido.
                                                                    var html = $.ajax({
                                                                      url: "page.aspx",
Podemos utilizar a função ajaxSetup() para definir estes
                                                                      async: false
settings globalmente na nossa aplicação, sendo que depois
                                                                     }).responseText;
podemos fazer override em cada caso aos settings que se
alteram, centralizando tudo o que são settings transversais.
                                                                    /*o       mesmo    caso    que   o   anterior,    mas   aqui
Exemplos:
                                                                    enviamos parâmetros e temos um callback de
                                                                    sucesso, e o o dataType é especificado.
 //obter um script via AJAX (GET)
                                                                    Ao utilizar o global a false, estamos a dizer
 $.ajax({
                                                                    explicitamente que os eventos globais de ajax
        type: "GET",
                                                                    não        vão     ser    disparados,    logo     os    seus
        url: "my.js",
                                                                    callbacks não vão executar, isto caso estejam
        dataType: "script"
                                                                    definidos via ajaxStart() e ajaxStop()*/
 });
                                                                    var bodyContent = $.ajax({
                                                                                url: "script.aspx",
 //fazer          o    pedido     por    POST,      enviando
                                                                                global: false,
 parámetros e com callback
                                                                                type: "POST",
 $.ajax({
                                                                               data: ({id : this.getAttribute('id')}),
        type: "POST",
                                                                                dataType: "html",
        url: "ajax.aspx",
                                                                                async:false,
        data: "nome=Ricardo&location=Lisboa",
                                                                                success: function(msg){
        success: function(msg){
                                                                                     alert(msg);
             alert("Dados enviados: " + msg);
                                                                                }
        }
                                                                          }
 });
                                                                    ).responseText;

 /*pedir         a    última    versão   de   uma    página,
 especificando que não queremos que o browser




                                                               23
A PROGRAMAR
j Qu e ry 1 . 5 e AJ AX


Com esta especificação extensa do AJAX, vamos passar às              Como podemos ver, deste modo podemos organizar o
novas funcionalidades do jQuery 1 .5, começando pelos já             código de maneira diferente, até podemos criar uma
mencionados Deferreds (Promises interface).                          abstracção à função de ajax no contexto da nossa
Esta funcionalidade tem como objectivo fazer com que uma             aplicação e ter funções para atribuição de callbacks, que
tarefa e a lógica executada após esta estar completa sejam           são executados numa metodologia FIFO (First in first out).
desacoplados, quer isto dizer que podemos assignar                   Não temos de definir callbacks de complexidade extrema
múltiplos callbacks para o resultado de uma tarefa e                 pelo facto de apenas podermos definir um e até podemos
mesmo após esta estar completa podemos continuar a                   começar a usar esta funcionalidade de um modo
adicioná-los e estes são executados do mesmo modo. Esta              inteligente, para por exemplo, executar determinado código
tarefa pode ser assíncrona ou não, nada obriga que o seja.           caso algumas funções ajax tenham sido executadas com
Visto que o AJAX do jQuery 1 .5 foi redesenhado para incluir         sucesso, isto de uma forma extremamente simples,
os Deferreds, podemos usufruir deles directamente:                   utilizando a função $.then():

  // este pedido é assíncrono por omissão                             function doAjax() {
  var req = $.get('foo.htm')                                               return $.get('ajax.aspx');
       .success(function(response) {                                  }
             //em caso de sucesso
       })                                                             function doMoreAjax() {
       .error(function() {                                                 return $.get('ajax2.aspx');
             //em caso de erro                                        }
       });
                                                                      $.when( doAjax(), doMoreAjax() )
  //isto até pode ser executado antes do get                               .then(function(){
  acima                                                                            console.log('Executado quando ambos
  algumaFuncao();                                                     os pedidos estão completos!');
                                                                           })
  /*definir algo mais a ser executado em caso                              .fail(function(){
  de sucesso, que pode ou não já ter ocorrido,                                     console.log('Executado quando um ou
  mas com os deferreds realmente não interessa,                       mais pedidos falharam!');
  é executado de qualquer forma*/                                          });
  req.success(function(response) {
       /*tomar alguma acção com a resposta isto
  vai ser executado quando o sucesso ocorrer,                        Este código funciona porque o AJAX agora retorna uma
  ou caso este já tenha ocorrido, é disparado                        promise() que é utilizada para monitorizar o pedido
  de   imediato,          caso   os   outros   callbacks   de        assíncrono, esta promise() é um objecto apenas de leitura
  sucesso já tenham sido executados                                  que existe no resultado da tarefa. Os deferreds verificam a
       */                                                            existência da função promise() para determinar se um
  })                                                                 objecto é observable ou não, que é o que lhe permite
                                                                     funcionar como deferred. A função when() aguarda pela
                                                                     execução das funções AJAX passadas por parâmetro e
Deste modo podemos ver que já não estamos limitados a                quando estas são executadas os métodos then() e fail() são
definir apenas um callback para error, sucesso e                     executados, conforme o estado da tarefa. Importante referir
complexão, podemos definir quantos quisermos, e mais                 novamente que os callbacks são executados pela ordem
importante, quando quisermos!                                        cujo são assignados a cada método.

                                                                24
A PROGRAMAR
                                                                                                          j Qu e ry 1 . 5 e AJ AX


Uma nota importante: os deferreds aceitam ou funções ou            código “típico”:
arrays de funções, que nos permite definir conjuntos de            Podemos ver aqui a utilização dos deferreds num bloco
comportamentos na nossa aplicação e passá-los                      simples, e a sua explicação é muito simples:
genericamente, ao invés de passarmos apenas uma função
isolada.
                                                                    function getData(){
Podemos verificar o estado de um deferred através das
                                                                        return $.get('/echo/html/');
suas funções isRejected() e isResolved().
                                                                    }
No caso do AJAX o que obtemos é um acesso a uma parte
do deferred, visto que se tivessemos acesso completo
                                                                    function showDiv() {
poderíamos controlar quando os callbacks são executados
                                                                         var dfd = $.Deferred();
através da função resolve() e poderíamos invocá-los antes
dos pedidos realmente serem executados, o que iria
                                                                         $('#foo').fadeIn( 1000, dfd.resolve );
quebrar a lógica, logo temos apenas acesso a uma parte do
deferred, à promise(), que é apenas de leitura, como já foi
                                                                         return dfd.promise();
referido.
                                                                    }

Em termos de métodos, os que utilizámos até agora foram
                                                                    $.when( getData(), showDiv() )
o then(), success() e fail(), também falámos do complete()
                                                                         .then(function(result) {
no caso de AJAX, mas existem mais métodos que podemos
                                                                                 console.log('A animação e o pedido
utilizar, especialmente no caso de estarmos a lidar com
                                                                    AJAX foram executados');
AJAX. O método escolhido depende exclusivamente do
                                                                         });
estado ao qual queremos fazer bind.
Para todos os deferreds existem os seguintes métodos:
- then(doneCallbacks, failedCallbacks);                            Na função showDiv estamos a criar um objecto deferred
- done(doneCallbacks);                                             novo, e retornamos a promise(). Este deferred como o
- fail(failCallbacks);                                             código o mostro é resolvido assim que o fadeIn terminar,
                                                                   pois o dfd.resolve foi definido como callback deste fadeIn.
Os deferreds de AJAX têm 3 métodos adicionais que se               O getData, retorna um objecto compatível com deferred
podem especificar, 2 dos quais invocam um dos acima                (não exactamente igual, visto que é um AJAX e como já foi
especificados. Estes métodos específicos existem                   referido o AJAX não é um deferred “simples”), e como o
exclusivamente para não quebrar a compatibilidade com os           objecto retornado pelo getData, tem o método promise, é
nomes dos callbacks para AJAX que existiam nas versões             tratado com deferred e o when() aguarda que ambos
anteriores de jQuery:                                              estejam no estado resolved, após estarem, executa o
- success(doneCallbacks); -> maps to done()                        callback passado no método then() e escreve na consola.
- error(failCallbacks); -> maps to fail()
                                                                   Neste artigo podemos observar todo o potencial do AJAX, a
Existe também o método complete() que é invocado após a            sua evolução nesta nova versão 1 .5 e também a grande
função AJAX ser executada, retorne ou não erro. Ao                 nova funcionalidade que são os deferreds.
contrário do success e do error o complete é um alias para         O jQuery está em constante evolução, esta é uma das
o done, que é resolvido assim que o pedido AJAX termina,           novas features da versão 1 .5, como foi demonstrado, tem
independentemente do seu resultado.                                um potencial enorme e uma abrangência e influência
- complete(completeCallbacks);                                     grandes, visto que até afectou áreas core da framework.
                                                                   Stay tuned!
Um exemplo de utilização de deferreds num bloco de

                                                              25
A PROGRAMAR
j Qu e ry 1 . 5 e AJ AX




                                                                         Link para o artigo: http://tinyurl.com/RPED28-08

 AUTOR

                          Escrito por Ricardo Rodrigues
                          É técnico Nível III em Informática/Gestão pela Fundação Escola Profissional de Setúbal, tendo ingressado
                          após na FCT da Universidade Nova de Lisboa.
                          Posteriormente frequentou vários cursos da Microsoft em diversas áreas como Windows Forms,ASP.NET,
                          Securing .NET Applications, WCF, WWF, Web Services e COM+ tendo obtido as certificações MCP .NET
                          2.0, MCAD .NET 1 .1 , MCSD .NET 1 .1 , MCPD Windows, Web e Distributed Applications e MCPD -
                          Enterprise Applications Developer. (MCP Profile)
                          Contribui activamente em comunidades como StackOverflow e também possui um blog/twitter como
                          temática relacionada: Blog / @ricmrodrigues




                                                                    26
A PROGRAMAR

Datagrid em Windows Presentation Foundation
Neste artigo pretendo apresentar a Datagrid em Windows              MinColumnWidth; ColumnHeaderHeight; permitem definir a
Presentation Foundation (WPF) na .Net Framework 4.0.                largura, largura máxima, largura mínima e a altura do
Vou começar por uma breve apresentação teórica e em                 cabeçalho da coluna.
seguida irei apresentar vários exemplos. De salientar que                     • RowHeight; MinRowHeight: permitem definir a
não terei em conta Design Patterns.                                 altura e altura mínima da linha.
                                                                              • GridLinesVisibility: permite definir a visibilidade
A DataGrid é um controlo que permite apresentar dados,              das linhas que delimitam as linhas e colunas. Caso sejam
representando cada linha um item de uma lista de objectos           visíveis as propriedades HorizontalGridLinesBrush e
do mesmo tipo e as colunas representam as várias                    VerticalGridLinesBrush permitem definir aparência das
características do objecto. Ou seja, se na instância da             linhas.
datagrid apresento uma lista de empregados, cada linha                        • SelectionMode; SelectionUnit permitem definir o
representa um empregado e cada coluna representa uma                modo de selecção dos itens, ou seja, se é possível
propriedade do empregado.                                           seleccionar mais de que um item e se é permitido
                                                                    seleccionar linha(s) completa(s) ou célula(s).
A classe DataGrid está incluída no namespace                                  • AutoGenerateColumns: permite gerar
System.Windows.Controls e é um selector que permite                 automáticas as colunas da datagrid. Para a geração
seleccionar mais do que um item ao mesmo tempo e tem                automática é considerada todas as propriedades do tipo de
por base a classe ItemsControl, que é um Controlo e que             objecto em causa, ou no caso de se estar a usar um
implementa a interface IAddChild. A seguinte imagem                 dataTable a geração é baseada nas colunas da dataTable.
mostra-nos esta hierarquia de classes.                                        • Columns: permite obter a colecção de colunas.
                                                                              • CellStyle: permite definir o estilo da célula.
                                                                              • ColumnHeaderStyle: permite definir o estilo do
                                                                    cabeçalho da coluna.
                                                                              • CanUserAddRows: permite que o utilizado
Vejamos agora algumas propriedades, métodos e eventos               adicione novos itens.
relevantes da DataGrid.                                                       • CanUserDeleteRows: permite que o utilizado
                                                                    apague itens.
                                                                              • CanUserReorderColumns permite que o
As propriedades mais relevantes são:                                utilizador organize as colunas.
         • Name: permite definir o nome.                                      • CanUserResizeColumns: permite que o utilizador
         • Foreground: permite definir a cor da letra.              redimensione as colunas.
         • Background: permite definir a cor de fundo.                        • CanUserResizeRows: permite que o utilizador
         • AlternatingRowBackground; AlternationIndex:              redimensione as linhas.
permitem definir a cor de fundo de cada linha, de forma                       • CanUserSortColumns: permite que o utilizador
alternada.                                                          ordene os itens ao fazer duplo clique no cabeçalho da
         • Width; Height; MaxHeight; MinWidth; MaxWidth;            coluna.
MinHeight: permitem definir a largura, altura e seus valores                  • CurrentColumn: permite obter a coluna actual.
mínimos e máximo. ActualHeight; ActualWidth permitem                          • CurrentCell: permite obter a célula actual.
obter qual é o valor actual da altura e da largura.                           • CurrentItem: permite saber o item actual.
         • ColumnWidth; MaxColumnWidth;                                       • SelectedCells: permite saber quais as células


                                                               27
A PROGRAMAR
D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


que estão seleccionadas.                                                  alterada.
           • SelectedIndex: permite saber qual o índex do                          • CurrentCellChanged: ocorre quando o valor da
item seleccionado.                                                        propriedade CurrentCell é alterado.
           • SelectedItem: permite obter o item que está                           • SelectedCellsChanged: ocorre quando o valor da
seleccionado.                                                             propriedade SelectedCells é alterado.
           • SelectedItems: permitem saber os itens que
estão seleccionados.                                                      Nota: O leitor que pretenda efectuar um estudo mais
           • HasItems: permite saber se a datagrid contém                 pormenorizado sobre as propriedades, métodos e eventos
itens.                                                                    da DataGrid, deve consultar a página DataGrid Class no
           • Items: permite obter a lista de itens.                       MSDN: http://bit.ly/ewIdaP
           • ItemsSource: permite obter a lista de itens.
           • ItemTemplate; ItemTemplateSelector: permitem
definir o template aplicar aos itens.                                     Antes de passarmos aos exemplos práticos, vejamos os
                                                                          vários tipos de colunas da DataGrid.
Nota: Existem diferenças entre a propriedade Items e a
propriedade ItemsSource e apenas se pode usar uma                         Em WPF, podemos definir os seguintes tipos de colunas:
delas. Quando se usa a propriedade ItemsSource, não é                       • DataGridTextColumn – permite apresentar e editar texto;
possível adicionar ou remover itens através desta                            • DataGridCheckBoxColumn – permite atribuir um valor
propriedade ou através da propriedade Items. No entanto,                  lógico (verdadeiro / falso)
se atribuirmos uma ObservableCollection ao ItemsSource,                      • DataGridComboBoxColumn – permite seleccionar uma
essa questão é ultrapassada.                                              opção de um conjunto de opções;
                                                                              • DataGridHyperlinkColumn – permite adicionar uma
                                                                          hiperligação;
Os métodos mais relevantes são:                                             • DataGridTemplateColumn – permite definir o template da
        • BeginEdit: permite invocar o comando                            coluna, isto é, podemos customizar a coluna.
BeginEditCommand, que será responsável por alterar para
modo de edição a linha ou célula seleccionada.                            O seguinte diagrama, permite-nos perceber melhor qual a
        • CommitEdit: permite invocar o comando                           classe de base de cada tipo de coluna.
CommitEditCommand para célula ou linha que está em
modo de edição.
        • CancelEdit:permite invocar o comando
CancelEditCommand para célula ou linha que está em
modo de edição.

 Os eventos mais relevantes são:
          • BeginningEdit: ocorre antes da célula ou linha
 entrar em modo de edição.                                                Passemos agora aos exemplos práticos.
          • PreparingCellForEdit: ocorre quando a célula
 entra em modo de edição.                                                 Nota: De apoio a este artigo criei uma demo, o leitor poderá
          • CellEditEnding: ocorre antes de haver um                      obter em: http://bit.ly/efSP1 W
“commit” da célula ou antes de ser cancelada a edição.
          • RowEditEnding: ocorre antes de haver um                       Suponhamos que temos um objecto empregado
“commit” da linha ou antes de ser cancelada a edição.                     (Employee) e um conjunto de empregados (Employees). O
          • SelectionChanged: ocorre quando a selecção é                  empregado, tem como principais características: código,

                                                                     28
A PROGRAMAR
                                                                      D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


nome, se é o patrão, salário, taxas e aniversário.
                                                                  private void WindowLoaded(object sender,
                                                                  RoutedEventArgs e){
                                                                             var employees=new Employees();
                                                                             // add the employee list
                                                                             //using ItemsSource
                                                                             dataGridEmployees.ItemsSource =
                                                                  employees;
                                                                  }

Notas:
          • A classe Employee implementa a interface             Usando a propriedade Items para atribuir a lista de
INotifyPropertyChanged para que sejam feitas notificações        empregados.
quando alguma propriedade é alterada. Isto é em parte
responsável pela actualização da informação na Datagrid.          Usando a propriedade Items para atribuir a
          • A classe Employees é uma ObservableCollection         lista de empregados.
de Employee, porque pretendo que sejam feitas                     private void WindowLoaded(object sender,
notificações quando um ou mais empregrados são                    RoutedEventArgs e){
adicionados/removidos da lista de empregados.                                var employees=new Employees();
Caso        tivesse    optado     por     List<Employee>,                    // add the employee list
Collection<Employee> ou IEnumerable<Employee> essas                          //using Items
notificações não aconteceriam. Na imagem anterior é                          foreach (var employee in employees)
possível analisar o que é uma ObservableCollection, sendo
a implementação das interfaces INotifyCollectionChanged e         dataGridEmployees.Items.Add(employee);
INotifyPropertyChanged reponsável por informar sobre as           }
notificações/actualizações.
                                                                  • Resultado:
1 º Exemplo:
   • Objectivo: Apresentar numa janela uma Datagrid com
uma lista de empregados, as colunas da Datagrid devem
ser geradas automaticamente:

 • XAML

 <DataGrid     Name="dataGridEmployees"
           Grid.Column="1" Grid.ColumnSpan="3"
           Grid.Row="2"
           AutoGenerateColumns="True"/>                          2º Exemplo:
                                                                   • Objectivo: Apresentar numa janela uma Datagrid com
                                                                 uma lista de empregados, as colunas da Datagrid não
 • Code Behind:                                                  devem ser geradas automaticamente e apenas se pretende
                                                                 visualizar as colunas relativas ao nome, se é patrão, salário
Usando a propriedade ItemsSource para atribuir a lista de        e taxas.
empregados.



                                                            29
A PROGRAMAR
D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


  • XAML:

  <DataGrid       Name="dataGridEmployees"
            Grid.Column="1" Grid.ColumnSpan="3"
            Grid.Row="2"
            AutoGenerateColumns="False">
            <DataGrid.Columns>
                       <DataGridTextColumn
  Header="Nome" MinWidth="200"
  Binding="{Binding Name}" />                                             3º Exemplo:
                       <DataGridTextColumn                                  • Objectivo: Formatar a apresentação do salário e das
  Header="Salário" Width="100" MaxWidth="150"                            taxas, ou seja, um salário com valor 0 (zero) deve
  Binding="{Binding Salary}"/>                                            apresentar o valor “Não está atribuído” e os salários que
                       <DataGridTextColumn                                estejam definidos devem apresentar o símbolo da moeda €
  Header="Taxa" Width="50" Binding="{Binding                              (euro). As Taxas devem apresentar o valor da taxa com o
  Rates}"/>                                                               símbolo de percentagem.
                       <DataGridCheckBoxColumn
  Header="É patrão" Binding="{Binding                                     Neste exemplo, temos necessidade de criar duas classes,
  IsBoss}"/>                                                              cada classe representa o conversor que será usado no
      </DataGrid.Columns>                                                 objecto de Binding da coluna. O conversor será
  </DataGrid>                                                             responsável por transformar o valor original no valor que é
                                                                          pretendido apresentar. Ambas as classes implementam a
Notas:                                                                    interface IValueConverter.
   • Através do objecto Binding da coluna é definido qual a
propriedade do objecto que se vai apresentar.                             Portanto, o conversor para o salário será definido da
     • Foram definidas as medidas para a largura, largura                 seguinte forma:
mínima e largura máxima das várias colunas.
                                                                           [ValueConversion(typeof(double),
 • Code Behind:                                                            typeof(string))]
                                                                           public class
  private void WindowLoaded(object sender,                                 SalaryValueConverter:IValueConverter{
  RoutedEventArgs e) {                                                              private const string
            var employees = new Employees();                               NotDefinedValue="Não está definido";
            // add the employee list                                                private const string EuroSymbol = "€";
            dataGridEmployees.ItemsSource =
  employees;                                                                        public object Convert(object value,
  }                                                                        Type targetType, object parameter,
                                                                           System.Globalization.CultureInfo culture) {
 • Resultado:                                                                                if (value == null ||
                                                                           (double.Parse(value.ToString()) == 0))
(A imagem com o resultado pode ser visto na coluna do                                                 return NotDefinedValue;
lado direito em cima de todo)
                                                                                             return string.Format("{0} {1}",




                                                                     30
A PROGRAMAR
                                                                    D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


                                                                 • XAML:
 value, EuroSymbol);
            }
                                                                É necessário adicionar o namespace dos resources

            public object ConvertBack(object                     xmlns:Converters="clr-
 value, Type targetType, object parameter,                       namespace:WPFDatagridImplementation.Converter
 System.Globalization.CultureInfo culture) {                     s"
                   if (value is string &&
 value.ToString().Equals(NotDefinedValue))
                                                                Nos resources da janela, inicializamos os dois conversores
                            return 0;

                                                                 <Window.Resources>
                   return value is string &&                           <Converters:RatesValueConverter
 value.ToString().Contains(EuroSymbol)                           x:Key="ratesValueConverter"/>
                                        ?                              <Converters:SalaryValueConverter
 double.Parse(value.ToString().Replace(EuroSym                   x:Key="salaryValueConverter"/>
 bol, string.Empty))                                             </Window.Resources>
                                        : value;
            }
                                                                É necessário alterar o Binding das colunas, é neste objecto
 }
                                                                que definimos o conversor aplicar.

                                                                 <DataGrid       Name="dataGridEmployees"
O conversor para a taxa será definido da seguinte forma:                   Grid.Column="1" Grid.ColumnSpan="3"
                                                                           Grid.Row="2"
 [ValueConversion(typeof(int),typeof(string))]                             AutoGenerateColumns="False">
 public class                                                              <DataGrid.Columns>
 RatesValueConverter:IValueConverter{                                                 <DataGridTextColumn
        private const string PercentageSymbol =                  Header="Nome" MinWidth="200"
 "%";                                                            Binding="{Binding Name}" />
            public object Convert(object value,                                       <DataGridTextColumn
 Type targetType, object parameter,                              Header="Salário" Width="100" MaxWidth="150"
 System.Globalization.CultureInfo culture){                      Binding="{Binding
                   if (value is int &&                           Path=Salary,Converter={StaticResource
 int.Parse(value.ToString()) == 0)                               salaryValueConverter}}"/>
                   return string.Empty;                                               <DataGridTextColumn
                   return string.Format("{0} {1}",               Header="Taxa" Width="50" Binding="{Binding
 value, PercentageSymbol);                                       Path=Rates,Converter={StaticResource
        }                                                        ratesValueConverter}}"/>
            public object ConvertBack(object                                          <DataGridCheckBoxColumn
 value, Type targetType, object parameter,                       Header="É patrão" Binding="{Binding
 System.Globalization.CultureInfo culture){                      IsBoss}"/>
            throw new NotImplementedException();                           </DataGrid.Columns>
        }                                                        </DataGrid>
 }




                                                           31
A PROGRAMAR
D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


 • Code Behind:
                                                                           int.Parse(values[1].ToString());
  private void WindowLoaded(object sender,                                                   if (salary == 0 && rates == 0)
  RoutedEventArgs e) {                                                                                return string.Empty;
            var employees = new Employees();
            // add the employee list                                                         return string.Format("{0} €",
            dataGridEmployees.ItemsSource =                                salary - salary * rates / 100);
  employees;                                                                         }
  }
                                                                                     public object[] ConvertBack(object

 • Resultado:                                                              value, Type[] targetTypes, object parameter,
                                                                           System.Globalization.CultureInfo culture) {
                                                                                             throw new
                                                                           NotImplementedException();
                                                                                     }
                                                                           }



                                                                          Nota: O objecto values que está definido no argumento do
                                                                          método Convert, recebe os valores de acordo com a ordem
4º Exemplo:                                                               que for definido no multibinding que será definido na
   • Objectivo: Apresentar uma coluna extra, que será o                   coluna.
resultado do produto do salário com a taxa associada.
                                                                           • XAML:
É necessário criar um conversor, que receba o salário e a
taxa, e devolva o resultado final, formado. Neste caso,                   Adicionamos o conversor nos resources da janela.
como é preciso receber dois valores a classe terá que                      <Window.Resources>
implementar a interface IMultiValueConverter.                                        <Converters:RatesValueConverter
                                                                           x:Key="ratesValueConverter"/>
  public class
                                                                                     <Converters:SalaryValueConverter
  FinalySalaryConverter:IMultiValueConverter {
                                                                           x:Key="salaryValueConverter"/>
            public object Convert(object[] values,
                                                                                     <Converters:FinalySalaryConverter
  Type targetType, object parameter,
                                                                           x:Key="finalySalaryConverter"/>
  System.Globalization.CultureInfo culture) {
                                                                           </Window.Resources>
                       double salary = 0.0;
                       int rates = 0;                                     Adicionamos a nova coluna com o nome “Salário Final”,
                                                                          repare-se que usou-se um Multibinding, para permitir enviar
                       if (values[0] is double)                           o valor do salário e o valor da taxa.
                                  salary =                                 <DataGrid.Columns>
  double.Parse(values[0].ToString());                                                <DataGridTextColumn Header="Nome"
                                                                           MinWidth="200" Binding="{Binding Name}" />
                       if (values[1] is int)                                         <DataGridTextColumn Header="Salário"
                                  rates =                                  Width="100" MaxWidth="150" Binding="{Binding




                                                                     32
A PROGRAMAR
                                                                 D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


                                                             5ºExemplo:
Path=Salary,Converter={StaticResource
                                                              • Objectivo: Apresentar a coluna de Aniversário, recorrendo
salaryValueConverter}}"/>
                                                             ao controlo DataPicker.
          <DataGridTextColumn Header="Taxa"
Width="50" Binding="{Binding
                                                              • XAML:
Path=Rates,Converter={StaticResource
ratesValueConverter}}"/>                                      <DataGridTemplateColumn Header="Aniversário"
          <DataGridTextColumn Header="Salário                 MinWidth="100">
Final">
               <DataGridTextColumn.Binding>                   <DataGridTemplateColumn.CellEditingTemplate>
                <MultiBinding                                                      <DataTemplate>
Converter="{StaticResource                                                                    <DatePicker
finalySalaryConverter}">                                      SelectedDate="{Binding Birthday}"
                                <Binding                      SelectedDateFormat="Short" />
Path="Salary"/>                                                                    </DataTemplate>
                                <Binding Path="Rates"
/>                                                            </DataGridTemplateColumn.CellEditingTemplate>
                    </MultiBinding>                                     <DataGridTemplateColumn.CellTemplate>
               </DataGridTextColumn.Binding>                                       <DataTemplate>
                                                                                              <TextBlock
          </DataGridTextColumn>                               Text="{Binding Birthday, StringFormat=d}" />
          <DataGridCheckBoxColumn Header="É                                        </DataTemplate>
patrão" Binding="{Binding IsBoss}"/>                                    </DataGridTemplateColumn.CellTemplate>
</DataGrid.Columns>                                           </DataGridTemplateColumn>
</DataGrid>


• Code Behind:
                                                             Nota: Apenas apresento o XAML da coluna criada. Foram
                                                             definidos dois templates: um para o caso em que se está
private void WindowLoaded(object sender,
                                                             em modo de edição, em que usou aplicar um DatePicker. O
RoutedEventArgs e) {
                                                             outro template apenas apresenta a data.
          var employees = new Employees();
          // add the employee list
                                                              • Resultado:
          dataGridEmployees.ItemsSource =
employees;
}


• Resultado:




                                                        33
A PROGRAMAR
D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


6º Exemplo:
                                                                           employees;
   • Objectivo: Apresentar os empregados ordenados por
Nome.
                                                                                     ICollectionView view =
                                                                           CollectionViewSource.GetDefaultView(dataGridE
                                                                           mployees.ItemsSource);
 • Code Behind:
                                                                                     view.Filter = new
                                                                           Predicate<object>(EmployeesWithSalaryGreaterT
  private void WindowLoaded(object sender,
                                                                           han500);
  RoutedEventArgs e) {
                                                                           }
            var employees = new Employees();
            dataGridEmployees.ItemsSource =
                                                                           private bool
  employees;
                                                                           EmployeesWithSalaryGreaterThan500(object
                                                                           param) {
            ICollectionView view =
                                                                                     var employee = (Employee)param;
  CollectionViewSource.GetDefaultView(dataGridE
  mployees.ItemsSource);
                                                                                     if (employee.Salary > 500)
                                                                                             return true;
            view.SortDescriptions.Add(new
  SortDescription("Name",
                                                                                     return false;
  ListSortDirection.Ascending));
                                                                           }
  }




 • Resultado:                                                              • Resultado:




                                                                          8º Exemplo:
7º Exemplo:                                                                 • Objectivo: As linhas da datagrid devem apresentar uma
  • Objectivo: Filtrar os empregados com salário superior a               cor alternada.
500.00€.
                                                                           • XAML:
• Code Behind:                                                             <DataGrid      Name="dataGridEmployees"

  private void WindowLoaded(object sender,
  RoutedEventArgs e) {                                                               Grid.Column="1" Grid.ColumnSpan="3"

            var employees = new Employees();                                         Grid.Row="2"

            dataGridEmployees.ItemsSource =                                          AutoGenerateColumns="True"




                                                                     34
A PROGRAMAR
                                                                            D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n



           AlternatingRowBackground="LightGray"                         <DataGrid Name="dataGridEmployees"
 AlternationCount="2"/>
                                                                                   Grid.Column="1" Grid.ColumnSpan="3"
                                                                                   Grid.Row="2"
 private void WindowLoaded(object sender,                                          AutoGenerateColumns="True"
 RoutedEventArgs e) {                                                              ColumnHeaderStyle="{DynamicResource
           var employees = new Employees();                             columnStyle}"
           dataGridEmployees.ItemsSource =                                         ColumnHeaderHeight="40"
 employees;                                                                        GridLinesVisibility="All"
 }                                                                                 HorizontalGridLinesBrush="Red"
                                                                                   VerticalGridLinesBrush="Green"/>
 • Resultado:

                                                                        • Code Behind:

                                                                        private void WindowLoaded(object sender,
                                                                        RoutedEventArgs e){
                                                                                   var employees = new Employees();
                                                                                   dataGridEmployees.ItemsSource =
                                                                        employees;
                                                                        }
9º Exemplo:
   • Objectivo: Alterar a altura do cabeçalho das colunas,
alterar o tipo de fonte da letra e tamanho e cor. Alterar a cor        • Resultado:
das linhas horizontais e verticais da datagrid.

 • XAML:
Nos resources da Window, definimos o estilo que iremos
aplicar às células.

 <Window.Resources>
           <Style x:Key="columnStyle"
 TargetType="DataGridColumnHeader">
                    <Setter Property="FontFamily"
 Value="Arial Black" />
                    <Setter Property="FontSize"                        1 0º Exemplo:
 Value="14"/>                                                             • Objectivo: Ao seleccionar uma célula e mostrar uma
                    <Setter Property="Foreground"                      mensagem de aviso de que foi detectada uma alteração,
 Value="Red"/>                                                         apresentando o nome do empregado seleccionado e o
           </Style>                                                    nome da coluna seleccionada.
 </Window.Resources>




                                                                  35
A PROGRAMAR
D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n


 • XAML:
                                                                           selectedEmployee.Name);
  <DataGrid       Name="dataGridEmployees"                                          MessageBox.Show(message);


            Grid.Column="1" Grid.ColumnSpan="3"                            }
            Grid.Row="2"
            AutoGenerateColumns="True"                                     • Resultado:
            SelectionMode="Single"
  SelectionUnit="Cell"


  CurrentCellChanged="DataGridEmployeesCurrentC
  ellChanged"/>


 • Code Behind:

  private void WindowLoaded(object sender,
  RoutedEventArgs e)
                                                                          Demo do artigo: http://bit.ly/efSP1 W
             {
                                                                          Contém:
                   var employees = new Employees();
                                                                           • Diagrama de Classes da hierarquia das colunas
                   dataGridEmployees.ItemsSource =
                                                                           • Diagrama de classes da hierarquia da Datagrid
  employees;
                                                                           • Diagrama de classes do modelo usado no demo
             }
                                                                           • Interfaces
  private void
                                                                           • Classes de dados
  DataGridEmployeesCurrentCellChanged(object
                                                                           • Conversores
  sender, System.EventArgs e) {
                                                                           • Janela principal com menu para os vários exemplos
            Employee selectedEmployee =
                                                                           • Janelas dos vários exemplos
  (Employee)dataGridEmployees.CurrentItem;


            string message = String.Format("Foi
                                                                          Referências:
  seleccionada a coluna '{0}' do empregado(a)
                                                                               • MSDN: DataGrid Class - .Net Framework 4.0:
  {1}.",
                                                                          http://bit.ly/ewIdaP
  dataGridEmployees.CurrentCell.Column.Header,
                                                                              • WindowsClient.Net: WPF Toolkit: DataGrid Feature
                                                                          Walkthrough: http://bit.ly/hksWsL
                                                                          Link para o artigo: http://tinyurl.com/RPED28-05

 AUTOR

                       Escrito por Sara Silva
                       É licenciada em Matemática – Especialidade em Computação, pela Universidade de Coimbra,
                       actualmente é Software Developer no Porto.
                       O entusiasmo pela área resultou na obtenção dos títulos de Microsoft Certified Profissional Developer –
                       Windows 3.5, Microsoft Certified Tecnology Specialist – WPF 3.5, WPF 4 e Windows Forms. Faz parte de
                       várias comunidades, tendo uma participação activa na Comunidade NetPonto e no P@P.




                                                                     36
A PROGRAMAR

Pl a n o s d e E xe c u ç ã o e m O R AC LE
Introdução                                                         sabemos qual a via que, mesmo não parecendo ser a mais
                                                                   óbvia, deverá ser a mais rápida. Se tivermos ouvido o
Nas últimas duas edições, abordámos o tema da                      estado do trânsito há uma hora atrás, a situação deverá já
optimização de SQL com o recurso a técnicas de melhoria            estar totalmente diferente, quando sairmos de casa, e a
do código SQL. Recorremos, nomeadamente, à utilização              rota mais rápida poderá agora estar entupida. Se, por
de bind variables e à correcta implementação de índices.           último, desconhecermos totalmente o estado do trânsito,
Nesta edição, vamos apresentar uma das ferramentas de              seguiremos pelo caminho que consideramos mais directo
diagnóstico que permitem prever e verificar a optimização:         mas que, eventualmente, poderá não ser o mais rápido
os planos de execução.                                             naquele momento. O Oracle procede do mesmo modo, pelo
                                                                   que, manter as estatísticas actualizadas é uma mais-valia
                                                                   para que o optimizador possa tomar a melhor decisão e, no
O que é                                                            caso do plano de execução, apresentar o plano mais
                                                                   idêntico à realidade.
Antes de efectuar um SELECT na base de dados, o
optimizador traça um plano de execução, de modo a avaliar
que dados recolher, onde e como os deve obter. O plano de          Criar a tabela PLAN_TABLE
execução é influenciado por múltiplos factores e varia ao
longo do tempo, isto é, varia consoante o estado presente          Os planos de execução são registados numa tabela,
da base de dados.                                                  usualmente definida como PLAN_TABLE, sob a forma de
                                                                   linhas com relações hierárquicas entre si. Por isso, é
Os principais factores que definem o plano de execução             possível registar vários planos de execução na
são a dimensão das tabelas acedidas, a diversidade de              PLAN_TABLE, de modo a compararmos diferentes queries.
dados das tabelas (selectividade) e a existência ou não de
índices. Mas, como é que o optimizador obtém,                      A PLAN_TABLE poderá não estar disponível no ambiente
rapidamente, esta informação? O Oracle produz                      Oracle. O Oracle fornece um script que permite criar essa
estatísticas da base de dados. As estatísticas registam os         tabela facilmente. O script pode ser encontrado na
principais factores que definem o plano de execução. Deste         directoria %ORACLE_HOME%/rdbms/admin com o nome
modo, o optimizador, em vez de percorrer todos os dados            UTLXPLAN.SQL. Consoante a versão de Oracle que
afectados por um SELECT, sabe à partida o que vai                  estamos a utilizar, o script pode conter algumas variações a
encontrar. No entanto, para que as estatísticas produzam           nível das colunas da tabela. Este script não é mais do que
bons resultados nas queries, é fundamental que estejam             um CREATE TABLE, mas não será aqui exposto, devido à
actualizadas. Por exemplo, se a estatística nos diz que uma        dimensão do mesmo e às variantes que existem para
tabela tem dez registos mas, entretanto, carregámos um             diferentes versões Oracle.
milhão de novos registos, a estatística produzirá valores
errados e induzirá o optimizador por um caminho que não é          Tendo a garantia de que a tabela existe, devemos sempre
o óptimo.                                                          limpar o seu conteúdo, antes de iniciarmos o “estudo” das
                                                                   queries, recorrendo à instrução TRUNCATE TABLE
Podemos fazer uma analogia com uma deslocação de                   PLAN_TABLE.
automóvel desde casa até ao local de trabalho. Se
soubermos, antecipadamente, o estado do trânsito,


                                                              37
A PROGRAMAR
Pl a n o s d e E xe c u ç ã o e m O R AC LE


Determinar o plano de execução
Estamos, agora, em condições de começar a obter planos
de execução das nossas queries. Necessitamos,
primeiramente, de registar o plano de execução na
PLAN_TABLE, recorrendo à instrução EXPLAIN PLAN SET
STATEMENT_ID = 'XPTO' FOR, seguida da query que
queremos analisar. Por exemplo:
                                                                   A forma correcta de ler o mapa do plano é começar pela
                                                                   instrução mais à direita (maior nível). Quando duas
  EXPLAIN PLAN SET STATEMENT_ID = 'XPTO' FOR
                                                                   instruções estão ao mesmo nível, começa-se pela que tem
  SELECT C.COD_ASSOC FROM ASSOCIADOS A
                                                                   um ID menor. Neste caso, vemos que a primeira instrução a
  INNER JOIN CARTOES C ON C.COD_ASSOC =
                                                                   ser executada será a n.º 2.
  A.CODIGO
  WHERE A.CODIGO BETWEEN 21000 AND 21500;
                                                                   Vejamos, primeiro, as          colunas    da    PLAN_TABLE
                                                                   apresentadas nesta query:
O STATEMENT_ID atribuído é o identificar do plano do tipo
                                                                             • Id: identificador da linha da instrução do presente
varchar2. O plano está criado e podemos continuar a
                                                                   plano. Atenção, não é o ID da linha na PLAN_TABLE, mas
determinar os planos de execução de outras queries ou,
                                                                   sim o ID da amostra de dados retirada dessa mesma
por exemplo, verificar os planos antes e após o cálculo das
                                                                   tabela. Lembremo-nos que a PLAN_TABLE pode conter
estatísticas. Os planos ficam registados na tabela e só
                                                                   vários planos de execução.
serão eliminados manualmente, pelo que se poderão
                                                                             • Operation: O tipo de instrução a ser executada.
guardar os registos para consulta futura.
                                                                             • Name: Tabela ou índice a que se refere a
                                                                   Operation.
                                                                             • Rows: Número de linhas afectadas ou acedidas.
Analisar o plano de execução
                                                                             • Bytes: Total de bytes que serão movimentados
                                                                   para ler os dados da instrução.
Naturalmente que, se a PLAN_TABLE é uma tabela, a
                                                                             • Cost: O custo de CPU para a instrução. Este
visualização do plano de execução é feita com um SELECT
                                                                   campo não tem qualquer unidade, pelo que o mesmo
à mesma tabela. Alguns editores SQL de Oracle já
                                                                   deverá ser utilizado como meio de comparação. Por
possuem essa funcionalidade à distância de um clique. O
                                                                   exemplo, comparando o Cost CPU de uma query leve com
que fazem é executar um dos muitos SELECT's possíveis à
                                                                   uma query mais pesada. Este valor é parametrizado num
tabela. O Oracle também já facilita a consulta dos planos
                                                                   ficheiro de configuração do Oracle e a sua compreensão
de execução através da seguinte instrução, adaptada aqui
                                                                   mais profunda seria alvo de um tema de administração de
ao nosso exemplo, com o respectivo statement_id:
                                                                   bases de dados.
  SELECT * FROM
  TABLE(dbms_xplan.display('plan_table','xpto',                    Note-se que os campos apresentados pela função do
 'all'));                                                          Oracle não correspondem aos campos da PLAN_TABLE
                                                                   em bruto. A função não faz mais do que criar uma VIEW
                                                                   com a selecção de dados da tabela do plano de execução.
O resultado desta query poderia ser o seguinte:
                                                                   Analisemos, agora, a informação apresentada para este
                                                                   plano. Os ID's 2 e 3 estão sob a operação de junção
                                                                   NESTED LOOPS. Este é um dos tipos de junção de tabelas


                                                              38
A PROGRAMAR
                                                                                          Pl a n o s d e E xe c u ç ã o e m O R AC LE


que consiste em:                                                    Tendo em conta que cada linhas das duas tabelas são
         (2) Escolher a tabela sem índice na condição,              cruzadas obedecendo ao match:
neste caso a tabela CARTOES que não possui um índice
no campo de junção COD_ASSOC. É feito um FULL TABLE                  access("C"."COD_ASSOC"="A"."CODIGO")
SCAN filtrando as linhas com a condição:
                                                                           (1 ) O Oracle pode agora juntar as tabelas, fazendo
 filter("C"."COD_ASSOC"<=21500 AND                                  o INNER JOIN através do algoritmo de NESTED LOOPS.
 "C"."COD_ASSOC">=21000)                                            Obtêm-se 394 linhas, no final, e terão sido acedidos 3940
                                                                    bytes.
Repare-se no * antes do 2, referente à nota em baixo
(Predicate Information), que indica o filtro no SCAN com os         Conclusão
números de código do SELECT:
                                                                    O plano de execução é uma ferramenta bastante poderosa
 WHERE A.CODIGO BETWEEN 21000 AND 21500;
                                                                    para fazer uma avaliação prévia do impacto da nossa query
          (3) Para cada uma das 51 4 linhas da tabela               na base de dados. Seja para avaliar o impacto de uma
anterior, já filtrada, é feito um acesso ao índice da tabela        query num ambiente de produção em alturas críticas ou
ASSOCIADOS, ASSOCIADOS_PK, obtendo apenas os                        simplesmente para optimizar e procurar queries com menor
dados com:                                                          consumo de CPU ou IO, o plano de execução é um bom
                                                                    começo.
 filter("A"."CODIGO"<=21500 AND
 "A"."CODIGO">=21000)                                               Conhecendo, detalhadamente, o tipo de operações que o
                                                                    Oracle executa, o plano de execução pode ser, na grande




                                                               39
A PROGRAMAR
Pl a n o s d e E xe c u ç ã o e m O R AC LE


maioria dos casos, mais do que suficiente para prever o
resultado da query na BD. No entanto, nem sempre o plano
de execução é eficaz. Há casos específicos que                      Referências:
necessitam de especial atenção e de uma avaliação pós-
processamento através de outra ferramenta, o SQL Trace.             Estrutura da tabela PLAN_TABLE e lista de operações
O SQL Trace vai registar as operações realizadas pelo               produzidas pelo plano de execução:
Oracle, permitindo-nos analisar detalhadamente o que                http://download.oracle.com/docs/cd/A5861 7_01 /server.804/
ocorreu no SELECT. Enquanto o plano de execução                     a58246/explan.htm#891
permite fazer uma avaliação a priori, o SQL Trace faz uma
avaliação a posteriori.                                             Outras formas de representar o plano de execução:
                                                                    http://download.oracle.com/docs/cd/A5861 7_01 /serve
Convém, ainda, frisar que, para que o plano de execução             r.804/a58246/explan.htm#1 088
seja o mais fiel possível, as estatística deverão estar
actualizadas, o que nem sempre é possível ou viável se a
dimensão das bases de dados for muito grande.




                                                                    Link para o artigo: http://tinyurl.com/RPED28-07

 AUTOR

                       Escrito por Ricardo Trindade
                       É actualmente o responsável pela área informática dos Serviços Sociais da Câmara Municipal de Lisboa
                       onde efectua, desde administração de sistemas, até programação em .NET. Está também ligado ao
                       projecto N-Ideias na área da consultoria, webdesign e software, trabalhando essencialmente com BD's
                       Oracle, PostgreSQL e SQL Server.




                                                               40
A PROGRAMAR

S m a rty PH P Te m p l a te E n gi n e
A maioria das pessoas que aprendem PHP começam,                    Introdução ao Smarty
normalmente, a construir as suas aplicações Web de forma
bastante rudimentar. Isto é normal, pois ao longo do tempo         Neste pequeno artigo vamos usar a versão 3.0.7 do Smarty
com que trabalham com PHP, os programadores vão-se                 que pode ser descarregada aqui 1 ). Vamos também usar a
habituando, aprendendo novas técnicas e desenvolvendo o            versão 5.3.0 do PHP.
seu próprio estilo de programar.
                                                                   O Smarty pe rmite-nos chamar determinados ficheiros
Este estilo desenvolvido reflecte-se maioritariamente na           e imprimi-los no ecrã, substituindo certos valores
estrutura da aplicação desenvolvida. Isto porque cada              pelos obtidos e/ou gerados pela nossa aplicação,
aplicação tem as suas funcionalidades, e estas reflectem-          mostrando ao utilizador final, dados dinâmicos.
se na necessidade de uma estrutura sólida capaz de
suportar aplicações mais robustas, extensíveis e seguras.          A diferença entre o método de templates em PHP ou
                                                                   Samrty é a mais fácil adaptação do visual da aplicação,
No entanto, há estruturas padrões e versáteis que são              sem que o designer tenha de saber a linguagem de
dadas como ideais para a construção de aplicações, e               programação (PHP) e tornando o template mais fácil de
criam-se então frameworks capazes de tornarem estas                entender. Este método torna também pequenos pedaços de
estruturas disponíveis para qualquer programador construir         texto (possivelmente HTML) sejam reutilizados mais
qualquer aplicação sem se ter de preocupar muito com a             facilmente, evitando partes de código duplicadas na
estrutura base da aplicação.                                       aplicação.

Em PHP usam-se muitas aplicações que seguem a lógica               O Smarty não necessita de nenhuma configuração do
do padrão de arquitectura de software MVC, que pretende            sistema, tornando-o assim extremamente simples de
separar a lógica do padrão da lógica de apresentação.              instalar em qualquer Sistema Operativo, dado que os
Models e Views, tendo pelo meio os Controllers. Mas não é          passos de instalação baseiam-se apenas na criação e
necessariamente obrigatório usar frameworks MVC nem                edição de pastas e ficheiros.
sequer aplicar o padrão MVC para criar aplicações que
separem a lógica da aplicação da lógica da apresentação.
                                                                   Instalar o Smarty
Cada programador pode criar a sua aplicação de modo a
separar estas duas camadas, mas isso nem sempre é um               Depois de termos feito o download da última versão do
trabalho fácil quando bem feito, e quando mal feito pode           Smarty, descomprimimo-la e copiamos os ficheiros para
resultar no aparecimento de graves falhas na aplicação e           uma pasta no nosso projecto (na raiz do projecto ou
de grandes quebras de performance. Assim sendo, porque             possivelmente numa pasta chamada smarty). Neste artigo
não usar uma framework poderosa, robusta e simples de              usaremos uma pasta dentro do nosso projecto chamada
usar que já exista e nos simplifique o trabalho? É aqui que        smarty. Portanto, apenas temos de copiar os conteúdos da
o Smarty entra.                                                    pasta libs para dentro da pasta smarty. Depois, no decorrer
                                                                   do desenvolvimento do nosso projecto apenas vamos ter
                                                                   de especificar a localização de certas pastas necessárias
                                                                   ao funcionamento do Smarty, tais como a pasta de cache e
                                                                   dos templates.


                                                              41
A PROGRAMAR
Sm a rty PH P Te m p l a te E n gi n e


                                                                    então o seguinte código.

                                                                     $smarty->assign("value", "Artigo de
Primeiro Projecto em Smarty
                                                                     introdução ao Smarty");

Portanto, agora que temos os ficheiros que necessitamos,
vamos começar a trabalhar com a biblioteca. Tudo gira à             Isto vai fazer com que as variáveis definidas no template
volta de uma classe, chamada Smarty, mas para isso                  com o nome value sejam substituídas pela respectiva
necessitamos de incluir o ficheiro.                                 string. Mas também é possível passar arrays. Para isso
                                                                    usamos a mesma função, a diferença estará no template.
 require('C:caminhoAbsolutoParaOProjectosmar
 tySmarty.class.php');                                              $array = new Array( 1 => "Introdução ao
                                                                     Smarty", 2 => "Instalar o Smarty", 3 =>
Depois necessitamos de instanciar a classe para uma
                                                                     "Primeiro Projecto em Smarty");
variável, algo simples.
                                                                     $smarty->assign("chapters", $array);

 $smarty = new Smarty();                                            Depois apenas temos de mostrar o template formatado.
Agora só temos de definir alguns directórios, necessários
                                                                     $smarty->display("index.tpl");
para o funcionamento da biblioteca.
                                                                    O ficheiro index.tpl apenas terá de conter o seguinte texto:
Primeiro, vamos criar quatro pastas dentro da pasta smarty:          <html>
cache, configs, templates, templates_c. Depois                          <head>
adicionamos o seguinte código ao ficheiro.                                    <title>Smarty</title>

 //Define as pastas. O seu caminho deve ser                             </head>

 absoluto                                                               <body>

 $smarty-                                                                <h1>{$value}</h1>

 >setTemplateDir('C:caminhoAbsolutoParaOProje                            <h2>Capítulos:</h2>

 ctosmartytemplates');                                                  <ul>

 $smarty-                                                                 {foreach $chapters as $chapter}

 >setCompileDir('C:caminhoAbsolutoParaOProjec                            <li>{$chapter}</li>

 tosmartytemplates_c');                                                 {/foreach}

 $smarty-                                                                 </ul>

 >setCacheDir('C:caminhoAbsolutoParaOProjecto                          </body>

 smartycache');                                                    </html>

 $smarty-
 >setConfigDir('C:caminhoAbsolutoParaOProject
 osmartyconfigs');

                                                                    Sintaxe do Templates
Feito isto, podemos começar a usar o Smarty à vontade.
Apesar de o Smarty ser muito bom, ele não adivinha os               A sintaxe usada na construção dos templates em Smarty é
valores que a página vai ter, pelo que temos de ser nós a           bastante simples e flexível, completamente abstraída da
dar-lhos. Isto é bastante simples, apenas temos de chamar           linguagem (PHP). Os ficheiros são HTML com pequenas
uma função e especificar o nome da variável que queremos            partes específicas do Smarty.
substituir no template e o seu respectivo valor. Adicionemos        Para aumentar a performance da aplicação e evitar gastos
                                                                    de tempo desnecessários ao fazer parse dos ficheiros de

                                                               42
A PROGRAMAR
                                                                                               S m a rty PH P Te m p l a te E n gi n e


 template de cada vez que uma página é vista, o Smarty                A parte do nome é o nome que será usado no template
“compila” os templates para ficheiros PHP, aumentando                 para se referenciar à variável, enquanto que o conteúdo é
 assim drasticamente a performance. Quando um template é              aquilo que a variável vai conter. As variáveis podem ser
 editado, o Smarty detecta-o e recompila o template, não              simples, como strings e integers ou arrays e objectos.
 sendo por isso necessária preocupação ao modificar os                Quando a variável é uma simples string, para a mostrarmos
 templates.                                                           no HTML, basta:
A Sintaxe do Smarty é de tal maneira poderosa que é
                                                                        {$nome}
 possível incluir lógica dentro dos templates, no entanto esta
 lógica deverá ser direccionada para a apresentação. Com              No entanto podemos querer usar arrays, e para isso
 isto pretendo dizer que a sintaxe do Smarty suporta                  teremos de usar funções como Smarty.
 excepções, ciclos, variáveis, includes e um sem-número de            Para imprimirmos objectos, é simples e bastante similar ao
 outras coisas fascinantes que não seriam possíveis de                PHP.
 abordar apenas num artigo. Por isso, aqui vamos apenas
                                                                        {$name>someproperty}
 abordar os aspectos mais importantes e mais comuns.
                                                                        {$name->anothervar}
 Basicamente, com o Smarty, temos o HTML, no qual
 podemos adicionar as partes do código que serão
 interpretadas pelo motor. Estas partes do código estão,
 geralmente, entre chavetas ({ e }), no entanto isto pode ser
 mudado. Para isso, basta-nos usar as seguintes linhas de             For
 código.
                                                                      Muitas vezes podemos querer mostrar uma lista, ou algo
  $smarty->left_delimiter = "({";
                                                                      cujo número de itens não é estático/previamente definido.
  $smarty->right_delimiter = "})";
                                                                      Isso significa que temos de usar ciclos no próprio template
Podemos personalizar os delimitadores que quisermos.                  para percorrer um array fornecido pelo script PHP. Para
Os delimitadores servem para delimitar cada tag Smarty,               isso usamos o ciclo for ou o foreach.
pelo que cada tag Smarty imprime o valor de uma variável              A sua sintaxe é a seguinte:
ou chama uma determinada função. Essa função pode ser
                                                                        {for $index=1 to 20 max=3}
interna, ou seja, definida pelo próprio Smarty, ou externa,
                                                                         - {$index}<b />
definida por nós e criada através de plugins. Aqui vamos
                                                                        {forelse}
ver algumas das funções internas do Smarty, mas também
                                                                        Sem items.
algumas funções externas que vêm já definidas com o
                                                                        {/for}
motor.
                                                                      Isto irá imprimir:

                                                                         - 1<br />
Variáveis
                                                                         - 2<br />
                                                                         - 3<br />
As variáveis são, provavelmente, a coisa mais simples,
básica e necessária para o Smarty, pois elas são o método             O parâmetro max é opcional, e o bloco do forelse também.
convencional e mais usado para introduzir dados no                    Este é mais importante quando temos valores dinâmicos no
template, e consequentemente, mostra-los. As variáveis                inicio e no fim do ciclo, pois estes podem ser nulos ou
para o Smarty, no PHP, podem ser definidas usando a                   inválidos (o inicio ser maior que o fim).
seguinte função.
  $smarty->(“nome”, $conteudo);



                                                                 43
A PROGRAMAR
Sm a rty PH P Te m p l a te E n gi n e


                                                                 da estrutura condicional, podem visitar aqui 2).
Foreach
O foreach é mais indicado quando o próprio PHP nos
retorna um array. Este pode ou não ser associativo. Por          Cycle
exemplo, para imprimir um array associativo, definimos no
PHP:                                                             Esta é uma função muito útil que permite obter valores de
                                                                 forma cíclica. Por exemplo, temos um ciclo for com 1 0
  $utilizador = array('Nome Real' => 'Pedro                      iterações, e temos uma função cycle com 3 valores, por
  Silva', 'Nickname' => 'Scorch', 'E-mail' =>                    exemplo: Um, Dois e Três, ou seja, ele vai obter os valores
 'xpto@email.net');                                              pela seguinte ordem: Um Dois Três Um Dois Três Um Dois
  $smarty->assign('utilizador', $utilizador);                    Três Um. Mas vamos ver um exemplo.
Depois escrevemos o seguinte código no template:
                                                                  {for $index=1 to 20 max=3}

  {foreach $utilizador as $var}                                     - {cycle name="ciclo_1"

  <b>{$var@key}:</b> {$var}<br />                                 values="Um,Dois,Três"}

  {/foreach}                                                      <b />
                                                                  {/for}

Isto irá imprimir:
                                                                 O parâmetro name é opcional, e permite-nos ter mais que
  <b>Nome Real:</b> Pedro Silva<br />                            um ciclo ao mesmo tempo. O parâmetro values deve conter
  <b>Nickname:</b>Scorch<br />                                   os valores a percorrer, separados por vírgulas e sem
  <b>E-mail:</b>xpto@email.net<br />                             espaços. Apesar da vírgula ser o valor por defeito, pode-se
                                                                 sempre definir um separador através do parâmetro
A lógica é muito similar à do PHP.                               delimiter. O conjunto de todos os parâmetros pode ser visto
                                                                 aqui 3).
                                                                 Esta função é particularmente interessante quando
If, Elseif e Else                                                imprimimos os dados numa tabela ou noutra forma
                                                                 qualquer de listagem, e queremos que a cor de fundo, por
Como não podia deixar de ser, o Smarty suporta estruturas        exemplo, mude ciclicamente em cada item. Por exemplo, o
condicionais. Uma vez que os templates são compilados            primeiro ficará branco, o segundo cinzento, o terceiro
para scripts PHP, estas estruturas são extremamente              branco e o quarto cinzento, até ao fim da lista.
poderosas e muito similares às nativas do PHP. Este é um
exemplo simples:
                                                                 Conclusão
  {if $var == '1'}
  Condição if verdadeira.
                                                                 Smarty é um sistema de templates em PHP, que permite
  {elseif $name == '2'}
                                                                 uma variedade enorme de funcionalidades e tem uma
  Condição elseif verdadeira.
                                                                 grande performance, uma vez que os templates são
  {else}
                                                                 convertidos para código PHP.
  É o que sobra.
                                                                 A lista completa de funções e documentação pode ser
  {/if}
                                                                 encontrada aqui 4), em Inglês.
Para uma lista completa de exemplos e das propriedades


                                                            44
A PROGRAMAR
                                                                                            S m a rty PH P Te m p l a te E n gi n e




                                  Exemplo do funcionamento de uma aplicação a usar Smarty


1 ) http://smarty.net/download
2) http://smarty.net/docs/en/language.function.if.tpl
3) http://smarty.net/docs/en/language.function.cycle.tpl
4) http://smarty.net/docs/en/index.tpl




                                                                  Link para o artigo: http://tinyurl.com/RPED28-1 0

 AUTOR

                    Escrito por Pedro Silva
                    Estudante, é um apaixonado por computadores e tecnologia. Gosta de Web Development, sendo a área
                    onde se inicou na programação. Também trabalha com várias tecnologia .NET.
                    Gosta também de multimédia, desporto e fotografia. É membro do staff da comunidade Portugal-a-
                    Programar, e autor de um blog: Blog / @Scorchpt




                                                             45
Revista programar 28
COLUNAS
CORE DUMP - O X No Quadrado Certo
VISUAL (NOT) BASIC - Entity Framework 4:Model/Code-First
CORE DUMP

O X N o Qu a d ra d o C e rto
O tema da escolha da universidade é um tópico sazonal e
recorrente no P@P, dando aso a vários tópicos e, como é
natural, a opiniões opostas.

Sendo um participante assíduo dessas discussões, e
estando na altura de pensar de forma clara e séria qual a
universidade a escolher, vou partilhar aqui a minha opinião
como profissional e empregador na área das Tecnologias
de Informação (TI).

Mas antes, comecemos pelo senso comum. Parece-me
pacífico que um candidato escolha determinada instituição
por vários parâmetros, sendo um deles o da preparação
para o mercado de trabalho. Diz-nos o bom senso que
optando por uma instituição que é reconhecida como boa                 instituição onde se licenciaram não é um dos pesos fortes
pelo mercado de trabalho, a presença de um curso superior              no mercado. Acontece que essa situação não é um contra-
no Curriculum Vitae (CV) de um candidato é um bom cartão               exemplo do que se passa. As empresas de RH vivem da
de visita para ser chamado para uma entrevista.                        colocação de pessoas em empresas, pelo que é do seu
                                                                       interesse entrevistas todas as pessoas e tentar colocá-las
 Quem não tem experiência profissional foca de forma                   numa empresa, esse é o seu negócio. Há empresas, e
 quase exclusiva todos os créditos que tem para apresentar             actividades, onde a formação de base não requer uma
 a um empregador no seu percurso académico. Neste                      preparação tão exigente, fazendo com que esses
 ponto, o nome da instituição que consta no CV do                      candidatos sejam boas escolhas, ficando contentes as três
 candidato é um bom cartão de visita e funciona como                   partes envolvidas.
 primeiro filtro. Este primeiro filtro é normalmente usado para
 fazer duas pilhas de CV, separando os candidatos cujo CV              Uma vez passado o choque, voltemos ao essencial:
 vamos ler com atenção dos candidatos que ficam                        quando enviam um CV em que pilha é que querem que
 eliminados logo na primeira ronda. Para os que estão                  o mesmo seja colocado? A resposta a esta pergunta
“chocados” ou “revoltados” com esta abordagem crua e até,              começa muitos anos antes da larga maioria das pessoas
 de certa forma, cruel, tenho apenas a dizer que da mesma              escrever o seu primeiro CV, começa quando colocam o X
 forma que eu uso a instituição como primeiro filtro, também           no quadrado certo, no quadrado que vos vai permitir ser
 as empresas de recursos humanos (RH) o fazem. E não                   reconhecidos pelo mercado como estando, à partida, mais
 somos os únicos. Este tipo de abordagem é normal para as              bem preparados. A verdade é que o mercado sabe muito
 empresas que operam nesta área.                                       bem quem são as instituições que melhor preparam as
                                                                       pessoas para a vida profissional, e tipicamente isso é
Há alguns dias atrás (re)confirmei esta situação numa                  valorizado. Para os que se lembram do tempo da bolha,
reunião com uma empresa de RH no âmbito do                             nessa altura quase qualquer um podia ingressar e fazer
recrutamento de um consultor. Nesta altura muitos de vós               uma carreira em TI, tal era a necessidade de recursos que
estão a pensar que isto não é verdade porque têm                       as empresas, em particular as consultoras, tinham. Mas
conhecimento de pessoas que foram a entrevistas e cuja                 esses tempos já lá vão, e num mercado cada vez mais


                                                                  48
CORE DUMP
                                                                                                  O X N o Qu a d ra d o C e rto


difícil e num país com uma taxa de desemprego tão                não têm curso superior. Para todos os que não têm curso
elevada, todos os argumentos são preciosos, e um carimbo         superior e querem ingressar nesta vida, as dificuldades são
de uma instituição reconhecida pelo mercado tem bastante         acrescidas. No entanto há outras formas de começar. No
peso.                                                            que toca à parte técnica e tecnológica é fácil encontrar
                                                                 informação e estudar por si mesmo ou tirar cursos ou
Com a introdução do regime de Bolonha, algumas                   mesmo certificações. No entanto não se devem ter ilusões,
empresas viram essa situação como um retrocesso                  mesmo assim será mais difícil iniciar uma carreira em TI. É
educativo na preparação dos estudantes para o mercado            que ao contrário do que muitos jovens pensam, numa
de trabalho. Para garantir o mesmo nível de preparação,          licenciatura de informática não se ensina a programar.
essas mesmas empresas passaram a exigir aos seus                 Os conhecimentos adquiridos ao longo do curso são muitos
candidatos não uma licenciatura mas sim um mestrado. O           e variados, alguns até são de utilidade duvidosa, mas são
mestrado é uma boa forma de aumentar os conhecimentos            valiosos. Essencialmente uma licenciatura ensina a pensar,
mas é também uma forma das empresas darem menos                  a analisar, ensina a descobrir soluções e alarga os
peso à instituição onde um candidato se licenciou. No            horizontes dos estudantes, fazendo com que estes tenham
entanto, as regras são as mesmas da licenciatura, o valor        contacto com imensas coisas novas e diferentes. Numa
do carimbo das instituições que ministram mestrados têm          comparação directa, não é de estranhar que quem saia de
pesos diferentes no mercado de trabalho. O mestrado              uma universidade reconhecida pelo mercado tenha mais
proporciona também uma especialização e uma maneira de           facilidade de encontrar um bom emprego e de fazer carreira
preparar o direccionamento da carreira em TI. Estas duas         em TI.
vantagens são muito interessantes tanto para para as
empresas, que valorizam os seus recursos e investem na           Se após toda a minha argumentação não estão
investigação e desenvolvimento, como para os candidatos,         convencidos, então guiem-se pelo vosso bom senso. Esse,
que podem querer evoluir por uma vertente mais                   aposto que vos diz para colocarem os X nos quadrados
estimulante para si.                                             certos quando preenchem o formulário de candidatura ao
                                                                 ensino superior.
Nesta altura alguns já se estão a questionar sobre os que




                                                                 Link para o artigo: http://tinyurl.com/RPED28-09

 AUTOR

                   Escrito por Fernando Martins
                   Faz parte da geração que se iniciou nos ZX Spectrum 48K. Tem um Mestrado em Informática e mais de
                   uma década de experiência profissional nas áreas de Tecnologias e Sistemas de Informação. Criou a sua
                   própria consultora sendo a sua especialidade a migração de dados.




                                                            49
VISUAL (NOT) BASIC

E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst

Existem três tipos de abordagens quando estamos a utilizar         necessário, reutilizar em diferentes projectos.
Entity Framework 4.0: database­first onde são criadas as
nossas entidades (classes) usando uma base de dados já             Para a criação do nosso modelo, numa abordagem model­
existente; model­first onde é criado o nosso modelo                first, criamos um novo projecto no Visual Studio 201 0
conceptual e, com base nele, é gerado um script para a             definindo como Framework a 4.0, e com o nome
criação da base de dados; e code­first onde é utilizado            “RevistaClassLibrary”.
POCO (Plain Old Code CRL) para criação manual de toda
a lógica de entidades e ligações, não perdendo no entanto,
todas as vantagens da utilização do Entity Framework.

Na edição da Revista PROGRAMAR nº 26, de Dezembro
de 201 0, abordei a utilização do modelo database­first,
mostrando como criar as entidades e como efectuar
algumas operações CRUD (acrónico para Create, Read,
Updade e Delete).

Neste artigo irei abordar de uma forma geral como utilizar
as restantes abordagens: model­first e code­first.

Abordagem Model-First

Esta abordagem permite-nos criar o nosso modelo                    NOTA: Após o projecto criado podemos apagar a classe
conceptual, usando o Visual Studio, e depois, com base             que aparece por defeito (Class1 .vb) pois não será
neste, criar a base de dados. Após a criação do modelo é           necessária.
criada a DDL (Data Definition Language), que será
guardado num ficheiro *.sql e que nos permite então criar a        Adicionamos um novo item, recorrendo aos templates no
base de dados.                                                     separador Data - ADO.NET Entity Data Model. Esta opção,
                                                                   que iremos definir com o nome RevistaModel.edmx, irá
Existem algumas vantagens desta abordagem pois é uma               criar um ficheiro *.edmx que irá representar o nosso
forma de trabalhar onde temos o nosso modelo e não nos             modelo.
precisamos de preocupar com a base de dados ou como
esta irá ser construída. Não necessitamos também de ter
conhecimentos muito específicos de bases de dados (como
criar tabelas, relações, etc.), sendo tudo feito no Visual
Studio de uma forma simplificada. Além disso, ficamos com
o DDL que nos permite criar a base de dados em qualquer
altura (por exemplo após a instalação da aplicação).

Neste exemplo será criada uma Class Library, permitindo
assim isolar a lógica de acesso a dados e, caso seja

                                                              50
VISUAL (NOT) BASIC
                                                                      E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst



                                                                   Ainda antes de iniciarmos a construção do nosso modelo
O *.edmx é um ficheiro XML que define o modelo                     conceptual, existe uma opção interessante, se olharmos
conceptual, o modelo de dados e as relações entre as               para a janela das propriedades: Pluralize New Objects.
diferentes entidades.                                              Esta opção, caso esteja definida como verdadeira (True),
                                                                   irá automaticamente tentar pluralizar os nomes das
Na seguinte opção, podemos escolher se queremos gerar              entidades. Infelizmente não funciona na versão Portuguesa,
um modelo de uma base de dados, como foi abordado no               mas se utilizarmos designações em Inglês, é muito
artigo anterior na Revista PROGRAMAR edição 26, ou criar           interessante e prática.
um modelo vazio. Iremos escolher a segunda opção –
Empty model.                                                       Para este exemplo vamos então criar um modelo muito
                                                                   simplificado que permita representar as edições da revista
                                                                   PROGRAMAR. Vamos criar duas entidades que vão
                                                                   representar os artigos e os seus autores.




Com o nosso documento criado, ainda vazio, existem duas
ferramentas importantes para o desenvolvimento do                  Por defeito, quando criamos uma nova entidade, ele inclui a
modelo: a Toolbox, que tem agora objectos específicos para         criação de um identificador (chave primária), que podemos,
o Entity Framework e o Model Browser que permite                   caso não seja necessário, retirar. Não define também
explorar o nosso modelo. Existem duas formas de criar o            nenhuma herança, podendo esta ser indicada no “Base
modelo: através da Toolbox, já referida anteriormente, ou          Type”, ou seja, podemos definir heranças entre entidades,
clicando com o botão direito do rato sobre a janela aberta.        seleccionado a entidade correspondente.
Esta segunda opção é mais simples de utilizar.
                                                                   Adicionando algumas propriedades, e definindo os tipos de
                                                                   dados correctos (ex. DataNascimento = DateTime ou
                                                                   Edicao = Int32), rapidamente construímos os modelos para
                                                                   representar as edições da revista. De notar que por defeito,
                                                                   quando é adicionada uma nova propriedade à entidade, o
                                                                   tipo de dados está definido como String, com um tamanho
                                                                   de armazenamento máximo para este tipo de dados (2^3-1 )
                                                                   - nvarchar(max). Podemos e devemos alterar, caso seja
                                                                   necessário, assim como explorar e ajustar as restantes
                                                                   propriedades, como por exemplo, o tamanho máximo para

                                                              51
VISUAL (NOT) BASIC
E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst



uma String (Max Lenght), qual o valor por defeito (Default
Value), se permite valores nulos (Nullable), etc.

E já estão então criadas as duas entidades e neste




                                                                            o fazer é só necessário clicar com o botão direito do rato
                                                                            sobre o editor e seleccionar a opção “Generate Database
                                                                            from Model”.
                                                                            Irá então aparecer um wizard que nos permite seleccionar
                                                                            uma ligação já existente ou criar uma nova.

momento só nos falta definir a relação entre ambas. Como
um artigo pode ter vários autores e um autor pode ter vários
artigos, necessitamos de criar uma relação muitos para
muitos (many-to-many).

Ao adicionarmos a relação entre as entidades, usando a
opção Association, é criado um novo campo no final,




                                                                            Seleccionado a ligação que pretendemos, irá ser gerado
                                                                            um script DDL que permitirá, após execução, criar uma




designado por Navigation Property, que irá permitir a
navegação entre as entidades. Podemos alterar o nome da
propriedade de navegação (caso seja necessário).

E já está! Este foi o último passo para criar o modelo
conceptual e é agora altura de gerar a base de dados. Para

                                                                       52
VISUAL (NOT) BASIC
                                                                     E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst



base de dados em SQL Server 2005, 2008 e Azure.                   Project) e a System.Data.Entity (separador .NET). É
                                                                  necessário também copiar a Connection String, que se
                                                                  encontra no ficheiro de configuração (app.config), uma vez
                                                                  que esta foi definida na Class Library, no momento de
                                                                  ligação à base de dados.
                                                                   <connectionStrings>
                                                                   <add name="RevistaModelContainer"
                                                                   connectionString="metadata=
                                                                   res://*/RevistaModel.csdl|
                                                                   res://*/RevistaModel.ssdl|
                                                                   res://*/RevistaModel.msl;
                                                                   provider=System.Data.SqlClient;provider
                                                                   connection string=&quot;Data Source=.;Initial
                                                                   Catalog=master;Integrated Security=True;
                                                                   MultipleActiveResultSets=True&quot;"
                                                                   providerName="System.Data.EntityClient" />
                                                                      </connectionStrings>
Reparem que apenas criamos duas entidades (autores e
artigos), mas como definimos uma relação muitos para
muitos (many-to-many), é necessário utilizar uma tabela           A Connection String tem um conjunto de metadata que
auxiliar. O Entity Framework fez isso por nós e no SQL            indica a localização do ficheiro de CSDL (Conceptual
ficamos então com três tabelas, como mostra a seguinte            Schema Definition Language), do SSDL (Store Schema
imagem:                                                           Definition Language) e do MSL (Mapping Schema
                                                                  Language). O asterisco (*) indica que estes ficaram
                                                                  embebidos no ficheiro binário, podendo isto ser alterado,
                                                                  indicando nas propriedades do modelo conceptual, que o
                                                                  Metadata Artifact Processing não esta Embed in Output
                                                                  Assembly mas sim Copy to Output Directory. Indica depois
                                                                  a ligação propriamente dita à base de dados.

                                                                  Abordagem Code-First

                                                                  Esta é outra abordagem que podemos utilizar em Entity
                                                                  Framework, além das já referidas neste artigo (model­first)
Se no Solution Explorer escolhermos a opção “Show All             e no artigo da edição 26 da revista PROGRAMAR
Files”, podemos ver que o nosso modelo (*.edmx) tem um            (database­first).
ficheiro com a extensão *.vb (neste caso                          Uma das vantagens do code­first (ou como é também
RevistaModel.Designer.vb) . Neste ficheiro podemos ver e o        designado code­only), utilizando POCO (Plain Old CLR
código que está por detrás do nosso modelo conceptual, e          objects ), é que não ficamos “presos” ao Entity Framework,
efectuar eventualmente, algumas alterações.                       pois todas as classes geradas automaticamente herdam da
 Ao adicionarmos um novo projecto a esta solução (*.sln),         classe EntityObject. Além disso utilizamos as classes que
que irá representar a camada de apresentação                      queremos, com muito menos código (um exemplo mesmo
(Presentation Tier), ou usando externamente, é necessário         pequeno como este tem mais de 300 linhas de código), o
adicionar referências à classe que criamos (separador             torna a manutenção da aplicação muito mais simples.

                                                             53
VISUAL (NOT) BASIC
E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst



                                                                                Public Property Id As Integer
Para usar esta abordagem, onde somos nós que
                                                                                Public Property Nome As String
desenhamos as classes que vão representar as entidades,
                                                                                Public Property DataNascimento As DateTime
podemos seleccionar o nosso modelo conceptual (*.edmx)
e na janela de propriedades, na opção “Code Generation
                                                                                 ' Overridable para permitir o LazyLoading
Strategy”, que está definida para Default, seleccionamos
                                                                                 Public Overridable Property Artigos() As
None. Isto fará com que o código gerado automaticamente
                                                                             ICollection(Of Artigo)
seja apagado, possibilitando desta forma o
desenvolvimento personalizado.
                                                                                Sub New()
                                                                                  Artigos = New List(Of Artigo)
Para representar o modelo conceptual mostrando
                                                                                End Sub
anteriormente, e tendo em conta que este é um exemplo
                                                                             End Class
muito simples (para efeitos de demonstração apenas),
necessitamos apenas de três classes: Artigo, Autor e
RevistaModelContainer.
                                                                            IMPORTANTE : A declaração de variáveis em Visual Basic
                                                                            não é, como sabem, case sensitive. No entanto, na
As duas primeiras classes ( Artigo e Autor), vão representar
                                                                            declaração das propriedades das entidades (classes) é
as duas entidades e definem as propriedades da classe e a
                                                                            obrigatório que se declarem de acordo com o modelo
associação entre ambas (usando uma ICollection).
                                                                            (*.edmx), ou seja, há distinção entre maiúsculas e
Podemos ter mais propriedades e mais métodos nas
                                                                            minúsculas.
classes, mas para que isto funcione, temos de ter pelo
menos as que estão definidas no modelo.
                                                                            A terceira classe é onde se define o nosso Container, que
                                                                            herdas do ObjectContext, ou seja, é onde criamos a ligação
  Imports System.Collections
                                                                            entre o Entity Framework e as nossas classes anteriores. O
  Imports System.Data.Objects
                                                                            ObjectSet é novo na versão 4.0 do Entity Framework e
                                                                            permite-nos trabalhar os dados como colecções, permitindo
  Public Class Artigo
                                                                            também executar queries.
     Public Property Id As Integer                                           Public Class RevistaModelContainer
     Public Property Titulo As String                                           Inherits ObjectContext
     Public Property Texto As String
     Public Property Edicao As Integer                                          Sub New()


      ' Overridable para permitir o LazyLoading                                   ' Indica a ConnectionString (ver em
       Public Overridable Property Autores() As                                   ' app.config) e nome do Container
  ICollection(Of Autor)                                                             MyBase.New("name=RevistaModelContainer",
                                                                             "RevistaModelContainer")
     Sub New()
        Autores = New List(Of Autor)                                              ' Cria as instancias dos ObjectSets
     End Sub                                                                      _Artigos = MyBase.CreateObjectSet(Of
                                                                                             Artigo)("Artigos")
  End Class                                                                       _Autores = MyBase.CreateObjectSet(Of
                                                                                             Autor)("Autores")
  Public Class Autor


                                                                       54
VISUAL (NOT) BASIC
                                                                  E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst


          ' Define que o LazyLoading está                      Por isso o Entity Framework permite a utilização/criação de
          ' activo (por defeito não está)                      templates que geram o código por nós. São designados por
         MyBase.ContextOptions.LazyLoadingEnabled              T4 (Text Template Transformation Toolkit) Text Templates e
 = True                                                        são ficheiros de texto com uma extensão *.tt .

   End Sub                                                     Existe um template para a criação de classes POCO. Não
                                                               está disponível nos templates do Visual Studio 201 0, mas
   Private _Artigos As ObjectSet(Of Artigo)                    se abrirmos o modelo conceptual e seleccionarmos “Add
   Public ReadOnly Property Artigos()                          Code Generation Item”, podemos pesquisar em "Online
                            As ObjectSet(Of Artigo)            Templates" e instalar.
   Get
          Return _Artigos
      End Get
   End Property


   Private _Autores As ObjectSet(Of Autor)
   Public ReadOnly Property Autores()
                             As ObjectSet(Of Autor)
      Get
          Return _Autores
      End Get
   End Property


 End Class


Como é possível ver neste codigo, habilitamos a opção
LazyLoadingEnable do ObjectContext, colocando-a a True.        Após a rápida instalação, podemos então seleccionar
É necessário também definir as propriedades como               ADO.NET POCO Entity Generator.
Overridable para que o Entity Framework saiba que
propriedades usar. O Lazy Loading permite que as
entidades relacionadas sejam automaticamente carregadas
da fonte de dados quando acedemos às propriedades de
navegação (neste caso Autores e Artigos).

E é tudo! Com poucas linhas de código criamos as nossas
classes, que definem as nossas entidades, e criamos o
nosso Container que permite interligar as classes com o
Entity Framework.

Mas este é apenas um exemplo bastante simples e caso
usássemos um modelo complexo, com inúmeras entidades
e associações, era muito trabalhoso criar todas estas          Isto irá adicionar dois ficheiros *.tt ao projecto:
classes POCO.                                                  POCOModel.tt e POCOModel.Context.tt. O POCOModel
                                                               tem as classes que representam as entidades e o

                                                          55
VISUAL (NOT) BASIC
E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst



POCOModel.Context tem as classe de contexto.                                principal novidade a DbContext API, que é uma abstracão
                                                                            simples do ObjectContex e que pode ser utilizada em
                                                                            qualquer abordagem (Database­First, Model­First e Code­
                                                                            First). Existe também algumas alterações na abordagem
                                                                            Code-First.

                                                                            Alguns endereços interessantes :

                                                                            ADO.NET team blog
                                                                            http://blogs.msdn.com/b/adonet/

NOTA: Ao adicionarmos os templates ao projecto, todo o                      Beginner's Guide to the ADO.NET Entity Framework
código de Entity Framework será apagado.                                    http://msdn.microsoft.com/en-us/data/ee71 2907

Desta forma, e muito rapidamente, criamos as nossas                         EF 4.1 Release Candidate Available
classes POCO com a ajuda de templates.                                      http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 -
                                                                            release-candidate-available.aspx
Como foi possível ver ao londo deste artigo, e do artigo da
edição nº 26 da revista PROGRAMAR, existem diferentes                       EF 4.1 Model & Database First Walkthrough
abordagens para a utilização do Entity Framework 4.0,                       http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 -
permitindo criar um modelo relacional de uma base de                        model-amp-database-first-walkthrough.aspx
dados, criar um modelo e com base neste criar a base de
dados ou criando as nossas classes (entidades) usando                       EF 4.1 Code First Walkthrough
POCO, ficando desta forma independentes e com a                             http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 -
possibilidade de uma maior personalização de toda a                         code-first-walkthrough.aspx
lógica. A existencia e utilizaçao de templates permite
simplificar o processo de criação de classes POCO e
podemos inclusivé criar os nossos próprios templates.

No momento da criação deste artigo está já disponível o
Entity Framework 4.1 Release Candidate que tem como

                                                                            Link para o artigo: http://tinyurl.com/RPED28-01

 AUTOR

                        Escrito por Jorge Paulino
                        Exerce funções de analista-programador numa multinacional sediada em Portugal. É formador e ministra
                        cursos de formação em tecnologias Microsoft .NET e VBA. É Microsoft Most Valuable Professional (MVP),
                        em Visual Basic, pela sua participação nas comunidades técnicas . É administrador da Comunidade
                        Portugal-a-Programar e membro de várias comunidades (PontoNetPT, NetPonto, MSDN, Experts-
                        Exchange, CodeProject, etc). É autor do blog http://vbtuga.blogspot.com - twitter @vbtuga




                                                                       56
COMUNIDADES
AndroidIPC - Inter Process-Communication
Automatização de deployments em Windows Azure
COMUNIDADE ANDROIDPT

An d ro i d I PC - I n te r Pro c e s s - C o m m u n i c a ti o n
As aplicações de Android correm sobre uma máquina virtual            Language). Esta linguagem tem uma sintaxe bastante
de Java, de nome Dalvik. Uma das particularidades desta              simples, e consiste apenas na declaração da assinatura
máquina virtual, é que as aplicações estão limitadas a uma           dos métodos responsáveis pela comunicação.
Sandbox de execução, ou seja, o seu espaço de memória é
privado. Este sistema é muito semelhante ao                          A título de exemplo, vamos produzir 2 aplicações muito
comportamento as aplicações nativas do sistema operativo             simples, de nomes appA e appB, que comunicarão entre si.
subjacente do Android, o GNU/Linux.                                  A appA enviará uma mensagem à appB com o pedido para
                                                                     calcular o produto de 2 números inteiros. A appB receberá
 Uma das consequências disto, é que a troca de informação            estes parâmetros na mensagens, e devolverá o resultado
 entre aplicações excluí logo à partida a partilha de                do produto dos mesmos. Apesar da simplicidade do
 informação através de memória partilhada. O que resta, é a          exemplo, servirá para demonstrar os problemas envolvidos
 troca de mensagens entre aplicações.                                na produção da solução, tais como, o que fazer quando a
 O Android fornece vários mecanismos para envio de                   aplicação com que estamos a comunicar não existe.
 mensagens entre aplicações, alguns são mais apropriados
 que outros, dependendo do cenário de utilização. Temos
 por exemplo os BroadcastReceivers, que se tratam de                 O primeiro passo será definir o ficheiro AIDL. Este ficheiro
 classes que recebem informação que é enviada para o                 contém a definição da função que a appA irá chamar.
 sistema operativo, e este trata de retransmitir a informação
 para as várias aplicações que se registaram como                     package ipc;
“Receivers” para esse tipo de informação.
 Este método não é o ideal em muitos casos, veja-se por               interface ServicoIPC {
 exemplo que a informação fica passível a ser enviada para            int multiplicar(in int num1, in int num2);
 várias aplicações e não só para uma, e que a comunicação             }
 é só numa direcção, ou seja, a mensagem é enviada,
 recebida, mas não há sequer confirmação de que a mesma              Repare que ambos os argumentos têm o prefixo “in”. Isto
 foi recebida, nem é possível retornar qualquer tipo de              faz parte da especificação AIDL, neste caso é “in” porque
 informação. Existe ainda o senão de que num ambiente em             estamos a lidar com tipos de dados simples de Java, e
 que existe mais que um BroadcastReceiver, o sistema                 esses apenas podem ser do tipo “in”.
 operativo envia a informação para a 1 ª aplicação, e se esta
 assim decidir pode consumir a mensagem e não a passar               O ficheiro que contem o código em cima especificado
 de volta para as seguintes.                                         deverá estar presente tanto na appA como na appB, na
                                                                     pasta src ou em dentro de qualquer package dentro da
Para resolver, este e outros cenários, a SDK fornece um              mesma. O ficheiro terá obrigatoriamente de ter a extensão
mecanismo de troca de mensagens entre aplicações, aquilo             .aidl , uma vez que em tempo de compilação estes ficheiros
que usualmente se chama de IPC (InterProcess-                        são tratados de forma especial atendendo à sua extensão.
Communication).
                                                                     Do lado da appB, que é aplicação que irá receber a
Este mecanismo é apoiado por uma linguagem de ligação                mensagem, e fazer o cálculo, temos de declarar um Service
das duas aplicações que queremos que comuniquem entre                de Android para lidar com a recepção da mensagem. O
si, chamada de AIDL¹ (Android Interface Definition                   código em baixo apresentado ilustra esta situação.


                                                                58
COMUNIDADE ANDROIDPT
                                                                                                               An d ro i d I PC



                                                                  ...
 package com.exemplo.appb;
                                                                  <application …>
                                                                             <service android:name="ServicoRemoto"
 import android.app.Service;
                                                                  android:process="com.exemplo.appb.SetPrefsSer
 import android.content.Intent;
                                                                  vice">
 import android.os.IBinder;
                                                                                     <intent-filter>
 import android.os.RemoteException;
                                                                                             <action
 import android.util.Log;
                                                                  android:name="com.exemplo.appb.IPC" />
                                                                                     </intent-filter>
 public class ServicoRemoto extends Service {
                                                                                     </service>
                                                                  </application>
     @Override
                                                                  ...
     public void onCreate() {
         super.onCreate();
     }
                                                                 Do lado da appA, temos agora de efectuar a ligação com a
                                                                 appB. Primeiro temos de garantir que temos o ficheiro .aidl
     @Override
                                                                 na árvore de fonte de código da mesma, como já tinha sido
     public IBinder onBind(Intent intent) {
                                                                 referido. É importante também garantir que o ficheiro AIDL
                                                                 esteja na mesma package de Java em ambas as
         return new ServicoIPC.Stub() {
                                                                 aplicações.
                                                                 Por motivos de escalabilidade convém separar a lógica da
              /**
                                                                 ligação e do envio da mensagem, do resto do código, assim
                  * Método que calcula o produtor de num1
                                                                 fica mais simples usar e manter o uso da comunicação
 com num2
                                                                 inter-procedual conforme a aplicação vai crescendo.
                  */
                                                                 Para tal, vamos fazer uma classe que implementa o
                   public int multiplicar(int num1, int
                                                                 ServiceConnection. O seguinte código exemplifica uma
 num2) throws RemoteException {
                                                                 classe deste género. Note-se que seria nesta classe que o
                        Log.d("appB","A appB recebeu um
                                                                 programador pode gerir os pedidos, a altura em que são
 mensagem para calcular o produto de "+num1+"
                                                                 enviados, possíveis filas de prioridade de pedidos, etc.
 com "+num2);
                   return num1 * num2;
              }                                                   package com.exemplo.appa;


         };
     }                                                            import android.content.ComponentName;
 }                                                                import android.content.ServiceConnection;
                                                                  import android.os.IBinder;
                                                                  import android.os.RemoteException;
                                                                  import android.util.Log;
Após isto, temos obviamente de adicionar o Service criado
em cima ao Manifest da aplicação, neste caso da appB. É
                                                                  public     class     ConServicoRemoto       implements
também aqui que vamos expor o Service ao exterior.
                                                                  ServiceConnection{
Fazemos isso adicionando as linhas coloridas ao ficheiro
AndroidManifest.xml :
                                                                           ServicoIPC service = null;



                                                            59
COMUNIDADE ANDROIDPT
An d ro i d I PC



             private boolean estaVivo= false;                            appB");
                                                                                               estaVivo=true;
                                                                                   }
             /**
                 * Constructor.                                                    @Override
                 */                                                                public                                         void
             public ConServicoRemoto() {                                 onServiceDisconnected(ComponentName name) {
                         // construtor vazio                                                   service=null;
             }                                                                                 estaVivo=false;
                                                                                               Log.d("appA","Desconectou            da
                                                                         appB");
             public       int    adicionarRemoto(int    val1,                      }
  int val2){
                         if (service==null)                                        /**
                         {                                                             *
                                   Log.d("appA","O    Serviço                          *     @return   True    se   a   ligação    à 
  não    está         ligado.   Causa   possível:    appB    não         aplicação          appB   estiver    activa.   False     caso
  está instalada");                                                      contrário.
                                   return 0;                                           */
                         }                                                         public boolean ligacaoEstaActiva(){
                         try {                                                                 return estaVivo;
                                   return                                          }
  service.multiplicar(val1, val2);
                         } catch (RemoteException e) {                   }


  Log.d("appA","RemoteException ao tentar fazer
  pedido de multiplicar à  appB");
                                                                        Agora falta apenas fazer uma Activity de Android, ainda na
                                   e.printStackTrace();
                                                                        appA, a exemplificar o uso da classe acima declarada.
                                   return 0;
                         }
                                                                        Para a nossa Activity, declaramos na pasta “layout” o
                                                                        seguinte ficheiro main.xml que será a Interface Gráfica da
                                                                        mesma.
             }

                                                                         <?xml version="1.0" encoding="utf-8"?>
                                                                         <RelativeLayout
             @Override                                                   xmlns:android="http://schemas.android.com/apk
             public                                         void         /res/android"
  onServiceConnected(ComponentName                      name,                 android:orientation="vertical"
  IBinder boundService) {                                                     android:layout_width="fill_parent"
                         service                               =              android:layout_height="fill_parent"
  ServicoIPC.Stub.asInterface((IBinder)                                       >
  boundService);                                                              <EditText android:id="@+id/valor1"
                         Log.d("appA","Ligou-se         à 



                                                                   60
COMUNIDADE ANDROIDPT
                                                                                                             An d ro i d I PC


                                                              E por fim temos o código da classe de nome Principal que
    android:layout_width="60dip"
                                                              fará uso desta interface gráfica acima declarada, e da
        android:layout_height="wrap_content"
                                                              classe ConServicoRemoto.
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dip" />
                                                              Conclusão
        <EditText android:id="@+id/valor2"
                                                              Repare-se que o código é simplista, não existem
    android:layout_width="60dip"
                                                              verificações se o utilizador de facto escreve números
        android:layout_height="wrap_content"
                                                              inteiros, e não existe tratamento de erros na classe
        android:layout_below="@id/valor1"
                                                              ConServicoRemoto. Isso fica ao critério do leitor, uma vez
        android:layout_centerHorizontal="true"
                                                              que este exemplo está focado unicamente no tema
        android:layout_marginTop="50dip" />
                                                              abordado.

        <Button android:id="@+id/btn_calcular"
        android:layout_width="wrap_content"
                                                              Bibliografia
        android:layout_height="wrap_content"
        android:layout_below="@id/valor2"
                                                              1 . AIDL na documentação oficial da SDK de Android:
        android:layout_centerHorizontal="true"
                                                              http://developer.android.com/guide/developing/tools/aidl.htm
        android:layout_marginTop="50dip"
                                                              l
        android:text="Calcular"/>


        <TextView android:id="@+id/resultado"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"


android:layout_below="@id/btn_calcular"
        android:layout_marginTop="40dip"
        android:layout_centerHorizontal="true"
        android:text="O    resultado     aparecerá
aqui"
       />
</RelativeLayout>


                                                              Link para o artigo: http://tinyurl.com/RPED28-03

AUTOR

               Escrito por Pedro Veloso
               Licenciado em Ciências da Computação na Universidade do Minho, trabalha actualmente na EmergeIT.
               Desenvolve profissionalmente para Android, e tem interesse especial na área de Unix, em particular Linux,
               e administração de sistemas deste tipo. Faz parte integrante das comunidades androidPT e GTUG
               Portugal.




                                                         61
COMUNIDADE NETPONTO

Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re

Primeiro que tudo, e para que todos nos possamos
encontrar com a mesma base de conhecimento, parece-
nos importante contextualizar todos os leitores quanto ao
tema em questão.

O que é então Cloud computing?

Cloud computing é, numa definição abrangente, uma
abordagem à computação assente sobre os conceitos de
escalabilidade e alta disponibilidade de processamento e
armazenamento online, disponível a um inúmero número
de dispositivos e endpoints.                                       bloco possibilita também o acesso através de ligações
                                                                   remotas para as máquinas que estivermos a usar e a
Apresentando-se este como um mercado emergente e                   possibilidade de fazer uso de VPNs. De ressalvar que estas
potencialmente bastante rentável, principalmente porque o          redes virtuais não têm de ser apenas entre máquinas que
“factor custo” passa a ter um papel fulcral e preponderante        se encontram na cloud, mas podem também ser entre
nas decisões ao longo de todo o planeamento e                      máquinas que se encontram na cloud e máquinas que se
desenvolvimento aplicacional, algumas empresas de                  encontram on-premises.
referência na área das TI não poderiam ficar de fora da
corrida.                                                           Relativamente ao SQL Azure, este bloco possui a oferta da
                                                                   Microsoft ao nível dos sistemas relacionais de base de
Entre as várias ofertas que existem hoje no mercado,               dados. Esta versão é em tudo parecida com o SQL Server
parece-nos importar salientar o caso do Google App Engine          2008 R2, apresentando no entanto algumas restrições.
da Google, o AWS e o EC2 da Amazon, as inúmeras                    Neste momento encontram-se disponíveis dois tipos
ofertas da Rackspace ou mesmo da Salesforce, e                     (edições) de bases de dados que podemos criar num
finalmente o Windows Azure Platform da Microsoft. Será             servidor SQL Azure: Web Edition e Business Edition.
sobre esta última que focaremos as nossas atenções, sem
qualquer desprimor para as restantes ofertas mencionadas.          As diferenças fundamentais entre estas duas hipóteses
                                                                   pretendem-se com o tamanho máximo de uma base de
A plataforma oferecida pela Microsoft é composta então por         dados e com o custo associado às mesmas. As versões
três grandes blocos: Windows Azure, SQL Azure e                    Web são bases de dados que serão normalmente utilizadas
Windows Azure AppFabric.                                           para ambientes de baixos requisitos, pois possuem limites
                                                                   de 1 GB e de 5GB. Já as bases de dados associadas a
O Windows Azure disponibiliza capacidades de                       edições Business possuem limites máximos de 1 0GB,
computação e armazenamento escalável, elástico e                   20GB, 30GB, 40GB e 50GB e serão normalmente utilizadas
altamente disponível, bem como uma gestão                          para suporte a aplicações de negócio complexas (Line of
completamente automatizada dos serviços usados,                    Business Applications). Neste bloco encontram-se ainda
possibilitando realizar todas estas tarefas com recurso a          incluídos os sistemas de reporting e de sincronização de
ferramentas, tecnologias e linguagens de programação já            dados.
conhecidas pelos programadores. Além de tudo isto, este


                                                              62
COMUNIDADE NETPONTO
                                                                   Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re



Para por término a esta contextualização relativamente aos         permite-nos fazer uso de todo esse poder de
blocos disponíveis, falta pois falar do Windows Azure              processamento apenas quando tal é necessário, revertendo
AppFabric. Este bloco inclui então acesso a um Service             para máquinas com processamento mais limitado quando
Bus, a mecanismos de federação e controlo de acessos,              tal não se justifique. Tal capacidade permite ter alta
bem como a mecanismos de caching. Mais uma vez, todos              disponibilidade quando sabemos que vamos precisar dela e
estes mecanismos são geridos e mantidos de forma                   apenas pagar por a mesma durante o período de carência,
automatizada e não imputável a nós.                                ao contrário do que aconteceria num data center que
                                                                   tivéssemos de ser nós a dimensionar e a gerir.
Sendo que o objectivo deste artigo é falar sobre
automatização de deployments em Windows Azure, é                   Quando fazemos uso de uma máquina no Windows Azure,
imperativo regressarmos a este bloco para falarmos de              podemos fazer uso de três perfis de execução: Worker
forma mais aprofundada sobre o mesmo e sobre os                    Role, Web Role e VM Role. Uma Worker Role é
serviços que o compõem. O poder computacional                      essencialmente um executável que executa no servidor
disponível encontra-se seccionado em cinco segmentos               com as características que nós definirmos, permitindo desta
distintos: XS (Extra Small), S (Small), M (Medium), L              forma implementar os mais variados cenários, como seja a
(Large) e XL (Extra Large). Estes segmentos são                    disponibilização de servidores aplicacionais próprios,
progressivos, isto é, a capacidade computacional e de              Apache Tomcat, servidores de base de dados, entre muitas
armazenamento local em cada uma das máquinas incluídas             outras coisas.
vai aumentando de forma gradual.
                                                                   Uma Web Role goza de todas as potencialidades e
Uma instância XS possui processamento partilhado, 768MB            capacidades de uma Worker Role, mas encontra-se
de memória RAM e 20GB de armazenamento local,                      suportada no/pelo IIS (Internet Information Services),
apresentado um custo de $0.05 por cada período horário,            podendo correr em modo Full Trust ou Partial Trust. A VM
sendo que uma instância S possui já 1 CPU Core dedicado,           Role é o perfil adicionado mais recentemente à oferta que
1 .7GB de RAM e 250GB de armazenamento local,                      nos permite colocar uma imagem de um sistema operativo
apresentando um custo horário de $0.1 2. Se precisarmos            a executar no Windows Azure. Esta Role, ao contrário das
de uma máquina com 2 CPU Cores dedicados com 3.5GB                 restantes que são completamente geridas pela plataforma,
de RAM e 500GB de armazenamento, então o segmento M                deixa ao nosso cuidado tudo o que tem a ver com a gestão
será a resposta por um custo horário de $0.24. Se                  da máquina, desde actualizações ao sistema operativo a
precisarmos de capacidades de processamento e                      garantias de segurança da própria máquina e das
armazenamento superiores, poderemos então abordar as               instalações/actualizações nela efectuadas, pois somos nós
ofertas L ou mesmo XL. Uma máquina com o perfil L possui           quem controla tudo.
já 4 CPU Cores, 7GB de RAM e 1 TB de armazenamento
local, apresentando um custo horário de $0.48, sendo que           O Windows Azure dispõe de uma componente denominada
uma máquina com o perfil XL possui 8 CPU Cores, 1 5GB              Fabric que é responsável por toda a gestão de máquinas,
de RAM e 2TB de armazenamento, apresentando um custo               falhas e recuperações dos sistemas existentes na
horário de $0.96.                                                  plataforma.

Como podemos ver pelos dados fornecidos, a capacidade              Tendo isto em linha de conta, é importante pois perceber
computacional e de armazenamento local é efectivamente             qual é então o ciclo de vida das Roles que são geridas por
progressiva ao longo de todos os segmentos, bem como o             este Fabric, relembrando que nos referimos às Worker
custo associado a cada um deles. Se precisamos de mais             Roles e às Web Roles. Para melhor ajudar a compreender
processamento, o custo será necessariamente maior. No              todo este ciclo, apresenta-se então graficamente o mesmo:
entanto, sendo que a plataforma é totalmente elástica, isso

                                                              63
COMUNIDADE NETPONTO
Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re




                                                   Figura 1 – Ciclo de vida de uma Role


Uma Role tipicamente estende o RoleEntryPoint, passando                     que devem ser efectuados todos os processos de término
desta forma a poder ser envolvida em todo o ciclo de vida                   “gracioso” das aplicações que se encontrem a correr na
controlado pelo Fabric. Quando o processo WaWorkerHost                      Role, bem como a salvaguarda de todos os dados que
é iniciado (processo que representa a Role), dá-se o                        possam ser relevantes armazenar num armazenamento
carregamento do assembly associado a essa instância,                        persistente. Este armazenamento persistente pode ser uma
começando o Fabric por efectuar uma chamada ao método                       base de dados ou, tirando partido do Azure Storage que se
OnStart().                                                                  encontra incluído no Windows Azure, como Blobs.

Esta chamada faz com que o estado da instância seja                         Para melhor compreender como efectuar um deployment
colocado como Busy, o que significa que o Load Balancer                     no Windows Azure, teremos de analisar o que esse
do Azure não vai ter essa instância em conta quando                         processo envolve. Um serviço é então composto por dois
estiver a processar pedidos para serem respondidos                          artefactos primordiais: um ficheiro de definição do serviço
aplicacionalmente. É neste método que devem ser                             (*.csdef) e um ficheiro de configuração do serviço (*.cscfg).
efectuados todos os processos de automatização do                           Quando efectuamos a compilação de um projecto para
deployment, de forma a garantir que quando a instância for                  Windows Azure, o Visual Studio pega no código e ficheiros
colocada como disponível, todos os sistemas se encontram                    associados e no ficheiro de definição do serviço,
disponíveis e funcionais.                                                   embalando tudo num só pacote (*.cspkg), sendo que este
                                                                            ficheiro se encontra encriptado de forma a garantir a
O método seguinte a ser chamado pelo Fabric é o método                      segurança da informação nele contida.
Run(). Esta chamada faz com que o estado da instância
passe agora para Ready, significando isto que a instância                   De uma forma resumida, podemos ilustrar este processo
se encontra totalmente operacional e disponível para                        como:
atender a pedidos, passando desta forma a ter tida em
conta pelo Load Balancer quando este estiver a distribuir                   Encrypted( Zipped( Code + *.csdef ) ) == *.cspkg
carga pelas várias instâncias disponíveis. Se o método
Run() terminar, o Fabric invoca o método OnStop() da Role.                  Com este pacote disponível (*.cspkg) e com o ficheiro de
Esta chamada faz com que o estado da instância seja                         configuração (*.cscfg), podemos então dar início à criação
modificado novamente para Busy, sendo removida também                       e disponibilização de um novo serviço no Windows Azure.
da lista de instância disponíveis para o Load Balancer
poder utilizar para direccionar os pedidos. É neste método

                                                                       64
COMUNIDADE NETPONTO
                                                                  Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re




                             Figura 2 – Exemplo de um ficheiro de definição de serviço (*.csdef)




                           Figura 3 – Exemplo de um ficheiro de configuração de serviço (*.cscfg)




Tal como mencionado anteriormente, um deployment dito             teremos sempre de fazer build de um novo pacote de
“normal”, conterá em si todos os ficheiros necessários à          deployment. Esta situação pode não ser particularmente
disponibilização de uma dada aplicação/site. Apesar de            gravosa caso estejamos a falar de deployments de
esta ser a solução mais simples de todas, o seu custo de          pequena dimensão, mas caso estejamos a falar de pacotes
manutenção pode ser bastante elevado e penoso. Porquê?            de vários megabytes, a gravidade aumenta
                                                                  consideravelmente, podendo mesmo tornar-se num factor
Imaginemos que estamos a disponibilizar uma                       crítico.
aplicação/sistema que possui inúmeros ficheiros. Cada vez
que necessitarmos de efectuar uma modificação, por mais           Para aumentar a complexidade do caso em questão,
diminuta que ela seja e por menos ficheiros que envolve,          imaginemos agora que o sistema recorre a um ficheiro de
                                                             65
COMUNIDADE NETPONTO
Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re




configurações internas, ficheiro este que é específico para                 Uma das soluções possíveis pode passar pela
cada serviço que disponibilizarmos. Neste caso, além de                     disponibilização, em Azure Storage, de um arquivo
termos de lidar com o problema já mencionado                                comprimido com todos os ficheiros comuns necessários à
anteriormente, teremos ainda de lidar com a necessidade                     aplicação/sistema, bem como de um ficheiro de
de ter pacotes de deployments em tudo em tudo                               configuração por cada serviço existente. Desta forma, a
semelhantes, onde apenas esse ficheiro de configuração é                    Role, durante a chamada do Fabric ao seu método
diferente. Além do crescimento exponencial que se pode                      OnStart(), poderia contactar o armazenamento persistente
verificar ao nível da quantidade de pacotes necessários, há                 e descarregar e descomprimir os ficheiros comuns, bem
também de ter em conta a dificuldade de manutenção                          como o ficheiro de configuração da aplicação/sistema.
acrescida destes ficheiros.                                                 Desta forma, apenas seria necessário gerir um ficheiro
                                                                            comprimido partilhado por todos os serviços, minimizando
Poderemos        fazer    alguma     coisa   para                           assim a margem de erro e facilitando a sua manutenção.
minimizar/ultrapassar estas situações? Há alguma
solução “mágica”?                                                           A solução anterior apresenta ainda um enorme problema no
                                                                            caso de o arquivo partilhado ser consideravelmente grande,
A resposta à primeira pergunta é claramente afirmativa,                     pois quando maior for, mais tempo vai demorar a
sendo que não existem silver bullets para resolver este tipo                disponibilizar no armazenamento persistente. Esta
de problemas, apenas abordagens mais correctas ou                           dificuldade pode ser ultrapassada de uma forma mais ou
menos correctas, sendo que devem ser sempre analisadas                      menos simples através da existência de um mecanismo de
caso a caso.                                                                actualizações. Ou seja, além do arquivo inicial de que a
                                                                            Role faria uso, seriam também disponibilizados outros

                                                                       66
COMUNIDADE NETPONTO
                                                                      Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re



arquivos que permitiriam ir actualizando o sistema de forma           proceder a uma diminuição significativa dos custos
incremental e com recurso a arquivos de tamanho                       envolvidos em todo o processo, não só pela diminuição da
consideravelmente inferior. Não só diminuiríamos o tempo              largura de banda necessária para disponibilizar um novo
necessário à disponibilização de uma actualização, como               serviço, mas também pela redução do espaço necessário
aumentaríamos a facilidade de manutenção de todo o                    em Azure Storage para armazenar toda a informação.
sistema, pois disponibilizaríamos de um histórico fidedigno.

Há ainda um outro factor que nos deve incomodar e                     Páginas úteis:
preocupar: a necessidade da existência de um ficheiro de
configuração por cada serviço existente. A solução para               Microsoft Windows Azure Homepage
este problema passaria pela introdução neste ficheiro de              http://www.microsoft.com/windowsazure/
wildcards, como seja por exemplo o caso de
[database_name]. Esta wildcard permitiria à Role proceder             Windows Azure SDK Downloads
à configuração deste ficheiro, por defeito genérico, com              http://www.microsoft.com/windowsazure/windowsazuresdk+
dados específicos de cada serviço. Estes dados poderiam               tools/
estar configurados no ficheiro de configuração do serviço
(*.cscfg) já mencionado anteriormente, ou poderíamos fazer            Microsoft Windows Azure Team Blog
uso de Tables, disponíveis em Azure Storage.                          http://blogs.msdn.com/b/windowsazure/

Recorrendo a algumas das técnicas mencionadas, existe                 Artigos Interessantes
um enorme aumento da capacidade de manutenção dos                     http://blogs.msdn.com/b/jnak/archive/201 0/02/11 /windows-
sistemas, bem como da facilidade com que se pode criar e              azure-roleentrypoint-method-call-order.aspx
disponibilizar um novo serviço. No limite, para disponibilizar        http://msdn.microsoft.com/en-us/library/gg433030.aspx
um novo serviço poderá ser apenas necessário um ficheiro
de configuração do serviço (*.cscfg) específico e/ou                  Azure Storage Explorer + SQL Azure Migration Wizard
configurar um conjunto de dados existentes numa dada                  http://azurestorageexplorer.codeplex.com/
Table existente em Azure Storage.                                     http://sqlazuremw.codeplex.com/

É também importante relembrar a diminuição da margem
de erro e de risco existentes, factores extremamente
importantes quando se trata de disponibilizar novos
serviços. Finalmente, há ainda a mencionar o facto de se
                                                                      Link para o artigo: http://tinyurl.com/RPED28-02

 AUTOR

                    Escrito por Virgílio Esteves
                    É Research Leader do grupo de R&D de uma multi-nacional portuguesa. Nutre um enorme gosto por
                    arquitectura de software, desenvolvimento em WPF, Silverlight e XNA, e cloud computing. Participa
                    activamente na comunidade NetPonto e é autor do blog http://pontonetpt.org/blogs/raposo - Twitter:
                    @vraposo




                                                                 67
Revista programar 28

Mais conteúdo relacionado

PDF
Revista Programar 42
PDF
Revista Programar 43
PDF
Revista Programar 41
PDF
Revista programar 38
PDF
Revista Programar 40
PDF
Revista programar 32
PDF
Revista programar 18
PPTX
Cortina quintero armando
Revista Programar 42
Revista Programar 43
Revista Programar 41
Revista programar 38
Revista Programar 40
Revista programar 32
Revista programar 18
Cortina quintero armando

Destaque (20)

PPTX
Publicacion en internet
PDF
Autodichiarazione strength & conditioning
PPTX
web 2.0
PDF
2. gestion administrativa diseño
PDF
Revista programar 8
PPT
Terminado
PPTX
Trabajo practico de formación
PPTX
13 aniversario 111111113334455567
PDF
Puntos suspensivos.
PDF
Revista programar 6
PPTX
pawer point
PPTX
Reglamento institucional nando
PPTX
Evaluacion1.pptx portillo
PPTX
Las TIC
PDF
Revista programar 26
PPTX
PPTX
Reglamento estudiantil Lorena Patricia Gutierrez Torres
PPTX
Trucos de Google
PPTX
Efectos de las herramientas
PPT
Plano de aula_terezinha_atividade_2_unidade_3
Publicacion en internet
Autodichiarazione strength & conditioning
web 2.0
2. gestion administrativa diseño
Revista programar 8
Terminado
Trabajo practico de formación
13 aniversario 111111113334455567
Puntos suspensivos.
Revista programar 6
pawer point
Reglamento institucional nando
Evaluacion1.pptx portillo
Las TIC
Revista programar 26
Reglamento estudiantil Lorena Patricia Gutierrez Torres
Trucos de Google
Efectos de las herramientas
Plano de aula_terezinha_atividade_2_unidade_3
Anúncio

Semelhante a Revista programar 28 (20)

PDF
Revista Programar nº1
PPTX
IntroduçãO Ao Desenvolvimento Web 2
PDF
Revista programar 36
PDF
Revista programar 25
PDF
I pv6 cparty2011
PDF
I pv6 cparty2011
PDF
Revista programar 11
PDF
Workshop Ferramentas Web para Serviços educativos
PPTX
Introdução ao desenvolvimento web - 2 - iDez 2010
PDF
Workshop Museus– trabalho colaborativo e tecnologias sociais
PDF
Workshop museus – trabalho colaborativo e_tecnologias_sociais
PDF
Revista programar 30
PDF
Revista programar 17
PDF
Revista programar 34
PDF
Web 2.0 e as bibliotecas
PPT
Capítulo1 - Introdução a Sistemas Distribuídos - Coulouris
PPT
Cenário e Tendencias TI 2009
PDF
Cloud computing
PDF
Empreendendo com soluções Adobe para plataforma RIA
PPT
As Falácias e os Desenganos no Desenvolvimento de Software (TechDays 2005)
Revista Programar nº1
IntroduçãO Ao Desenvolvimento Web 2
Revista programar 36
Revista programar 25
I pv6 cparty2011
I pv6 cparty2011
Revista programar 11
Workshop Ferramentas Web para Serviços educativos
Introdução ao desenvolvimento web - 2 - iDez 2010
Workshop Museus– trabalho colaborativo e tecnologias sociais
Workshop museus – trabalho colaborativo e_tecnologias_sociais
Revista programar 30
Revista programar 17
Revista programar 34
Web 2.0 e as bibliotecas
Capítulo1 - Introdução a Sistemas Distribuídos - Coulouris
Cenário e Tendencias TI 2009
Cloud computing
Empreendendo com soluções Adobe para plataforma RIA
As Falácias e os Desenganos no Desenvolvimento de Software (TechDays 2005)
Anúncio

Mais de Filipe Bezerra Sousa (19)

PDF
Revista programar 23
PDF
Revista programar 37
PDF
Revista programar 39
DOCX
Como criar metas por fred graef
DOCX
Estudo de produtividade com eclipse
PDF
Revista espirito livre_035_fevereiro2012
PDF
Revista programar 33
PDF
Revista programar 31
PDF
Revista programar 29
PDF
Revista programar 27
PDF
Revista espirito livre_0019_outubro2010
PDF
Revista espirito livre_016_julho2010
PDF
Revista espirito livre_015_junho2010
PDF
Revista espirito livre_014_maio2010
PDF
Revista espirito livre_013_abril2010
PDF
Revista espirito livre_012_marco2010
PDF
Revista espirito livre_011_fevereiro10
PDF
Revista espirito livre_010_janeiro10
PDF
Revista espirito livre_009_dezembro09
Revista programar 23
Revista programar 37
Revista programar 39
Como criar metas por fred graef
Estudo de produtividade com eclipse
Revista espirito livre_035_fevereiro2012
Revista programar 33
Revista programar 31
Revista programar 29
Revista programar 27
Revista espirito livre_0019_outubro2010
Revista espirito livre_016_julho2010
Revista espirito livre_015_junho2010
Revista espirito livre_014_maio2010
Revista espirito livre_013_abril2010
Revista espirito livre_012_marco2010
Revista espirito livre_011_fevereiro10
Revista espirito livre_010_janeiro10
Revista espirito livre_009_dezembro09

Último (11)

PPTX
Eng. Software - pontos essenciais para o início
PPT
Conceitos básicos de Redes Neurais Artificiais
PPTX
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
PDF
Manejo integrado de pragas na cultura do algodão
PPTX
Utilizando code blockes por andre backes
PDF
Jira Software projetos completos com scrum
PPTX
Tipos de servidor em redes de computador.pptx
PPTX
Viasol Energia Solar -Soluções para geração e economia de energia
PDF
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
PDF
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf
Eng. Software - pontos essenciais para o início
Conceitos básicos de Redes Neurais Artificiais
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
Manejo integrado de pragas na cultura do algodão
Utilizando code blockes por andre backes
Jira Software projetos completos com scrum
Tipos de servidor em redes de computador.pptx
Viasol Energia Solar -Soluções para geração e economia de energia
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf

Revista programar 28

  • 2. Editorial EDITORIAL EQUIPA PROGRAMAR FMI - Fim da Maravilhosa Internet? Coordenadores Aconteceu. O ICANN (Internet Corporation for Assigned Names and António Silva Numbers) distribuiu o último bloco de endereços IPV4 pelos 5 RIRs Fernando Martins (Regional Internet Registries). Ou seja após esses endereços serem atribuídos aos ISP, poderá estar em causa a aceitação de novos clientes por Editor parte dos ISP e não haverá no IPV4 mais lugar a expansão. Ou haverá? O António Silva facto é que a norma IPV6 já está preparada (foi descrito como um standard da Internet num documento publicado em Dezembro de 2008), e já em Design Agosto de 2008, na edição #1 5 da Revista PROGRAMAR, foi publicado um Sérgio Alves (@scorpion_blood) artigo que falava um pouco sobre esta nova norma. Contudo a verdade é que parece não existir uma vontade comercial muito grande para adoptar Redacção esta nova norma, porque é financeiramente desagradável, uma vez que é André Vala, Augusto Manzano, Fernando necessário aos ISP fazerem a actualização do seu hardware de rede, aos Martins, Jorge Paulino, Pedro Silva, Pedro programadores actualizarem as suas aplicações… Veloso, Ricardo Rodrigues, Ricardo Trindade, Sara Silva, Virgílio Esteves No dia 8 de Junho, algumas empresas do sector da Internet e não só disponibilizarão durante 24 horas os seus serviços em IPV6, para o Staff utilizador testar os seus serviços com esta nova norma e para pressionar António Santos, Fábio Domingos, Jorge um pouco os ISP a fazerem a migração. Pode testar a sua ligação neste Paulino, Marco Marques site: http://test-ipv6.com/ Contacto Nos EUA existem já soluções que tentam contornar este problema, sem no revistaprogramar@portugal-a-programar.info entanto ser necessário passar a usar o IPV6. Tecnicamente dois ou mais clientes de um ISP estarão numa rede mais pequena (possivelmente Website ligados pela central mais próxima), e existirá um router, e esse sim terá o http://www.revista-programar.info verdadeiro endereço IP da internet, enquanto os PCs dos clientes têm apenas endereços de redes internas. Na prática dois ou mais clientes ISSN podem ter o mesmo IP ao mesmo tempo (algo idêntico ao que acontece nos 1 647-071 0 hotspots). Mas não será isto simplesmente um remedeio? O ser humano tem tendências para rejeitar mudanças, prolongando até ao limite em que já não pode adiar mais essa mudança. Um estudo mundial recente mostra que uma grande parte dos jovens dos denominados países desenvolvidos está dependente de dispositivos com acesso à Internet, sofrendo sintomas de abstinência comuns quando estão afastados muito tempo desses dispositivos. Traduzindo não podem viver sem a Internet. Mas e se os ISP não derem “o salto” para que a Internet continue a existir como a conhecemos? E se os programadores não adaptarem as suas aplicações a este salto? Poderá isto matar a Internet, pelo facto de o utilizador deixar de confiar nela? António Silva <antonio.silva@revista-programar.info> A revista PROGRAMAR é um projecto voluntário, sem fins lucrativos. Todos os artigos são da responsabilidade dos autores, não podendo a revista ou a comunidade ser responsabilizada por alguma imprecisão ou erro. Para qualquer dúvida ou esclarecimento poderá sempre contactar-nos. 2
  • 3. Índice INDICE TEMA DE CAPA 6 Business Connectivity Services A PROGRAMAR 17 Lua – Linguagem de Programação (Parte 8) 21 jQuery 1 .5 e AJAX 27 Datagrid em Windows Presentation Foundation 37 Planos de Execução em ORACLE 47 Smarty PHP Template Engine COLUNAS 48 CORE DUMP - O X No Quadrado Certo 50 VISUAL (NOT) BASIC - Entity Framework 4.0: Model-First e Code-First COMUNIDADES 58 AndroidIPC - Inter Process-Communication 62 Automatização de deployments em Windows Azure EVENTOS 1 5 Abr. SQL Saturday - Portugal 2011 1 5 Abr. 6º Encontro Nacional de Estudantes de Informática ENEI’2011 1 6 Abr. SharePointPT - 1 0ª Reunião da SPUGPT 1 6 Abr. 1 9ª Reunião Presencial da Comunidade NetPonto - Lisboa 03 Mai. Fim das Inscrições ONI'2011 06 Mai. Microsoft WebCamp Portugal - Lisboa 06 Mai. Prova de Qualificação na Internet ONI'2011 09 Mai. CLOUD para DEVELOPERS 1 3 Mai. StopNplay Lan Party 2011 27 Mai. Final Nacional ONI'2011 Para mais informações/eventos: http://bit.ly/PAP_Eventos 3
  • 4. NOTICIAS Noticias R e s u l ta d o s s o b re o Pa n o ra m a La n ç a m e n to d o G N O M E 3 . 0 N a c i o n a l Te c n o l ó gi c o O Sapo Developers Blog fez recentemente um inquérito O GNOME 3.0 é o principal marco na história do projeto sobre um conjunto de questões sobre o Panorama Nacional GNOME. O lançamento introduz um excitante novo Tecnológico. Responderam 421 pessoas sendo a maioria ambiente de trabalho que foi desenhado para utilizadores dos inquiridos jovens com idades entre os 21 e os 35 anos. comuns e adequado para uma grande quantidade de Os resultado apresentados, revelam que os recursos online modernos dispositivos computacionais. As tecnologias de mais influentes são: desenvolvimento do GNOME foram substancialmente melhoradas para o GNOME 3.0. Modernizadas e Portugal a Programar padronizadas, elas irão permitir aos desenvolvedores Aberto até de Madrugada promover melhorias na experiência do utilizador com SAPO Tek menos tempo e esforço. E o GNOME 3.0 vem com as Zwame mesmas aplicações GNOME que os utilizadores conhecem Planet Geek e confiam, muitos dos quais receberam melhorias Pplware significantes. Exame Informática SAPO Developers Blog Mais info Globais: Engadget, Gizmodo, Mashable, ReadWriteWeb, outras. Mais info Le i d a s N o rm a s a b e rta s Wi n d o ws 8 p o d e rá te r Ap p a p ro va d a n a AR Sto re Foi votada no Plenário da Assembleia da República a Lei om a disponibilização da primeira versão do Windows 8 das Normas Abertas, uma proposta que já tinha passado na para os RTM’s, começaram a surgir as primeiras imagens especialidade e prevê a garantia de interoperabilidade e do que será o novo sistema operativo da Microsoft. Estas adopção de normas abertas nos sistemas informáticos do imagens, não oficiais mostram um sistema operativo que Estado. seguirá a continuidade do que o Windows 7 nos trouxe, mas também novidades que farão as delicias de todos os Depois de já ter conseguido gerar consenso, e muitas que o forem usar. vezes unanimidade, na discussão na especialidade, a Lei As últimas imagens que surgiram mostram que o Windows foi aprovada com votos a favor do PEV, PCP, BE, CDS e 8 poderá ter uma store incorporada e onde os utilizadores PS, abstendo-se o PSD. poderão aceder às aplicações que pretenderem. Ainda não existem muitas informações sobre que software esta store Bruno Dias, deputado do PCP, já tinha adiantado que "este conterá e se apenas existirá software gratuito ou se existirá foi um processo legislativo de enorme abertura e espírito a possibilidade de os utilizadores adquirem aplicações. construtivo de todas as partes. Não houve "ideias fixas" O conceito de store dentro do sistema operativo não é porque as opiniões que foram surgindo contribuíam para novo, mas nos últimos tempos tem ganho uma importancia aperfeiçoar o texto, e dessa maneira foram tidas em conta". grande, com a disponibilização da Apple Store dentro do Mac OS e até com o Ubuntu Software Center. 4
  • 5. TEMA DE CAPA Business Connectivity Services
  • 6. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s O SharePoint 201 0 é uma plataforma complexa e com um impressionante conjunto de funcionalidades nativas que lhe Arquitectura permitem adaptar-se a uma enorme variedade de situações. Uma das novas funcionalidades com mais A tecnologia BCS não se limita a apenas um serviço ou API potencial designa-se Business Connectivity Services e este dentro do SharePoint 201 0. É, na realidade, um conjunto de artigo é uma introdução a esta tecnologia e às suas componentes, serviços e ferramentas tal como apresentado potencialidades. no esquema abaixo. O que são os Business Connectivity Services e para que servem? Business Connectivity Services (BCS) é o nome da tecnologia integrada no SharePoint 201 0 que permite ler e escrever informação em sistemas externos a partir do SharePoint 201 0 e do Office 201 0. Trata-se de uma evolução da tecnologia Business Data Catalog (BDC) Figura 1 - Arquitectura dos Business Connectivity Services introduzida no SharePoint 2007, e sobre a qual foram feitas várias melhorias, nomeadamente: Business Data Connectivity (BDC) Service • Possibilidade de leitura e escrita sobre a fonte de dados externa; O Business Data Connectivity Service é uma das peças • Suporte para cenários de autenticação mais complexos; mais importantes dos BCS. Trata-se do componente que • Suporte para múltiplas fontes de dados; permite, através do seu repositório central de • Integração com aplicações Office; metainformação, guardar as descrições da informação à • Novas e melhores formas de apresentar a informação; qual se pretende aceder bem como do próprio sistema • Ferramentas destinadas à criação e manipulação dos externo onde esta está armazenada. modelos; • Extensibilidade através de assemblies .Net. Metadata Store O objectivo desta tecnologia é permitir a integração de informação proveniente de sistemas externos e apresentá- O repositório de metainformação é a base de dados la em SharePoint e aplicações Office com o mínimo de utilizada pelo Business Data Connectivity Service para esforço possível e, idealmente, sem ser necessário armazenar as descrições da informação e dos sistemas escrever qualquer linha de código. Há, de facto, um externos onde esta está armazenada. Este repositório não conjunto de cenários em que é possível a utilização da contém qualquer informação proveniente dos sistemas tecnologia BCS apenas por configuração mas é a sua externos, apenas a metainformação necessária para a extensibilidade que lhe permite adequar-se a praticamente obter. qualquer necessidade de integração. 6
  • 7. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s Connectors modo offline sejam replicadas assim que o sistema externo fica disponível. Os connectors são as peças que permitem ao Business Data Connectivity Service ligar-se às fontes de dados externas descritas nos modelos armazenados no seu Principais Conceitos Metadata Store. São fornecidos três conectores com o produto: Uma vez conhecida a arquitectura dos Business • Database Connector – permite a ligação a bases de Connectivity Services, é importante que se perceba em dados SQL Server. que consiste a metainformação que é armazenada na • WCF/Web Services Connector – permite a ligação a Metadata Store pelo Business Data Connectivity Service. serviços WCF ou web services. • .Net Assembly Connector – permite a ligação utilizando um assembly .Net desenvolvido à medida. Uma vez que se Modelo trata de um assembly desenvolvido à medida, este conector permite a ligação a virtualmente qualquer fonte de dados A metainformação utilizada pelo BDC Service e externa, incluindo até a ligação a múltiplas fontes em armazenada na Metadata Store materializa-se em ficheiros simultâneo. XML que descrevem Modelos, normalmente designados Este mecanismo de connectors é extensível, sendo ainda por BDC Metadata Models. No SharePoint 2007, estes possível desenvolver conectores à medida, para casos em ficheiros de metainformação eram designados por que os conectores existentes não são suficientes. application definition files. Um modelo contém, de forma declarativa, toda a informação necessária para que os BCS consigam ligar-se BDC Client Runtime a um sistema externo e obter a informação que se encontra armazenado no mesmo. As aplicações cliente que fazem parte do Office 201 0 conseguem também expor informação proveniente de sistemas externos através dos BCS. Isso é possível porque Lob System o Office 201 0 inclui o BDC Client Runtime, um componente que faz no contexto da aplicação cliente o que o BDC No contexto dos BCS, o Lob System (ou Line-of-Business Service faz no contexto do System) refere-se ao sistema externo no qual está servidor SharePoint, ou seja, acede ao repositório de armazenada a informação a que se pretende aceder. Este metainformação e, através das definições que este contém, sistema pode ser uma base de dados relacional, ou acede à informação propriamente dita. qualquer outro sistema que exponha essa informação através de web services ou serviços WCF. Client Data Cache External Content Type No sentido de acelerar o acesso à informação, bem como para suportar cenários de acesso offline à informação, os O External Content Type (ECT) é o conceito central e mais BCS utilizam uma cache para guardar a informação externa importante dos BCS, uma vez que descreve uma entidade obtida através dos mesmos. Esta cache é baseada numa de negócio, ou seja, descreve a estrutura e comportamento base de dados SQL Server 2005 Compact Edition e possui da informação a que se pretende aceder. Exemplos de um mecanismo de sincronização automático que permite ECTs podem ser Cliente, Factura ou Colaborador. que todas as alterações efectuadas sobre a informação em Na definição de um ECT é especificada a estrutura e o 7
  • 8. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s comportamento da entidade, ou seja: a uma relação entre duas entidades (External Content • Os campos que constituem uma instância da entidade, e Types). No entanto, uma vez que não há garantia que a respectivo tipo de dados. Por exemplo: Nome, Morada ou fonte de dados seja uma base de dados relacional, a País. associação requer a existência de métodos que permitam • O mapeamento destes campos para objectos utilizados obter, a partir de uma entidade, elementos da entidade pelas aplicações Office cliente. Por exemplo: o campo relacionada. Nome da entidade corresponde ao campo FullName no Outlook. • Os métodos que devem ser invocados pelos BCS para Exemplo de Modelo ler, criar, actualizar e apagar instâncias da entidade. Estes métodos pode corresponder, por exemplo, a stored Felizmente, na grande maioria dos casos, não precisamos procedures, queries SQL ou web services. de editar o modelo manualmente já que as ferramentas No contexto de um Modelo, podem ser definidas várias fornecidas pela Microsoft permitem fazer grande parte da entidades, ou seja, vários External Content Types. configuração de forma visual. No entanto, apenas a título de exemplo, um ficheiro de modelo tem o aspecto apresentado abaixo. Métodos Os métodos são abstracções da API do sistema externo e permitem ao BDC Service saber que stored procedures ou web services devem ser chamados para manipular a informação. A definição de um método é feita no contexto de uma entidade e baseia-se sempre num dos estereótipos disponibilizados pelos BCS. Existem cerca de 20 estereótipos possíveis, como sejam, Updater (para actualizar um item), Finder (para listar itens), SpecificFinder (para obter um item específico), Deleter (para apagar um item) entre outros. Figura 2 - Exemplo parcial de modelo BDC Filtros Os filtros descrevem os parâmetros que podem ser Apresentar Informação Externa passados para os métodos na definição de cada entidade. Mas toda esta complexidade tem um objectivo – o de Existem 1 8 tipos de filtros que podem ser utilizados nos permitir apresentar e manipular a informação armazenada métodos e que indicam ao BDC Service que informação em sistemas externos – por isso não faltam várias deve ser passada para os mesmos. Exemplos de filtros são alternativas para o fazer. o UserName que permite passar o username do utilizador em contexto, ou o Limit que define o número máximo de itens a retornar numa chamada. External List A External List é um novo tipo de lista no SharePoint 201 0 que, através da associação a um External Content Type, Associação permite visualizar e manipular a informação desse ECT como se esta estivesse armazenada numa lista de Uma associação, designada por association, corresponde SharePoint normal. Na realidade, a informação continua a 8
  • 9. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s residir no sistema externo e é lida e manipulada em tempo funcionamento é semelhante ao de uma coluna lookup, real. permitindo ao utilizador seleccionar um dos itens retornados pelo ECT. Figura 4 - External Data Column Uma das vantagens das External Data Columns é a possibilidade de serem utilizadas também pelo Word 201 0, permitindo ao utilizador seleccionar um item exposto através de BCS e utilizando essa informação nos Figura 3 - External List documentos. Tal como para as External Lists, para utilizar um ECT numa A grande vantagem das External Lists é que se parecem e External Data Column este tem que definir, pelo menos, os comportam exactamente como listas normais e, métodos Finder e SpecificFinder. adicionalmente, o object model do SharePoint trata-as como se assim fossem, permitindo aos developers ler e escrever itens como se estes estivessem armazenados no Business Data Web Parts próprio SharePoint. Por outro lado, nem tudo funciona exactamente como nas As Business Data Web Parts são, como o nome indica, um listas tradicionais. Em particular: conjunto de web parts que conseguem ligar-se a fontes de • Workflows dados externas através de um ECT e apresentar essa • Alertas informação no SharePoint. Estas web parts também já • Pastas (folders) existiam no SharePoint 2007 mas foram melhoradas no • Anexos (attachments) SharePoint 201 0, nomeadamente permitindo fazer cache • Feeds RSS da informação externa para melhorar o desempenho. • Exportação para Excel Para que um ECT possa ser utilizado numa External List este tem que definir, pelo menos, os métodos Finder (listar itens) e SpecificFinder (obter um item específico). Isto permitirá à External List apresentar a lista de itens e ver o detalhe de cada um. Adicionalmente, se o ECT possuir métodos Updater (actualizar um item), Deleter (eliminar um item) e Creator (criar um novo item), a External List Figura 5 - Business Data Web Parts disponibilizará as acções correspondentes. As Business Data Web Parts utilizam XSLT para apresentar a informação, o que lhes dá uma enorme flexibilidade no External Data Column que respeita ao seu aspecto gráfico bem como a possibilidade de edição através do SharePoint Designer A External Data Column já existia no SharePoint 2007 e, 201 0. embora tenha sido ligeiramente melhorada no SharePoint As web parts incluídas neste pacote são: 201 0, o seu objectivo é o mesmo – permitir utilizar • Business Data List – permite listar instâncias (itens) de informação externa numa coluna de uma lista. O uma entidade (ECT). 9
  • 10. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s • Business Data Item – permite apresentar o detalhe de Administration, acedendo à gestão do Business Data uma instância (item) de uma entidade (ECT). Connectivity Service. A única informação que precisamos • Business Data Item Builder – permite utilizar parâmetros de fornecer é o endereço URL do site onde estas páginas da query string para criar uma instância (item) de uma serão automaticamente criadas e o SharePoint fará o resto entidade (ECT) que pode depois ser utilizada para por nós. alimentar outras web parts, nomeadamente a Business Neste ponto, basta-nos apenas dizer ao Search Service Data Item web part. que deve indexar uma nova Content Source do tipo Line of • Business Data Related List – permite listar instâncias Business Data e efectuar um Full Crawl. Após a conclusão (itens) de uma entidade (ECT) relacionada. É do crawl a informação externa passa a estar disponível especialmente útil para apresentar informação em cenários para ser pesquisada e a informação de cada item será de Master/Detail. apresentada na respectiva Profile Page. • Business Data Connectivity Filter – permite filtrar a informação proveniente de um ECT antes que seja consumida por outra web part, como a Business Data List User Profiles web part. • Business Data Actions – apresenta as acções Utilizando os BCS, o SharePoint 201 0 consegue utilizar disponíveis para uma instância (item) de uma entidade fontes de dados externas para complementar a informação (ECT). dos User Profiles. Para isso basta que seja possível mapear User Profiles com itens de um ECT, utilizando um campo de cada lado. Pesquisa Não é possível configurar um ECT como fonte principal para a sincronização de perfis, mas é possível que uma Um dos maiores benefícios oferecidos pelos BCS é a sincronização com Active Directory seja complementada possibilidade de indexar e realizar pesquisas sobre a com informação proveniente de um ECT. informação externa exposta através dos ECTs como se se tratasse de informação armazenada em listas no Integração com Office Client SharePoint. Para que um ECT seja indexável é necessário que defina, A integração da informação externa nas aplicações do pelo menos, os métodos IDEnumerator e SpecificFinder. O Office 201 0 é outra das novidades do SharePoint 201 0 primeiro permitirá ao SharePoint obter os IDs de todos os relacionada com os Business Connectivity Services. Até itens e o segundo obter o detalhe de cada um. agora, este tipo de funcionalidade só era possível com Adicionalmente, o modelo tem que ter a propriedade desenvolvimentos à medida de razoável complexidade. ShowInSearchUI para que o SharePoint o consiga indexar. Com os BCS é possível apresentar a informação externa Mas isto é para que a informação seja indexada. Para que, nas aplicações Office, utilizá-la em cenários offline e, em ao realizar uma pesquisa, o utilizador consiga clicar sobre determinados casos, actualizar a informação directamente um dos resultados e visualizar informação detalhada sobre na fonte de dados externa. Contudo, nem todas as o resultado que seleccionou, precisamos também de aplicações incluídas no Office 201 0 suportam esta configurar a Profile Page de cada ECT indexado. integração nativamente. De momento apenas o Outlook Uma Profile Page não é mais que uma página em 201 0, o Word 201 0, o Access 201 0, o InfoPath 201 0 e o SharePoint com algumas web parts que recebe o SharePoint Workspace 201 0 conseguem fazê-lo, sendo que identificador de um item na query string e apresenta cada uma das aplicações utiliza esta tecnologia de forma informação detalhada sobre esse item, incluíndo itens de diferente. ECT relacionados (através de Associations). As Profile Pages são configuradas na Central 10
  • 11. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s Outlook 201 0 Figura 6 - Informação adicional (não mapeada) do ECT O Outlook 201 0 é uma das aplicações que tira melhor Tal com as restantes aplicações Office, o Outlook tira partido das funcionalidades cliente dos BCS. Para que seja partido de um mecanismo de cache e sincronização da possível visualizar a informação exposta através de um informação permitindo ao utilizador trabalhar sobre esta em ECT no Outlook 201 0 são necessários dois passos na offline e sincronizando-a automaticamente assim que o configuração desse ECT: acesso ao sistema externo fica disponível. 1 . Definir qual o tipo de informação exposto pelo ECT, de entre os tipos de informação manipulados pelo Outlook: Contactos (Contacts), Tarefas (Tasks), Eventos Word 201 0 (Appointments) ou Artigos (Posts). Esta configuração pode ser feita através do SharePoint Designer ou directamente O Word 201 0 é outras das aplicações Office que tem no XML do Modelo. suporte nativo para os BCS. No entanto, os cenários para 2. Mapear os campos do ECT com os campos do Outlook aplicação desta tecnologia são diferentes dos disponíveis para esse tipo de informação. Por exemplo, indicar quais os para Outlook. A utilização dos BCS em Word 201 0 limita-se campos do ECT que correspondem aos campos Last à inserção de informação proveniente de fontes de dados Name, First Name, E-mail Address e outros, no Outlook. externas em documentos através de Quick Parts. Existindo uma External List que exponha a informação do Para quem não conhece, as Quick Parts são uma ECT, passa a ser possível utilizar o botão funcionalidade do Word que permite criar campos para Connect to Outlook disponibilizado pela preenchimento dinâmico da informação no meio do texto de ribbon da lista. Ao pressionar o botão, o um documento. Estes campos podem depois ser SharePoint vai analisar a especificação do preenchidos automaticamente com informação proveniente ECT e vai incluí-lo num pacote de instalação Click Once do content type do documento, no SharePoint. Isto inclui que é imediatamente instalado no Outlook 201 0 do informação proveniente de uma External Data Column utilizador como um Add-In. existente na Biblioteca de Documentos em que o Uma vez instalado o pacote, a lista aparece na interface do documento está armazenado. Outlook permitindo ao utilizador interagir com a informação O funcionamento é simples: externa como se fossem contactos, tarefas, eventos ou 1 . Numa Biblioteca de Documentos, cria-se uma External artigos normais. Caso o ECT defina os métodos Data Column configurando-a para expor a informação de necessários, é ainda possível utilizar o Outlook para um determinado ECT e definindo os campos do ECT que actualizar a informação da fonte de dados externa. Todos são expostos. os campos expostos pelo ECT que não estejam mapeados 2. Cria-se um novo documento nessa biblioteca, em campos do objecto Outlook, são mostrados numa utilizando o botão New da ribbon. secção própria do detalhe desse objecto e podem também 3. Já no Word, através da ribbon Insert, inserimos uma ser actualizados. (ou mais) Quick Part, seleccionando a(s) Document Property(s) que corresponde(m) à informação externa que queremos incluir no documento. 11
  • 12. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s Figura 7 - Quick Parts com informação externa SharePoint Workspace 201 0 4. O Word passa então a permitir que o utilizador seleccione um item do ECT, utilizando o Entity Data Picker, O SharePoint Workspace 201 0 é a evolução do Groove e popula automaticamente todos os campos relacionados. 2007 e posiciona-se como a ferramenta de acesso offline à informação guardada em SharePoint 201 0, incluindo External Lists. Tal como para os restantes tipos de listas, basta clicar no botão Sync to SharePoint Workspace para que o conteúdo das mesmas seja descarregado para a máquina do utilizador ficando disponível quando este está desligado do servidor. No que respeita aos BCS, o que o SharePoint Workspace faz é descarregar a definição do ECT associado à External List e armazená-la localmente, bem como os forms de inserção, edição e consulta da informação que foram Figura 8 - External Data Picker gerados para essa External List. Tal como as restantes aplicações Office descritas, o SharePoint Workspace utiliza a cache local para garantir a disponibilização da informação Access 201 0 externa quando o sistema externo não está disponível. O Access 201 0 consegue importar um modelo Business Data Connectivity (BDC) e apresentar a informação externa Soluções e Ferramentas sob a forma de tabelas. No entanto, as tabelas criadas são read-only, ou seja, não é possível escrever de volta para a Uma das grandes queixas de quem utilizou o Business fonte de dados externa. Data Catalog no SharePoint 2007, foi a falta de ferramentas que permitissem uma boa experiência na criação e manipulação da metainformação (modelos). A Microsoft InfoPath 201 0 ouviu essas queixas e brindou-nos com duas ferramentas fantásticas para utilizar com os Business Connectivity Quando é criada uma External List, são também gerados Services: forms para inserção, edição e consulta da informação • SharePoint Designer 201 0 externa. Por omissão, estes forms são gerados como • Visual Studio 201 0 páginas ASP.NET normais mas, utilizando o SharePoint Designer ou a ribbon da External List, é possível criar forms mais inteligentes utilizando InfoPath. Os forms são gerados SharePoint Designer 201 0 automaticamente, mas podem depois ser modificados utilizando o InfoPath. O SharePoint Designer 201 0 é uma ferramenta gratuita e É ainda possível arrastar um External Data Picker para um obrigatória para qualquer utilizador avançado ou developer formulário InfoPath e definir uma External List como fonte de SharePoint. Possui um enorme número de de informação, permitindo a leitura e escrita de informação funcionalidades focando-se principalmente na criação de proveniente de fontes de dados externas. soluções sem código, ou seja, soluções de customização 12
  • 13. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s do SharePoint sem necessidade de desenvolvimentos à medida. Figura 1 0 - Editor visual de Modelos BDC no Visual Studio 201 0 Figura 9 - Utilização do SharePoint Designer para gerir ECTs Alguns dos casos de uso possibilitados pelo Visual Studio 201 0 são: No que respeita aos Business Connectivity Services, o • Criar e manipular External Content Types, utilizando o SharePoint Designer 201 0 permite: novo template de projecto Business Data Connectivity • Criar e manipular External Content Types, incluindo Model. Este template inclui um conjunto de designers que alterar configurações, criar novos métodos e mapear ECTs permite a edição visual do Modelo e respectivos ECTs, e com objectos Office. Na criação de ECTs apenas é possível possibilita ainda o desenvolvimento de soluções utilizando efectuar ligações a bases de dados SQL Server, Web código .Net para acesso a virtualmente qualquer fonte de Services cujos schemas sejam suportados pelos BCS ou dados externa. assemblies .Net existentes. • Criar componentes reutilizáveis para os BCS utilizando • Criar e configurar External Lists com base em ECTs já os vários pontos de extensibilidade da API dos BCS, como criados. sejam Code Actions que podem ser utilizadas dentro do • Gerar e editar formulários InfoPath de suporte às Outlook, External Data Parts para utilização em task panes External Lists. declarativas no Outlook, actividades para workflows e • Utilizar informação externa em workflows. outros. • Criar web part pages e profile pages • Criar Add-Ins para aplicações Office com suporte para Estas funcionalidades permitem a utilização dos BCS sem BCS, utilizando o object model dos BCS. qualquer desenvolvimento à medida e adaptam-se às • Criar workflows à medida que tiram partido de necessidades mais simples e comuns. informação em External Lists ou utilizam o object model dos BCS. Visual Studio 201 0 Tipos de Solução por Ferramenta Com o Visual Studio 201 0 podemos criar soluções mais complexas para casos em que as funcionalidades do A tabela na página seguinte ajuda a seleccionar a SharePoint Designer 201 0 não são suficientes. ferramenta ideal para cada necessidade. Adicionalmente, com o Visual Studio 201 0 podemos criar componentes reutilizáveis que depois poderão ser incorporados em soluções através do SharePoint Designer. 13
  • 14. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s dados adicional para a sincronização de perfis do SharePoint. • Necessidade de sincronizar contactos que estão armazenados num sistema de negócio ou ERP. Utilizando os BCS é possível definir um ECT que expõe esses contactos através de uma External List e ligá-la ao Outlook onde serão geridos como contactos normais. Este cenário permite ainda que os utilizadores tenham acesso aos contactos mesmo quando estão fora do escritório, em modo offline. Casos de Uso • Necessidade de apresentar informação proveniente de fontes de dados distintas. Utilizando o conector para Uma das perguntas mais frequentes relacionadas com a assemblies .Net e desenvolvendo um ECT com o Visual utilização de Business Connectivity Services é quais os Studio 201 0, podemos construir cenários de acesso a casos de uso desta tecnologia ou, de outra maneira, múltiplas fontes de dados com agregação dos mesmos quando devo utilizar os BCS. numa única entidade. Alguns dos casos de uso mais comuns para a utilização de BCS são: • Necessidade de indexar e pesquisar informação residente num sistema de negócio ou ERP. Os BCS • Necessidade de apresentar informação de uma base de permitem ao serviço de pesquisa do SharePoint indexar dados SQL Server. Utilizando BCS é possível apresentar e, conteúdos expostos através de ECTs e pesquisá-los como caso seja necessário, modificar a informação utilizando se a informação estive armazenada no SharePoint. External Lists sem ser preciso desenvolver uma única linha Há muitos outros cenários onde os BCS podem ser úteis, de código à medida. É um back-office instantâneo. por vezes apenas como um dos componentes da solução. • Necessidade de complementar os User Profiles dos utilizadores do domínio com informação proveniente do Funcionalidades por Versão do SharePoint sistema de gestão de Recursos Humanos ou ERP. Tal como já foi falado, os BCS permitem responder a este A infraestrutura utilizada pelos Business Connectivity requisito permitindo configurar um ECT como fonte de Services está disponível em todas as versões do 14
  • 15. TEMA DE CAPA B u s i n e s s C o n n e c ti vi ty S e rvi c e s SharePoint, incluíndo o SharePoint Foundation 201 0. No entanto, nem tudo vem incluído na versão gratuita. A tabela Connecting to a .NET Framework Source Using Business abaixo ajuda a clarificar quais as funcionalidades que estão Connectivity Services in Office 201 0 incluídas em cada uma das versões do SharePoint 201 0. Visual How To sobre como desenvolver um ECT usando Visual Studio 201 0 para obter dados de uma fonte externa. O suporte para Business Connectivity Services em http://msdn.microsoft.com/en- aplicações Office requer o Microsoft Office 201 0 us/library/ff394331 (office.1 4).aspx Professional Plus, ou superior. Microsoft Business Connectivity Services Secção do SDK do SharePoint 201 0 dedicada aos Links Úteis Business Connectivity Services. Aqui ficam alguns links úteis para quem está agora a http://msdn.microsoft.com/en-us/library/ee556826.aspx começar e quer saber mais sobre Business Connectivity Services. Business Connectivity Services Resource Center Resource Center dedicado aos Business Connectivity Microsoft Business Connectivity Services Team Blog Services, no TechNet. O blog official da equipa que desenvolveu os BCS, com http://technet.microsoft.com/en- imensos artigos com vários níveis de complexidade. us/sharepoint/ee51 8675.aspx Obrigatório para todos os interessados nesta tecnologia. http://blogs.msdn.com/b/bcs/ Business Connectivity Services: Technical Articles Artigos técnicos da MSDN relacionados com Business BCS Team Channel Connectivity Services. O canal no YouTube onde alguns vídeos foram publicados http://msdn.microsoft.com/en-us/library/gg481 768.aspx pela equipa de produto. http://www.youtube.com/user/MOSSBCSTeam Link para o artigo: http://tinyurl.com/RPED28-04 AUTOR Escrito por André Vala Licenciado e Mestre em Engenharia Informática e de Computadores pelo Instituto Superior Técnico, é actualmente consultor sénior na |create|it| e co-fundador da Comunidade Portuguesa de SharePoint . Autor do blog http://blogit.create.pt/blogs/andrevala, trabalha com SharePoint desde 2006, altura em que surgiu a primeira versão beta do SharePoint 2007. Tem participado em vários projectos nacionais e internacionais sobre SharePoint, e participa frequentemente como orador em eventos da Microsoft relacionados com o mesmo tema. 15
  • 16. A PROGRAMAR Lua – Linguagem de Programação (Parte 8) jQuery 1.5 e Ajax Datagrid em Windows Presentation Foundation Planos de Execução em ORACLE Smarty PHP Template Engine
  • 17. A PROGRAMAR Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 ) Este artigo trata o uso de operações de aleatoriedade e a valor estabelecido junto a parâmetro “n” e pode ainda ser manipulação de cadeias (operações de detecção de usada com os parâmetros “n” e “m” para gerar valores tamanho de cadeias – revisão, repetição de caracteres, inteiros entre “n” e “m”. separação de cadeias, busca e substituição de caracteres, O programa seguinte efectua a acção de geração de conversão em modo ASCII). valores aleatórios da forma mais simples possível. -- inicio do programa ALEAT01 ERRATA math.randomseed(0) Por falha pessoal no artigo anterior (Parte 7) ficou indicado após a conclusão que esta parte trataria do tema: arquivo. local function SORTEIO() No entanto, este assunto fora apresentado na sexta parte N = math.random() desta série de artigos. return N end ALEATORIEDADE for I = 1, 5 do X = SORTEIO() É sabido que aleatoriedade é a característica do que é print(X) indeterminado ou incerto. Uma das possibilidades end operativas de uma linguagem de programação é a capacidade de “gerar” valores numéricos aleatórios. O -- fim do programa ALEAT01 termo: gerar é grafado entre aspas devido a característica que os computadores possuem de fazer este trabalho de Em seguida escreva o código de programa em um editor de uma forma considerada não real, ou seja, por meio de uma texto, gravando-o com o nome aleat01 .lua e execute-o com acção considerada pseudo-aleatória. a linha de comando lua 5.1 aleat01 .lua. Para esta acção em linguagem Lua há as funções de A função math.randomseed() necessita ser usada a frente geração de números aleatórios: math.randomseed() e da função math.random() para que math.random() consiga math.rendom(). gerar os valores aleatórios. Os valores gerados por estas funções são valores pseudo- Ao executar o programa várias vezes os valores aleatórios, e necessitam ser usados com alguma cautela, apresentados como saída sempre serão: tanto que há no manual de referência da linguagem Lua a advertência: Nenhuma garantia pode ser dada para suas 0.0011 597033600879 propriedades estatísticas. 0.23557237464522 A função math.randomseed(n) faz uso do valor “n” como 0.6481 521 04251 23 parâmetro de semente para a geração de valores 0.074373607593005 aleatórios. 0.270241 401 40996 A função math.random([n[,m]]) pode ser usada de três formas diferentes: usada sem parâmetros o que fará a Os valores se repetem pelo fato de estar sendo utilizado o geração de valores entre 0 e 1 , pode ser usada apenas valor de semente “0” (zero). Se o valor de semente for com o parâmetro “n” para gerar valores inteiros entre 1 e o mudado para 1 , 2, 3 ou outro valor qualquer serão 17
  • 18. A PROGRAMAR Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 ) conseguidos valores diferentes. No entanto para um Observe que uso da função os.time() como valor semente mesmo valor de semente para mais de uma execução ter- permite um comportamento de aleatoriedade mais se-á a apresentação dos mesmos valores. Uma forma de convincente. mudar um pouco este comportamento é fazer uso da Agora imagine que se queira sortear valores numéricos função os.time() como valor de semente. A função os.time() entre 1 e 5. Assim sendo, observe o código seguinte: retorna o valor do tempo corrente. Assim sendo, observe o código de programa seguinte: -- inicio do programa ALEAT03 -- inicio do programa ALEAT02 math.randomseed(os.time()) math.randomseed(os.time()) local function SORTEIO() N = math.random(1,5) local function SORTEIO() return N N = math.random() end return N end for I = 1, 5 do X = SORTEIO() for I = 1, 5 do print(X) X = SORTEIO() end print(X) end -- fim do programa ALEAT03 -- fim do programa ALEAT02 Em seguida escreva o código de programa em um editor de Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat03.lua e execute-o com texto, gravando-o com o nome aleat02.lua e execute-o com a linha de comando lua 5.1 aleat03.lua. a linha de comando lua 5.1 aleat02.lua. Execute o programa algumas vezes. Note que o primeiro Ao se executar o programa várias vezes notar-se-á que os valor é sempre o mesmo em toda a execução, somente os resultados apresentados são levemente diferentes. Por demais valores são apresentados diferentemente. Este é exemplo, a seguir apresenta-se os valores de saída de um comportamento operativo da linguagem Lua que gera duas execuções sequenciais do programa: dúvidas nos iniciantes no uso desta linguagem. Não se preocupe em seguida será mostrado como contornar este 0.85509811 700797 tipo de ocorrência. 0.76201 66631 061 7 Observe que para gerar valores entre 1 e 5 fora usado: N = 0.21 799371 31 8705 math.random(1 ,5). 0.1 767021 6986602 O próximo programa mostra como contornar o problema de 0.249671 9260231 3 repetição do primeiro valor da sequência sorteada. -- inicio do programa ALEAT04 0.85558641 31 5958 0.402081 36234626 math.randomseed(os.time()) 0.943876461 07364 math.random() 0.84850611 89611 5 0.82357249671 926 local function SORTEIO() 18
  • 19. A PROGRAMAR Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 ) Nas operações de manipulação de cadeias há ainda a N = math.random(1,5) possibilidade de separar partes de uma cadeia. Para este return N efeito faz-se uso da função string.sub(texto, início, [fim]), end onde texto é a indicação da cadeia que será separada, início é a indicação da posição de separação inicial que for I = 1, 5 do pode ser positiva ou negativa e fim - indicação opcional da X = SORTEIO() posição final de separação. print(X) Em seguida escreva o código de programa em um editor de end texto, gravando-o com o nome cadeia02.lua e execute-o com a linha de comando lua 5.1 cadeia02.lua. -- fim do programa ALEAT04 -- inicio do programa CADEIA02 Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat04.lua e execute-o com X = "COMPUTADOR" a linha de comando lua 5.1 aleat04.lua. Execute o programa algumas vezes e note a diferença print(string.sub(X)) nesta versão. Observe o uso da função math.random() logo print(string.sub(X, 1)) após o uso da função math.randomseed(os.time()). Este print(string.sub(X, 1, 3)) pequeno ajuste faz o acerto desejado. print(string.sub(X, 4, 5)) print(string.sub(X, 6, 7)) print(string.sub(X, 8)) MAIS MANIPULAÇÃO DE CADEIAS print(string.sub(X, -5)) No sexto artigo desta série fora apresentada uma forma de -- fim do programa CADEIA02 detecção da quantidade de caracteres de uma cadeia com o uso do operador # por meio da instrução de código Após a execução serão apresentados os textos print(#"Linguagem Lua") que mostra como resultado o valor COMPUTADOR, COM, PU, TA, DOR e TADOR. 1 3. Outro factor de manipulação de cadeias de caracteres é a Esta mesma acção pode ser efectuada por meio da função realização de operações de substituição de caracteres de string.len(texto) como apresentado no quinto artigo desta uma cadeia. Para tanto, use a função de substituição série, onde texto é a indicação da cadeia que terá contada string.gsub(texto, busca, troca, vezes), onde texto é a a quantidade de caracteres. cadeia de texto definida, busca é o carácter a ser Em seguida escreva o código de programa em um editor de localizado, troca é o carácter que será substituído e vezes texto, gravando-o com o nome cadeia01 .lua e execute-o indica o número máximo de substituições a serem com a linha de comando lua 5.1 cadeia01 .lua. efectuadas, sendo este último argumento opcional. Em seguida escreva o código de programa em um editor de -- inicio do programa CADEIA01 texto, gravando-o com o nome cadeia03.lua e execute-o com a linha de comando lua 5.1 cadeia03.lua. X = "Linguagem Lua" -- inicio do programa CADEIA03 print(string.len(X)) X = "A BOLA AZUL APARECEU" print(string.gsub(X,"A","4")) -- fim do programa CADEIA01 print(string.gsub(X,"A","X",2)) -- fim do programa CADEIA03 19
  • 20. A PROGRAMAR Lu a – Li n gu a ge m d e Pro gra m a ç ã o ( Pa rte 8 ) Observe que após a execução, o programa mostra além da troca realizada o número de trocas realizadas. print(string.byte(X, -5)) Outra acção para manipulação de cadeias é a função string.rep(texto, vezes), onde texto é a cadeia a ser -- fim do programa CADEIA05 repetida e vezes é a definição do número de repetições. Em seguida escreva o código de programa em um editor de O programa apresenta os valores: texto, gravando-o com o nome cadeia04.lua e execute-o - 65 com a linha de comando lua 5.1 cadeia04.lua. - 65 66 67 - 68 69 -- inicio do programa CADEIA04 - 65 66 67 68 69 70 - 66 X = "OBA " A acção inversa é conseguida com o uso da função print(string.rep(X,2)) string.char(código1 , código2, …, códigoN), onde cada argumento usado é um valor ASCII. -- fim do programa CADEIA04 Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia06.lua e execute-o Outro efeito com cadeias é a obtenção do código ASCII dos com a linha de comando lua 5.1 cadeia06.lua. caracteres que formam a cadeia com a função string.byte(texto, início, [fim]), onde texto é a indicação da -- inicio do programa CADEIA06 cadeia que terá seus caracteres convertidos em formato ASCII, início é a indicação da posição de separação inicial print(string.char(65)) que pode ser positiva ou negativa e fim - indicação opcional print(string.char(65, 66, 67)) da posição final de separação. Em seguida escreva o código de programa em um editor de -- fim do programa CADEIA06 texto, gravando-o com o nome cadeia05.lua e execute-o com a linha de comando lua 5.1 cadeia05.lua. CONCLUSÃO -- inicio do programa CADEIA05 Neste artigo o enfoque foi o uso dos recursos de geração X = "ABCDEF" de valores aleatórios e alguns detalhes sobre a print(string.byte(X, 1)) manipulação de cadeias. print(string.byte(X, 1, 3)) No próximo artigo a ênfase será dada a criação e uso de print(string.byte(X, 4, 5)) módulos em linguagem Lua. print(string.byte(X, 1, 6)) Link para o artigo: http://tinyurl.com/RPED28-06 AUTOR Escrito por Augusto Manzano Natural da Cidade de São Paulo, tem experiência em ensino e desenvolvimento de programação de software desde 1 986. É professor da rede federal de ensino no Brasil, no Instituto Federal de Educação, Ciência e Tecnologia. É também autor, possuindo na sua carreira várias obras publicadas na área da computação. 20
  • 21. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX O objectivo deste artigo é expor a funcionalidade de AJAX também iremos rever mais à frente) que aceitam uma que o jQuery inclui, ao detalhe, e é também falar sobre as função como parâmetro que é chamada quando o pedido novas funcionalidades introduzidas pela versão 1 .5 da terminar a sua execução, ou mesmo que estes callbacks framework, neste caso, os Deferreds. sejam assignados após o pedido AJAX ter sido executado, Nesta nova versão toda a funcionalidade de AJAX foi estas são chamadas de qualquer modo, esta é uma das redesenhada, pelo que iremos entrar no tema das novas novidades deste interface de Promises, permite assignar funcionalidades através da sua utilização no próprio AJAX e callbacks à posteriori, o que não era possível nas versões depois expandindo a outras alterações também com anteriores às 1 .5. relevância. Podemos ver aqui o exemplo de como assignar estes callbacks, e verificar que mesmo após o pedido ser Começando pelo princípio, o método mais simples de completamente executado, assignando novos callbacks, efectuar um pedido AJAX em jQuery é utilizando a função estes executam de qualquer modo: jQuery.get: /*Assignar handlers imediatamente após var ajaxObj = $.get('ajax/mypage.aspx', executar o pedido e function(data) { guardar numa var o objecto jqXHR*/ $('#ajaxDiv').html(data); var xhrObj = $.get("ajax.aspx", function() alert('callback called!'); { }); alert("sucesso!"); }) Este é o método mais simplificado, especificamos .success(function() { alert("novamente unicamente que url irá retornar os dados, e a função de sucesso"); }) callback retorna-nos os dados e aí poderemos adicionar .error(function() { alert("erro"); }) qualquer lógica necessária. .complete(function() { alert("pedido Os dados que retornam do nosso pedido podem ser texto, completo"); }); JSON, XML ou JavaScript, e a função infere o tipo, pois neste caso não o estamos a especificar. Além da variável //alguma lógica adicional (...) data, poderíamos especificar outras duas variáveis na função de callback, a segunda seria o textStatus do XHR /*adicionar outro callback de complexão aqui, (XMLHttpRequest) e a terceira seria o mesmo que o e verificar que é executado mesmo que o ajaxObj irá conter, um jqXHR (que passou a ser um jqXHR pedido já tenha sido completamente efectuado a partir da versão 1 .5, anteriormente era um XHR nativo). anteriormente, devido às funcionalidades das Neste exemplo caso retornássemos HTML seria adicionado Promises*/ ao DOM como innerHTML do objecto com o id ajaxDiv e xhrObj.complete(function(){ alert("completo mostraria um alert, depois do pedido retornar com sucesso. novamente"); }); O objecto jqXHR implementa o interface de Promises (que iremos descortinar mais à frente na funcionalidade Deferreds do jQuery 1 .5) e inclui toda a sua funcionalidade, Em versões anteriores do jQuery, no caso de utilizarmos pelo que inclui os métodos error() success() e complete() esta função get(), se existisse um erro não conseguiríamos para acordar com os callbacks da função $.ajax (que assignar um callback a não ser através da função global 21
  • 22. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX ajaxError(), ou seja, não conseguiríamos ter um error Também existe a possibilidade de enviar parâmetros, como handling local e objectivo, a não utilizando uma função mais o segundo parâmetro,à semelhança do get(). genérica com a ajax(). Existe também a função post() que funciona do mesmo Uma ressalva, os pedido efectuados com a função get() exacto modo que a get() mas ao invés de enviar os dados que não sejam pedidos JSONP ou Script, não permitem por HTTP GET, envia precisamente por HTTP POST. cross-domain, como é usual. Se quisermos efectuar outro tipo de pedidos com a função Caso o nosso objectivo seja exclusivamente obter JSON, get() : existe uma função específica para tal, a getJSON(), que tem algumas especificidades, tais como no caso de especificarmos adicionar ao url o texto callback=? O pedido //fazer apenas o request e ignorar resultado passa a ser tratado com um pedido JSONP, e não JSON, o $.get("ajax.aspx"); que permite pedidos cross domain sem qualquer problema. //passar parâmetros simples e ignorar O segundo parâmetro pode ser utilizado para enviar resultados parâmetros, como nas outras funções. $.get("ajax.aspx", { tipo: "noticias", quantas: "10" } ); $.getJSON('outputjson.json', function(data) { //passar arrays e ignorar resultados $('.result').html('<p>' + data.foo + '</p>' $.get("ajax.aspx", { 'valores[]': ["10", + '<p>' + data.baz[1] + '</p>'); "20"]} ); }); //combinar parâmetros com callback //estrutura de JSON esperada: $.get("ajax.aspx", { param1: "teste" }, { function(data) { "foo": "The quick brown fox jumps over the alert("callback executado!"); lazy dog.", }); "bar": "ABCDEFG", //receber um JSON já parsed "baz": [52, 97] $.get("ajax.aspx", { param1: "teste" }, } function(data) { alert(data.prop1); // valor da variável Passando à função mais completa e talvez a mais utilizada, data: { "prop1": "valor1" } a função ajax(), podemos definir o url, e imensos settings, }); vou passar aqui pelos mais importantes: Outra das funcões para efectuar pedidos AJAX é a load(): async: permite definir se o pedido é ou não executado assíncronamente; //carrega o resultado no/s objecto do DOM beforeSend(jqXHR, settings): este callback é executado especificado/s pelo selector imediatamente antes do pedido ser executado, e caso $('#ajaxDiv').load('ajax.aspx', function() { retornemos false, o pedido não é executado; alert('HTML carregado'); complete(jqXHR, textStatus): este callback é executado }); quando o pedido foi completamente executado, a partir da //carrega o resultado no/s objecto do DOM versão 1 .5 podemos passar aqui um array de funções que especificado/s pelo selector, mas apenas o serão todas executadas; que faz match com o selector passado ao lado data: permite passar parâmetros no formato querystring do url (valor1 =X&valor2=y...); $('#ajaxDiv').load('ajax.aspx #mainContent'); dataType: permite definir exactamente que tipo de dados iremos receber, json, script, text, html, jsonp, xml (podemos 22
  • 23. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX passar múltiplos valores, por exemplo “jsonp xml”, para persista qualquer cache*/ efectuar um pedido jsonp e converter para XML); $.ajax({ error(jqXHR, textStatus, error): callback em caso de erro; url: "teste.html", statusCode: definir um callback conforme o HTTP error cache: false, code: success: function(html){ $.ajax({ $("#resultado").append(html); statusCode: {404: function() { } alert('page not found'); }); } }); /*efectuar um pedido que ao estando o seu resultado a ser utilizado de imediato para assignar à  variável html, devemos especifica success(data, textStatus, jqXHR): callback executado que não pode ser assíncrono, pois caso quando o pedido é retornado com sucesso; contrário poderíamos tentar usar a variável type: tipo de pedido “GET” ou “POST”; html e esta não iria ter o valor esperado.*/ url: URL do pedido. var html = $.ajax({ url: "page.aspx", Podemos utilizar a função ajaxSetup() para definir estes async: false settings globalmente na nossa aplicação, sendo que depois }).responseText; podemos fazer override em cada caso aos settings que se alteram, centralizando tudo o que são settings transversais. /*o mesmo caso que o anterior, mas aqui Exemplos: enviamos parâmetros e temos um callback de sucesso, e o o dataType é especificado. //obter um script via AJAX (GET) Ao utilizar o global a false, estamos a dizer $.ajax({ explicitamente que os eventos globais de ajax type: "GET", não vão ser disparados, logo os seus url: "my.js", callbacks não vão executar, isto caso estejam dataType: "script" definidos via ajaxStart() e ajaxStop()*/ }); var bodyContent = $.ajax({ url: "script.aspx", //fazer o pedido por POST, enviando global: false, parámetros e com callback type: "POST", $.ajax({ data: ({id : this.getAttribute('id')}), type: "POST", dataType: "html", url: "ajax.aspx", async:false, data: "nome=Ricardo&location=Lisboa", success: function(msg){ success: function(msg){ alert(msg); alert("Dados enviados: " + msg); } } } }); ).responseText; /*pedir a última versão de uma página, especificando que não queremos que o browser 23
  • 24. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX Com esta especificação extensa do AJAX, vamos passar às Como podemos ver, deste modo podemos organizar o novas funcionalidades do jQuery 1 .5, começando pelos já código de maneira diferente, até podemos criar uma mencionados Deferreds (Promises interface). abstracção à função de ajax no contexto da nossa Esta funcionalidade tem como objectivo fazer com que uma aplicação e ter funções para atribuição de callbacks, que tarefa e a lógica executada após esta estar completa sejam são executados numa metodologia FIFO (First in first out). desacoplados, quer isto dizer que podemos assignar Não temos de definir callbacks de complexidade extrema múltiplos callbacks para o resultado de uma tarefa e pelo facto de apenas podermos definir um e até podemos mesmo após esta estar completa podemos continuar a começar a usar esta funcionalidade de um modo adicioná-los e estes são executados do mesmo modo. Esta inteligente, para por exemplo, executar determinado código tarefa pode ser assíncrona ou não, nada obriga que o seja. caso algumas funções ajax tenham sido executadas com Visto que o AJAX do jQuery 1 .5 foi redesenhado para incluir sucesso, isto de uma forma extremamente simples, os Deferreds, podemos usufruir deles directamente: utilizando a função $.then(): // este pedido é assíncrono por omissão function doAjax() { var req = $.get('foo.htm') return $.get('ajax.aspx'); .success(function(response) { } //em caso de sucesso }) function doMoreAjax() { .error(function() { return $.get('ajax2.aspx'); //em caso de erro } }); $.when( doAjax(), doMoreAjax() ) //isto até pode ser executado antes do get .then(function(){ acima console.log('Executado quando ambos algumaFuncao(); os pedidos estão completos!'); }) /*definir algo mais a ser executado em caso .fail(function(){ de sucesso, que pode ou não já ter ocorrido, console.log('Executado quando um ou mas com os deferreds realmente não interessa, mais pedidos falharam!'); é executado de qualquer forma*/ }); req.success(function(response) { /*tomar alguma acção com a resposta isto vai ser executado quando o sucesso ocorrer, Este código funciona porque o AJAX agora retorna uma ou caso este já tenha ocorrido, é disparado promise() que é utilizada para monitorizar o pedido de imediato, caso os outros callbacks de assíncrono, esta promise() é um objecto apenas de leitura sucesso já tenham sido executados que existe no resultado da tarefa. Os deferreds verificam a */ existência da função promise() para determinar se um }) objecto é observable ou não, que é o que lhe permite funcionar como deferred. A função when() aguarda pela execução das funções AJAX passadas por parâmetro e Deste modo podemos ver que já não estamos limitados a quando estas são executadas os métodos then() e fail() são definir apenas um callback para error, sucesso e executados, conforme o estado da tarefa. Importante referir complexão, podemos definir quantos quisermos, e mais novamente que os callbacks são executados pela ordem importante, quando quisermos! cujo são assignados a cada método. 24
  • 25. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX Uma nota importante: os deferreds aceitam ou funções ou código “típico”: arrays de funções, que nos permite definir conjuntos de Podemos ver aqui a utilização dos deferreds num bloco comportamentos na nossa aplicação e passá-los simples, e a sua explicação é muito simples: genericamente, ao invés de passarmos apenas uma função isolada. function getData(){ Podemos verificar o estado de um deferred através das return $.get('/echo/html/'); suas funções isRejected() e isResolved(). } No caso do AJAX o que obtemos é um acesso a uma parte do deferred, visto que se tivessemos acesso completo function showDiv() { poderíamos controlar quando os callbacks são executados var dfd = $.Deferred(); através da função resolve() e poderíamos invocá-los antes dos pedidos realmente serem executados, o que iria $('#foo').fadeIn( 1000, dfd.resolve ); quebrar a lógica, logo temos apenas acesso a uma parte do deferred, à promise(), que é apenas de leitura, como já foi return dfd.promise(); referido. } Em termos de métodos, os que utilizámos até agora foram $.when( getData(), showDiv() ) o then(), success() e fail(), também falámos do complete() .then(function(result) { no caso de AJAX, mas existem mais métodos que podemos console.log('A animação e o pedido utilizar, especialmente no caso de estarmos a lidar com AJAX foram executados'); AJAX. O método escolhido depende exclusivamente do }); estado ao qual queremos fazer bind. Para todos os deferreds existem os seguintes métodos: - then(doneCallbacks, failedCallbacks); Na função showDiv estamos a criar um objecto deferred - done(doneCallbacks); novo, e retornamos a promise(). Este deferred como o - fail(failCallbacks); código o mostro é resolvido assim que o fadeIn terminar, pois o dfd.resolve foi definido como callback deste fadeIn. Os deferreds de AJAX têm 3 métodos adicionais que se O getData, retorna um objecto compatível com deferred podem especificar, 2 dos quais invocam um dos acima (não exactamente igual, visto que é um AJAX e como já foi especificados. Estes métodos específicos existem referido o AJAX não é um deferred “simples”), e como o exclusivamente para não quebrar a compatibilidade com os objecto retornado pelo getData, tem o método promise, é nomes dos callbacks para AJAX que existiam nas versões tratado com deferred e o when() aguarda que ambos anteriores de jQuery: estejam no estado resolved, após estarem, executa o - success(doneCallbacks); -> maps to done() callback passado no método then() e escreve na consola. - error(failCallbacks); -> maps to fail() Neste artigo podemos observar todo o potencial do AJAX, a Existe também o método complete() que é invocado após a sua evolução nesta nova versão 1 .5 e também a grande função AJAX ser executada, retorne ou não erro. Ao nova funcionalidade que são os deferreds. contrário do success e do error o complete é um alias para O jQuery está em constante evolução, esta é uma das o done, que é resolvido assim que o pedido AJAX termina, novas features da versão 1 .5, como foi demonstrado, tem independentemente do seu resultado. um potencial enorme e uma abrangência e influência - complete(completeCallbacks); grandes, visto que até afectou áreas core da framework. Stay tuned! Um exemplo de utilização de deferreds num bloco de 25
  • 26. A PROGRAMAR j Qu e ry 1 . 5 e AJ AX Link para o artigo: http://tinyurl.com/RPED28-08 AUTOR Escrito por Ricardo Rodrigues É técnico Nível III em Informática/Gestão pela Fundação Escola Profissional de Setúbal, tendo ingressado após na FCT da Universidade Nova de Lisboa. Posteriormente frequentou vários cursos da Microsoft em diversas áreas como Windows Forms,ASP.NET, Securing .NET Applications, WCF, WWF, Web Services e COM+ tendo obtido as certificações MCP .NET 2.0, MCAD .NET 1 .1 , MCSD .NET 1 .1 , MCPD Windows, Web e Distributed Applications e MCPD - Enterprise Applications Developer. (MCP Profile) Contribui activamente em comunidades como StackOverflow e também possui um blog/twitter como temática relacionada: Blog / @ricmrodrigues 26
  • 27. A PROGRAMAR Datagrid em Windows Presentation Foundation Neste artigo pretendo apresentar a Datagrid em Windows MinColumnWidth; ColumnHeaderHeight; permitem definir a Presentation Foundation (WPF) na .Net Framework 4.0. largura, largura máxima, largura mínima e a altura do Vou começar por uma breve apresentação teórica e em cabeçalho da coluna. seguida irei apresentar vários exemplos. De salientar que • RowHeight; MinRowHeight: permitem definir a não terei em conta Design Patterns. altura e altura mínima da linha. • GridLinesVisibility: permite definir a visibilidade A DataGrid é um controlo que permite apresentar dados, das linhas que delimitam as linhas e colunas. Caso sejam representando cada linha um item de uma lista de objectos visíveis as propriedades HorizontalGridLinesBrush e do mesmo tipo e as colunas representam as várias VerticalGridLinesBrush permitem definir aparência das características do objecto. Ou seja, se na instância da linhas. datagrid apresento uma lista de empregados, cada linha • SelectionMode; SelectionUnit permitem definir o representa um empregado e cada coluna representa uma modo de selecção dos itens, ou seja, se é possível propriedade do empregado. seleccionar mais de que um item e se é permitido seleccionar linha(s) completa(s) ou célula(s). A classe DataGrid está incluída no namespace • AutoGenerateColumns: permite gerar System.Windows.Controls e é um selector que permite automáticas as colunas da datagrid. Para a geração seleccionar mais do que um item ao mesmo tempo e tem automática é considerada todas as propriedades do tipo de por base a classe ItemsControl, que é um Controlo e que objecto em causa, ou no caso de se estar a usar um implementa a interface IAddChild. A seguinte imagem dataTable a geração é baseada nas colunas da dataTable. mostra-nos esta hierarquia de classes. • Columns: permite obter a colecção de colunas. • CellStyle: permite definir o estilo da célula. • ColumnHeaderStyle: permite definir o estilo do cabeçalho da coluna. • CanUserAddRows: permite que o utilizado Vejamos agora algumas propriedades, métodos e eventos adicione novos itens. relevantes da DataGrid. • CanUserDeleteRows: permite que o utilizado apague itens. • CanUserReorderColumns permite que o As propriedades mais relevantes são: utilizador organize as colunas. • Name: permite definir o nome. • CanUserResizeColumns: permite que o utilizador • Foreground: permite definir a cor da letra. redimensione as colunas. • Background: permite definir a cor de fundo. • CanUserResizeRows: permite que o utilizador • AlternatingRowBackground; AlternationIndex: redimensione as linhas. permitem definir a cor de fundo de cada linha, de forma • CanUserSortColumns: permite que o utilizador alternada. ordene os itens ao fazer duplo clique no cabeçalho da • Width; Height; MaxHeight; MinWidth; MaxWidth; coluna. MinHeight: permitem definir a largura, altura e seus valores • CurrentColumn: permite obter a coluna actual. mínimos e máximo. ActualHeight; ActualWidth permitem • CurrentCell: permite obter a célula actual. obter qual é o valor actual da altura e da largura. • CurrentItem: permite saber o item actual. • ColumnWidth; MaxColumnWidth; • SelectedCells: permite saber quais as células 27
  • 28. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n que estão seleccionadas. alterada. • SelectedIndex: permite saber qual o índex do • CurrentCellChanged: ocorre quando o valor da item seleccionado. propriedade CurrentCell é alterado. • SelectedItem: permite obter o item que está • SelectedCellsChanged: ocorre quando o valor da seleccionado. propriedade SelectedCells é alterado. • SelectedItems: permitem saber os itens que estão seleccionados. Nota: O leitor que pretenda efectuar um estudo mais • HasItems: permite saber se a datagrid contém pormenorizado sobre as propriedades, métodos e eventos itens. da DataGrid, deve consultar a página DataGrid Class no • Items: permite obter a lista de itens. MSDN: http://bit.ly/ewIdaP • ItemsSource: permite obter a lista de itens. • ItemTemplate; ItemTemplateSelector: permitem definir o template aplicar aos itens. Antes de passarmos aos exemplos práticos, vejamos os vários tipos de colunas da DataGrid. Nota: Existem diferenças entre a propriedade Items e a propriedade ItemsSource e apenas se pode usar uma Em WPF, podemos definir os seguintes tipos de colunas: delas. Quando se usa a propriedade ItemsSource, não é • DataGridTextColumn – permite apresentar e editar texto; possível adicionar ou remover itens através desta • DataGridCheckBoxColumn – permite atribuir um valor propriedade ou através da propriedade Items. No entanto, lógico (verdadeiro / falso) se atribuirmos uma ObservableCollection ao ItemsSource, • DataGridComboBoxColumn – permite seleccionar uma essa questão é ultrapassada. opção de um conjunto de opções; • DataGridHyperlinkColumn – permite adicionar uma hiperligação; Os métodos mais relevantes são: • DataGridTemplateColumn – permite definir o template da • BeginEdit: permite invocar o comando coluna, isto é, podemos customizar a coluna. BeginEditCommand, que será responsável por alterar para modo de edição a linha ou célula seleccionada. O seguinte diagrama, permite-nos perceber melhor qual a • CommitEdit: permite invocar o comando classe de base de cada tipo de coluna. CommitEditCommand para célula ou linha que está em modo de edição. • CancelEdit:permite invocar o comando CancelEditCommand para célula ou linha que está em modo de edição. Os eventos mais relevantes são: • BeginningEdit: ocorre antes da célula ou linha entrar em modo de edição. Passemos agora aos exemplos práticos. • PreparingCellForEdit: ocorre quando a célula entra em modo de edição. Nota: De apoio a este artigo criei uma demo, o leitor poderá • CellEditEnding: ocorre antes de haver um obter em: http://bit.ly/efSP1 W “commit” da célula ou antes de ser cancelada a edição. • RowEditEnding: ocorre antes de haver um Suponhamos que temos um objecto empregado “commit” da linha ou antes de ser cancelada a edição. (Employee) e um conjunto de empregados (Employees). O • SelectionChanged: ocorre quando a selecção é empregado, tem como principais características: código, 28
  • 29. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n nome, se é o patrão, salário, taxas e aniversário. private void WindowLoaded(object sender, RoutedEventArgs e){ var employees=new Employees(); // add the employee list //using ItemsSource dataGridEmployees.ItemsSource = employees; } Notas: • A classe Employee implementa a interface Usando a propriedade Items para atribuir a lista de INotifyPropertyChanged para que sejam feitas notificações empregados. quando alguma propriedade é alterada. Isto é em parte responsável pela actualização da informação na Datagrid. Usando a propriedade Items para atribuir a • A classe Employees é uma ObservableCollection lista de empregados. de Employee, porque pretendo que sejam feitas private void WindowLoaded(object sender, notificações quando um ou mais empregrados são RoutedEventArgs e){ adicionados/removidos da lista de empregados. var employees=new Employees(); Caso tivesse optado por List<Employee>, // add the employee list Collection<Employee> ou IEnumerable<Employee> essas //using Items notificações não aconteceriam. Na imagem anterior é foreach (var employee in employees) possível analisar o que é uma ObservableCollection, sendo a implementação das interfaces INotifyCollectionChanged e dataGridEmployees.Items.Add(employee); INotifyPropertyChanged reponsável por informar sobre as } notificações/actualizações. • Resultado: 1 º Exemplo: • Objectivo: Apresentar numa janela uma Datagrid com uma lista de empregados, as colunas da Datagrid devem ser geradas automaticamente: • XAML <DataGrid Name="dataGridEmployees" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" AutoGenerateColumns="True"/> 2º Exemplo: • Objectivo: Apresentar numa janela uma Datagrid com uma lista de empregados, as colunas da Datagrid não • Code Behind: devem ser geradas automaticamente e apenas se pretende visualizar as colunas relativas ao nome, se é patrão, salário Usando a propriedade ItemsSource para atribuir a lista de e taxas. empregados. 29
  • 30. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n • XAML: <DataGrid Name="dataGridEmployees" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Nome" MinWidth="200" Binding="{Binding Name}" /> 3º Exemplo: <DataGridTextColumn • Objectivo: Formatar a apresentação do salário e das Header="Salário" Width="100" MaxWidth="150" taxas, ou seja, um salário com valor 0 (zero) deve Binding="{Binding Salary}"/> apresentar o valor “Não está atribuído” e os salários que <DataGridTextColumn estejam definidos devem apresentar o símbolo da moeda € Header="Taxa" Width="50" Binding="{Binding (euro). As Taxas devem apresentar o valor da taxa com o Rates}"/> símbolo de percentagem. <DataGridCheckBoxColumn Header="É patrão" Binding="{Binding Neste exemplo, temos necessidade de criar duas classes, IsBoss}"/> cada classe representa o conversor que será usado no </DataGrid.Columns> objecto de Binding da coluna. O conversor será </DataGrid> responsável por transformar o valor original no valor que é pretendido apresentar. Ambas as classes implementam a Notas: interface IValueConverter. • Através do objecto Binding da coluna é definido qual a propriedade do objecto que se vai apresentar. Portanto, o conversor para o salário será definido da • Foram definidas as medidas para a largura, largura seguinte forma: mínima e largura máxima das várias colunas. [ValueConversion(typeof(double), • Code Behind: typeof(string))] public class private void WindowLoaded(object sender, SalaryValueConverter:IValueConverter{ RoutedEventArgs e) { private const string var employees = new Employees(); NotDefinedValue="Não está definido"; // add the employee list private const string EuroSymbol = "€"; dataGridEmployees.ItemsSource = employees; public object Convert(object value, } Type targetType, object parameter, System.Globalization.CultureInfo culture) { • Resultado: if (value == null || (double.Parse(value.ToString()) == 0)) (A imagem com o resultado pode ser visto na coluna do return NotDefinedValue; lado direito em cima de todo) return string.Format("{0} {1}", 30
  • 31. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n • XAML: value, EuroSymbol); } É necessário adicionar o namespace dos resources public object ConvertBack(object xmlns:Converters="clr- value, Type targetType, object parameter, namespace:WPFDatagridImplementation.Converter System.Globalization.CultureInfo culture) { s" if (value is string && value.ToString().Equals(NotDefinedValue)) Nos resources da janela, inicializamos os dois conversores return 0; <Window.Resources> return value is string && <Converters:RatesValueConverter value.ToString().Contains(EuroSymbol) x:Key="ratesValueConverter"/> ? <Converters:SalaryValueConverter double.Parse(value.ToString().Replace(EuroSym x:Key="salaryValueConverter"/> bol, string.Empty)) </Window.Resources> : value; } É necessário alterar o Binding das colunas, é neste objecto } que definimos o conversor aplicar. <DataGrid Name="dataGridEmployees" O conversor para a taxa será definido da seguinte forma: Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" [ValueConversion(typeof(int),typeof(string))] AutoGenerateColumns="False"> public class <DataGrid.Columns> RatesValueConverter:IValueConverter{ <DataGridTextColumn private const string PercentageSymbol = Header="Nome" MinWidth="200" "%"; Binding="{Binding Name}" /> public object Convert(object value, <DataGridTextColumn Type targetType, object parameter, Header="Salário" Width="100" MaxWidth="150" System.Globalization.CultureInfo culture){ Binding="{Binding if (value is int && Path=Salary,Converter={StaticResource int.Parse(value.ToString()) == 0) salaryValueConverter}}"/> return string.Empty; <DataGridTextColumn return string.Format("{0} {1}", Header="Taxa" Width="50" Binding="{Binding value, PercentageSymbol); Path=Rates,Converter={StaticResource } ratesValueConverter}}"/> public object ConvertBack(object <DataGridCheckBoxColumn value, Type targetType, object parameter, Header="É patrão" Binding="{Binding System.Globalization.CultureInfo culture){ IsBoss}"/> throw new NotImplementedException(); </DataGrid.Columns> } </DataGrid> } 31
  • 32. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n • Code Behind: int.Parse(values[1].ToString()); private void WindowLoaded(object sender, if (salary == 0 && rates == 0) RoutedEventArgs e) { return string.Empty; var employees = new Employees(); // add the employee list return string.Format("{0} €", dataGridEmployees.ItemsSource = salary - salary * rates / 100); employees; } } public object[] ConvertBack(object • Resultado: value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } Nota: O objecto values que está definido no argumento do método Convert, recebe os valores de acordo com a ordem 4º Exemplo: que for definido no multibinding que será definido na • Objectivo: Apresentar uma coluna extra, que será o coluna. resultado do produto do salário com a taxa associada. • XAML: É necessário criar um conversor, que receba o salário e a taxa, e devolva o resultado final, formado. Neste caso, Adicionamos o conversor nos resources da janela. como é preciso receber dois valores a classe terá que <Window.Resources> implementar a interface IMultiValueConverter. <Converters:RatesValueConverter x:Key="ratesValueConverter"/> public class <Converters:SalaryValueConverter FinalySalaryConverter:IMultiValueConverter { x:Key="salaryValueConverter"/> public object Convert(object[] values, <Converters:FinalySalaryConverter Type targetType, object parameter, x:Key="finalySalaryConverter"/> System.Globalization.CultureInfo culture) { </Window.Resources> double salary = 0.0; int rates = 0; Adicionamos a nova coluna com o nome “Salário Final”, repare-se que usou-se um Multibinding, para permitir enviar if (values[0] is double) o valor do salário e o valor da taxa. salary = <DataGrid.Columns> double.Parse(values[0].ToString()); <DataGridTextColumn Header="Nome" MinWidth="200" Binding="{Binding Name}" /> if (values[1] is int) <DataGridTextColumn Header="Salário" rates = Width="100" MaxWidth="150" Binding="{Binding 32
  • 33. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n 5ºExemplo: Path=Salary,Converter={StaticResource • Objectivo: Apresentar a coluna de Aniversário, recorrendo salaryValueConverter}}"/> ao controlo DataPicker. <DataGridTextColumn Header="Taxa" Width="50" Binding="{Binding • XAML: Path=Rates,Converter={StaticResource ratesValueConverter}}"/> <DataGridTemplateColumn Header="Aniversário" <DataGridTextColumn Header="Salário MinWidth="100"> Final"> <DataGridTextColumn.Binding> <DataGridTemplateColumn.CellEditingTemplate> <MultiBinding <DataTemplate> Converter="{StaticResource <DatePicker finalySalaryConverter}"> SelectedDate="{Binding Birthday}" <Binding SelectedDateFormat="Short" /> Path="Salary"/> </DataTemplate> <Binding Path="Rates" /> </DataGridTemplateColumn.CellEditingTemplate> </MultiBinding> <DataGridTemplateColumn.CellTemplate> </DataGridTextColumn.Binding> <DataTemplate> <TextBlock </DataGridTextColumn> Text="{Binding Birthday, StringFormat=d}" /> <DataGridCheckBoxColumn Header="É </DataTemplate> patrão" Binding="{Binding IsBoss}"/> </DataGridTemplateColumn.CellTemplate> </DataGrid.Columns> </DataGridTemplateColumn> </DataGrid> • Code Behind: Nota: Apenas apresento o XAML da coluna criada. Foram definidos dois templates: um para o caso em que se está private void WindowLoaded(object sender, em modo de edição, em que usou aplicar um DatePicker. O RoutedEventArgs e) { outro template apenas apresenta a data. var employees = new Employees(); // add the employee list • Resultado: dataGridEmployees.ItemsSource = employees; } • Resultado: 33
  • 34. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n 6º Exemplo: employees; • Objectivo: Apresentar os empregados ordenados por Nome. ICollectionView view = CollectionViewSource.GetDefaultView(dataGridE mployees.ItemsSource); • Code Behind: view.Filter = new Predicate<object>(EmployeesWithSalaryGreaterT private void WindowLoaded(object sender, han500); RoutedEventArgs e) { } var employees = new Employees(); dataGridEmployees.ItemsSource = private bool employees; EmployeesWithSalaryGreaterThan500(object param) { ICollectionView view = var employee = (Employee)param; CollectionViewSource.GetDefaultView(dataGridE mployees.ItemsSource); if (employee.Salary > 500) return true; view.SortDescriptions.Add(new SortDescription("Name", return false; ListSortDirection.Ascending)); } } • Resultado: • Resultado: 8º Exemplo: 7º Exemplo: • Objectivo: As linhas da datagrid devem apresentar uma • Objectivo: Filtrar os empregados com salário superior a cor alternada. 500.00€. • XAML: • Code Behind: <DataGrid Name="dataGridEmployees" private void WindowLoaded(object sender, RoutedEventArgs e) { Grid.Column="1" Grid.ColumnSpan="3" var employees = new Employees(); Grid.Row="2" dataGridEmployees.ItemsSource = AutoGenerateColumns="True" 34
  • 35. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n AlternatingRowBackground="LightGray" <DataGrid Name="dataGridEmployees" AlternationCount="2"/> Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" private void WindowLoaded(object sender, AutoGenerateColumns="True" RoutedEventArgs e) { ColumnHeaderStyle="{DynamicResource var employees = new Employees(); columnStyle}" dataGridEmployees.ItemsSource = ColumnHeaderHeight="40" employees; GridLinesVisibility="All" } HorizontalGridLinesBrush="Red" VerticalGridLinesBrush="Green"/> • Resultado: • Code Behind: private void WindowLoaded(object sender, RoutedEventArgs e){ var employees = new Employees(); dataGridEmployees.ItemsSource = employees; } 9º Exemplo: • Objectivo: Alterar a altura do cabeçalho das colunas, alterar o tipo de fonte da letra e tamanho e cor. Alterar a cor • Resultado: das linhas horizontais e verticais da datagrid. • XAML: Nos resources da Window, definimos o estilo que iremos aplicar às células. <Window.Resources> <Style x:Key="columnStyle" TargetType="DataGridColumnHeader"> <Setter Property="FontFamily" Value="Arial Black" /> <Setter Property="FontSize" 1 0º Exemplo: Value="14"/> • Objectivo: Ao seleccionar uma célula e mostrar uma <Setter Property="Foreground" mensagem de aviso de que foi detectada uma alteração, Value="Red"/> apresentando o nome do empregado seleccionado e o </Style> nome da coluna seleccionada. </Window.Resources> 35
  • 36. A PROGRAMAR D a ta gri d e m Wi n d o ws Pre s e n ta ti o n Fo u n d a ti o n • XAML: selectedEmployee.Name); <DataGrid Name="dataGridEmployees" MessageBox.Show(message); Grid.Column="1" Grid.ColumnSpan="3" } Grid.Row="2" AutoGenerateColumns="True" • Resultado: SelectionMode="Single" SelectionUnit="Cell" CurrentCellChanged="DataGridEmployeesCurrentC ellChanged"/> • Code Behind: private void WindowLoaded(object sender, RoutedEventArgs e) Demo do artigo: http://bit.ly/efSP1 W { Contém: var employees = new Employees(); • Diagrama de Classes da hierarquia das colunas dataGridEmployees.ItemsSource = • Diagrama de classes da hierarquia da Datagrid employees; • Diagrama de classes do modelo usado no demo } • Interfaces private void • Classes de dados DataGridEmployeesCurrentCellChanged(object • Conversores sender, System.EventArgs e) { • Janela principal com menu para os vários exemplos Employee selectedEmployee = • Janelas dos vários exemplos (Employee)dataGridEmployees.CurrentItem; string message = String.Format("Foi Referências: seleccionada a coluna '{0}' do empregado(a) • MSDN: DataGrid Class - .Net Framework 4.0: {1}.", http://bit.ly/ewIdaP dataGridEmployees.CurrentCell.Column.Header, • WindowsClient.Net: WPF Toolkit: DataGrid Feature Walkthrough: http://bit.ly/hksWsL Link para o artigo: http://tinyurl.com/RPED28-05 AUTOR Escrito por Sara Silva É licenciada em Matemática – Especialidade em Computação, pela Universidade de Coimbra, actualmente é Software Developer no Porto. O entusiasmo pela área resultou na obtenção dos títulos de Microsoft Certified Profissional Developer – Windows 3.5, Microsoft Certified Tecnology Specialist – WPF 3.5, WPF 4 e Windows Forms. Faz parte de várias comunidades, tendo uma participação activa na Comunidade NetPonto e no P@P. 36
  • 37. A PROGRAMAR Pl a n o s d e E xe c u ç ã o e m O R AC LE Introdução sabemos qual a via que, mesmo não parecendo ser a mais óbvia, deverá ser a mais rápida. Se tivermos ouvido o Nas últimas duas edições, abordámos o tema da estado do trânsito há uma hora atrás, a situação deverá já optimização de SQL com o recurso a técnicas de melhoria estar totalmente diferente, quando sairmos de casa, e a do código SQL. Recorremos, nomeadamente, à utilização rota mais rápida poderá agora estar entupida. Se, por de bind variables e à correcta implementação de índices. último, desconhecermos totalmente o estado do trânsito, Nesta edição, vamos apresentar uma das ferramentas de seguiremos pelo caminho que consideramos mais directo diagnóstico que permitem prever e verificar a optimização: mas que, eventualmente, poderá não ser o mais rápido os planos de execução. naquele momento. O Oracle procede do mesmo modo, pelo que, manter as estatísticas actualizadas é uma mais-valia para que o optimizador possa tomar a melhor decisão e, no O que é caso do plano de execução, apresentar o plano mais idêntico à realidade. Antes de efectuar um SELECT na base de dados, o optimizador traça um plano de execução, de modo a avaliar que dados recolher, onde e como os deve obter. O plano de Criar a tabela PLAN_TABLE execução é influenciado por múltiplos factores e varia ao longo do tempo, isto é, varia consoante o estado presente Os planos de execução são registados numa tabela, da base de dados. usualmente definida como PLAN_TABLE, sob a forma de linhas com relações hierárquicas entre si. Por isso, é Os principais factores que definem o plano de execução possível registar vários planos de execução na são a dimensão das tabelas acedidas, a diversidade de PLAN_TABLE, de modo a compararmos diferentes queries. dados das tabelas (selectividade) e a existência ou não de índices. Mas, como é que o optimizador obtém, A PLAN_TABLE poderá não estar disponível no ambiente rapidamente, esta informação? O Oracle produz Oracle. O Oracle fornece um script que permite criar essa estatísticas da base de dados. As estatísticas registam os tabela facilmente. O script pode ser encontrado na principais factores que definem o plano de execução. Deste directoria %ORACLE_HOME%/rdbms/admin com o nome modo, o optimizador, em vez de percorrer todos os dados UTLXPLAN.SQL. Consoante a versão de Oracle que afectados por um SELECT, sabe à partida o que vai estamos a utilizar, o script pode conter algumas variações a encontrar. No entanto, para que as estatísticas produzam nível das colunas da tabela. Este script não é mais do que bons resultados nas queries, é fundamental que estejam um CREATE TABLE, mas não será aqui exposto, devido à actualizadas. Por exemplo, se a estatística nos diz que uma dimensão do mesmo e às variantes que existem para tabela tem dez registos mas, entretanto, carregámos um diferentes versões Oracle. milhão de novos registos, a estatística produzirá valores errados e induzirá o optimizador por um caminho que não é Tendo a garantia de que a tabela existe, devemos sempre o óptimo. limpar o seu conteúdo, antes de iniciarmos o “estudo” das queries, recorrendo à instrução TRUNCATE TABLE Podemos fazer uma analogia com uma deslocação de PLAN_TABLE. automóvel desde casa até ao local de trabalho. Se soubermos, antecipadamente, o estado do trânsito, 37
  • 38. A PROGRAMAR Pl a n o s d e E xe c u ç ã o e m O R AC LE Determinar o plano de execução Estamos, agora, em condições de começar a obter planos de execução das nossas queries. Necessitamos, primeiramente, de registar o plano de execução na PLAN_TABLE, recorrendo à instrução EXPLAIN PLAN SET STATEMENT_ID = 'XPTO' FOR, seguida da query que queremos analisar. Por exemplo: A forma correcta de ler o mapa do plano é começar pela instrução mais à direita (maior nível). Quando duas EXPLAIN PLAN SET STATEMENT_ID = 'XPTO' FOR instruções estão ao mesmo nível, começa-se pela que tem SELECT C.COD_ASSOC FROM ASSOCIADOS A um ID menor. Neste caso, vemos que a primeira instrução a INNER JOIN CARTOES C ON C.COD_ASSOC = ser executada será a n.º 2. A.CODIGO WHERE A.CODIGO BETWEEN 21000 AND 21500; Vejamos, primeiro, as colunas da PLAN_TABLE apresentadas nesta query: O STATEMENT_ID atribuído é o identificar do plano do tipo • Id: identificador da linha da instrução do presente varchar2. O plano está criado e podemos continuar a plano. Atenção, não é o ID da linha na PLAN_TABLE, mas determinar os planos de execução de outras queries ou, sim o ID da amostra de dados retirada dessa mesma por exemplo, verificar os planos antes e após o cálculo das tabela. Lembremo-nos que a PLAN_TABLE pode conter estatísticas. Os planos ficam registados na tabela e só vários planos de execução. serão eliminados manualmente, pelo que se poderão • Operation: O tipo de instrução a ser executada. guardar os registos para consulta futura. • Name: Tabela ou índice a que se refere a Operation. • Rows: Número de linhas afectadas ou acedidas. Analisar o plano de execução • Bytes: Total de bytes que serão movimentados para ler os dados da instrução. Naturalmente que, se a PLAN_TABLE é uma tabela, a • Cost: O custo de CPU para a instrução. Este visualização do plano de execução é feita com um SELECT campo não tem qualquer unidade, pelo que o mesmo à mesma tabela. Alguns editores SQL de Oracle já deverá ser utilizado como meio de comparação. Por possuem essa funcionalidade à distância de um clique. O exemplo, comparando o Cost CPU de uma query leve com que fazem é executar um dos muitos SELECT's possíveis à uma query mais pesada. Este valor é parametrizado num tabela. O Oracle também já facilita a consulta dos planos ficheiro de configuração do Oracle e a sua compreensão de execução através da seguinte instrução, adaptada aqui mais profunda seria alvo de um tema de administração de ao nosso exemplo, com o respectivo statement_id: bases de dados. SELECT * FROM TABLE(dbms_xplan.display('plan_table','xpto', Note-se que os campos apresentados pela função do 'all')); Oracle não correspondem aos campos da PLAN_TABLE em bruto. A função não faz mais do que criar uma VIEW com a selecção de dados da tabela do plano de execução. O resultado desta query poderia ser o seguinte: Analisemos, agora, a informação apresentada para este plano. Os ID's 2 e 3 estão sob a operação de junção NESTED LOOPS. Este é um dos tipos de junção de tabelas 38
  • 39. A PROGRAMAR Pl a n o s d e E xe c u ç ã o e m O R AC LE que consiste em: Tendo em conta que cada linhas das duas tabelas são (2) Escolher a tabela sem índice na condição, cruzadas obedecendo ao match: neste caso a tabela CARTOES que não possui um índice no campo de junção COD_ASSOC. É feito um FULL TABLE access("C"."COD_ASSOC"="A"."CODIGO") SCAN filtrando as linhas com a condição: (1 ) O Oracle pode agora juntar as tabelas, fazendo filter("C"."COD_ASSOC"<=21500 AND o INNER JOIN através do algoritmo de NESTED LOOPS. "C"."COD_ASSOC">=21000) Obtêm-se 394 linhas, no final, e terão sido acedidos 3940 bytes. Repare-se no * antes do 2, referente à nota em baixo (Predicate Information), que indica o filtro no SCAN com os Conclusão números de código do SELECT: O plano de execução é uma ferramenta bastante poderosa WHERE A.CODIGO BETWEEN 21000 AND 21500; para fazer uma avaliação prévia do impacto da nossa query (3) Para cada uma das 51 4 linhas da tabela na base de dados. Seja para avaliar o impacto de uma anterior, já filtrada, é feito um acesso ao índice da tabela query num ambiente de produção em alturas críticas ou ASSOCIADOS, ASSOCIADOS_PK, obtendo apenas os simplesmente para optimizar e procurar queries com menor dados com: consumo de CPU ou IO, o plano de execução é um bom começo. filter("A"."CODIGO"<=21500 AND "A"."CODIGO">=21000) Conhecendo, detalhadamente, o tipo de operações que o Oracle executa, o plano de execução pode ser, na grande 39
  • 40. A PROGRAMAR Pl a n o s d e E xe c u ç ã o e m O R AC LE maioria dos casos, mais do que suficiente para prever o resultado da query na BD. No entanto, nem sempre o plano de execução é eficaz. Há casos específicos que Referências: necessitam de especial atenção e de uma avaliação pós- processamento através de outra ferramenta, o SQL Trace. Estrutura da tabela PLAN_TABLE e lista de operações O SQL Trace vai registar as operações realizadas pelo produzidas pelo plano de execução: Oracle, permitindo-nos analisar detalhadamente o que http://download.oracle.com/docs/cd/A5861 7_01 /server.804/ ocorreu no SELECT. Enquanto o plano de execução a58246/explan.htm#891 permite fazer uma avaliação a priori, o SQL Trace faz uma avaliação a posteriori. Outras formas de representar o plano de execução: http://download.oracle.com/docs/cd/A5861 7_01 /serve Convém, ainda, frisar que, para que o plano de execução r.804/a58246/explan.htm#1 088 seja o mais fiel possível, as estatística deverão estar actualizadas, o que nem sempre é possível ou viável se a dimensão das bases de dados for muito grande. Link para o artigo: http://tinyurl.com/RPED28-07 AUTOR Escrito por Ricardo Trindade É actualmente o responsável pela área informática dos Serviços Sociais da Câmara Municipal de Lisboa onde efectua, desde administração de sistemas, até programação em .NET. Está também ligado ao projecto N-Ideias na área da consultoria, webdesign e software, trabalhando essencialmente com BD's Oracle, PostgreSQL e SQL Server. 40
  • 41. A PROGRAMAR S m a rty PH P Te m p l a te E n gi n e A maioria das pessoas que aprendem PHP começam, Introdução ao Smarty normalmente, a construir as suas aplicações Web de forma bastante rudimentar. Isto é normal, pois ao longo do tempo Neste pequeno artigo vamos usar a versão 3.0.7 do Smarty com que trabalham com PHP, os programadores vão-se que pode ser descarregada aqui 1 ). Vamos também usar a habituando, aprendendo novas técnicas e desenvolvendo o versão 5.3.0 do PHP. seu próprio estilo de programar. O Smarty pe rmite-nos chamar determinados ficheiros Este estilo desenvolvido reflecte-se maioritariamente na e imprimi-los no ecrã, substituindo certos valores estrutura da aplicação desenvolvida. Isto porque cada pelos obtidos e/ou gerados pela nossa aplicação, aplicação tem as suas funcionalidades, e estas reflectem- mostrando ao utilizador final, dados dinâmicos. se na necessidade de uma estrutura sólida capaz de suportar aplicações mais robustas, extensíveis e seguras. A diferença entre o método de templates em PHP ou Samrty é a mais fácil adaptação do visual da aplicação, No entanto, há estruturas padrões e versáteis que são sem que o designer tenha de saber a linguagem de dadas como ideais para a construção de aplicações, e programação (PHP) e tornando o template mais fácil de criam-se então frameworks capazes de tornarem estas entender. Este método torna também pequenos pedaços de estruturas disponíveis para qualquer programador construir texto (possivelmente HTML) sejam reutilizados mais qualquer aplicação sem se ter de preocupar muito com a facilmente, evitando partes de código duplicadas na estrutura base da aplicação. aplicação. Em PHP usam-se muitas aplicações que seguem a lógica O Smarty não necessita de nenhuma configuração do do padrão de arquitectura de software MVC, que pretende sistema, tornando-o assim extremamente simples de separar a lógica do padrão da lógica de apresentação. instalar em qualquer Sistema Operativo, dado que os Models e Views, tendo pelo meio os Controllers. Mas não é passos de instalação baseiam-se apenas na criação e necessariamente obrigatório usar frameworks MVC nem edição de pastas e ficheiros. sequer aplicar o padrão MVC para criar aplicações que separem a lógica da aplicação da lógica da apresentação. Instalar o Smarty Cada programador pode criar a sua aplicação de modo a separar estas duas camadas, mas isso nem sempre é um Depois de termos feito o download da última versão do trabalho fácil quando bem feito, e quando mal feito pode Smarty, descomprimimo-la e copiamos os ficheiros para resultar no aparecimento de graves falhas na aplicação e uma pasta no nosso projecto (na raiz do projecto ou de grandes quebras de performance. Assim sendo, porque possivelmente numa pasta chamada smarty). Neste artigo não usar uma framework poderosa, robusta e simples de usaremos uma pasta dentro do nosso projecto chamada usar que já exista e nos simplifique o trabalho? É aqui que smarty. Portanto, apenas temos de copiar os conteúdos da o Smarty entra. pasta libs para dentro da pasta smarty. Depois, no decorrer do desenvolvimento do nosso projecto apenas vamos ter de especificar a localização de certas pastas necessárias ao funcionamento do Smarty, tais como a pasta de cache e dos templates. 41
  • 42. A PROGRAMAR Sm a rty PH P Te m p l a te E n gi n e então o seguinte código. $smarty->assign("value", "Artigo de Primeiro Projecto em Smarty introdução ao Smarty"); Portanto, agora que temos os ficheiros que necessitamos, vamos começar a trabalhar com a biblioteca. Tudo gira à Isto vai fazer com que as variáveis definidas no template volta de uma classe, chamada Smarty, mas para isso com o nome value sejam substituídas pela respectiva necessitamos de incluir o ficheiro. string. Mas também é possível passar arrays. Para isso usamos a mesma função, a diferença estará no template. require('C:caminhoAbsolutoParaOProjectosmar tySmarty.class.php'); $array = new Array( 1 => "Introdução ao Smarty", 2 => "Instalar o Smarty", 3 => Depois necessitamos de instanciar a classe para uma "Primeiro Projecto em Smarty"); variável, algo simples. $smarty->assign("chapters", $array); $smarty = new Smarty(); Depois apenas temos de mostrar o template formatado. Agora só temos de definir alguns directórios, necessários $smarty->display("index.tpl"); para o funcionamento da biblioteca. O ficheiro index.tpl apenas terá de conter o seguinte texto: Primeiro, vamos criar quatro pastas dentro da pasta smarty: <html> cache, configs, templates, templates_c. Depois <head> adicionamos o seguinte código ao ficheiro. <title>Smarty</title> //Define as pastas. O seu caminho deve ser </head> absoluto <body> $smarty- <h1>{$value}</h1> >setTemplateDir('C:caminhoAbsolutoParaOProje <h2>Capítulos:</h2> ctosmartytemplates'); <ul> $smarty- {foreach $chapters as $chapter} >setCompileDir('C:caminhoAbsolutoParaOProjec <li>{$chapter}</li> tosmartytemplates_c'); {/foreach} $smarty- </ul> >setCacheDir('C:caminhoAbsolutoParaOProjecto </body> smartycache'); </html> $smarty- >setConfigDir('C:caminhoAbsolutoParaOProject osmartyconfigs'); Sintaxe do Templates Feito isto, podemos começar a usar o Smarty à vontade. Apesar de o Smarty ser muito bom, ele não adivinha os A sintaxe usada na construção dos templates em Smarty é valores que a página vai ter, pelo que temos de ser nós a bastante simples e flexível, completamente abstraída da dar-lhos. Isto é bastante simples, apenas temos de chamar linguagem (PHP). Os ficheiros são HTML com pequenas uma função e especificar o nome da variável que queremos partes específicas do Smarty. substituir no template e o seu respectivo valor. Adicionemos Para aumentar a performance da aplicação e evitar gastos de tempo desnecessários ao fazer parse dos ficheiros de 42
  • 43. A PROGRAMAR S m a rty PH P Te m p l a te E n gi n e template de cada vez que uma página é vista, o Smarty A parte do nome é o nome que será usado no template “compila” os templates para ficheiros PHP, aumentando para se referenciar à variável, enquanto que o conteúdo é assim drasticamente a performance. Quando um template é aquilo que a variável vai conter. As variáveis podem ser editado, o Smarty detecta-o e recompila o template, não simples, como strings e integers ou arrays e objectos. sendo por isso necessária preocupação ao modificar os Quando a variável é uma simples string, para a mostrarmos templates. no HTML, basta: A Sintaxe do Smarty é de tal maneira poderosa que é {$nome} possível incluir lógica dentro dos templates, no entanto esta lógica deverá ser direccionada para a apresentação. Com No entanto podemos querer usar arrays, e para isso isto pretendo dizer que a sintaxe do Smarty suporta teremos de usar funções como Smarty. excepções, ciclos, variáveis, includes e um sem-número de Para imprimirmos objectos, é simples e bastante similar ao outras coisas fascinantes que não seriam possíveis de PHP. abordar apenas num artigo. Por isso, aqui vamos apenas {$name>someproperty} abordar os aspectos mais importantes e mais comuns. {$name->anothervar} Basicamente, com o Smarty, temos o HTML, no qual podemos adicionar as partes do código que serão interpretadas pelo motor. Estas partes do código estão, geralmente, entre chavetas ({ e }), no entanto isto pode ser mudado. Para isso, basta-nos usar as seguintes linhas de For código. Muitas vezes podemos querer mostrar uma lista, ou algo $smarty->left_delimiter = "({"; cujo número de itens não é estático/previamente definido. $smarty->right_delimiter = "})"; Isso significa que temos de usar ciclos no próprio template Podemos personalizar os delimitadores que quisermos. para percorrer um array fornecido pelo script PHP. Para Os delimitadores servem para delimitar cada tag Smarty, isso usamos o ciclo for ou o foreach. pelo que cada tag Smarty imprime o valor de uma variável A sua sintaxe é a seguinte: ou chama uma determinada função. Essa função pode ser {for $index=1 to 20 max=3} interna, ou seja, definida pelo próprio Smarty, ou externa, - {$index}<b /> definida por nós e criada através de plugins. Aqui vamos {forelse} ver algumas das funções internas do Smarty, mas também Sem items. algumas funções externas que vêm já definidas com o {/for} motor. Isto irá imprimir: - 1<br /> Variáveis - 2<br /> - 3<br /> As variáveis são, provavelmente, a coisa mais simples, básica e necessária para o Smarty, pois elas são o método O parâmetro max é opcional, e o bloco do forelse também. convencional e mais usado para introduzir dados no Este é mais importante quando temos valores dinâmicos no template, e consequentemente, mostra-los. As variáveis inicio e no fim do ciclo, pois estes podem ser nulos ou para o Smarty, no PHP, podem ser definidas usando a inválidos (o inicio ser maior que o fim). seguinte função. $smarty->(“nome”, $conteudo); 43
  • 44. A PROGRAMAR Sm a rty PH P Te m p l a te E n gi n e da estrutura condicional, podem visitar aqui 2). Foreach O foreach é mais indicado quando o próprio PHP nos retorna um array. Este pode ou não ser associativo. Por Cycle exemplo, para imprimir um array associativo, definimos no PHP: Esta é uma função muito útil que permite obter valores de forma cíclica. Por exemplo, temos um ciclo for com 1 0 $utilizador = array('Nome Real' => 'Pedro iterações, e temos uma função cycle com 3 valores, por Silva', 'Nickname' => 'Scorch', 'E-mail' => exemplo: Um, Dois e Três, ou seja, ele vai obter os valores 'xpto@email.net'); pela seguinte ordem: Um Dois Três Um Dois Três Um Dois $smarty->assign('utilizador', $utilizador); Três Um. Mas vamos ver um exemplo. Depois escrevemos o seguinte código no template: {for $index=1 to 20 max=3} {foreach $utilizador as $var} - {cycle name="ciclo_1" <b>{$var@key}:</b> {$var}<br /> values="Um,Dois,Três"} {/foreach} <b /> {/for} Isto irá imprimir: O parâmetro name é opcional, e permite-nos ter mais que <b>Nome Real:</b> Pedro Silva<br /> um ciclo ao mesmo tempo. O parâmetro values deve conter <b>Nickname:</b>Scorch<br /> os valores a percorrer, separados por vírgulas e sem <b>E-mail:</b>xpto@email.net<br /> espaços. Apesar da vírgula ser o valor por defeito, pode-se sempre definir um separador através do parâmetro A lógica é muito similar à do PHP. delimiter. O conjunto de todos os parâmetros pode ser visto aqui 3). Esta função é particularmente interessante quando If, Elseif e Else imprimimos os dados numa tabela ou noutra forma qualquer de listagem, e queremos que a cor de fundo, por Como não podia deixar de ser, o Smarty suporta estruturas exemplo, mude ciclicamente em cada item. Por exemplo, o condicionais. Uma vez que os templates são compilados primeiro ficará branco, o segundo cinzento, o terceiro para scripts PHP, estas estruturas são extremamente branco e o quarto cinzento, até ao fim da lista. poderosas e muito similares às nativas do PHP. Este é um exemplo simples: Conclusão {if $var == '1'} Condição if verdadeira. Smarty é um sistema de templates em PHP, que permite {elseif $name == '2'} uma variedade enorme de funcionalidades e tem uma Condição elseif verdadeira. grande performance, uma vez que os templates são {else} convertidos para código PHP. É o que sobra. A lista completa de funções e documentação pode ser {/if} encontrada aqui 4), em Inglês. Para uma lista completa de exemplos e das propriedades 44
  • 45. A PROGRAMAR S m a rty PH P Te m p l a te E n gi n e Exemplo do funcionamento de uma aplicação a usar Smarty 1 ) http://smarty.net/download 2) http://smarty.net/docs/en/language.function.if.tpl 3) http://smarty.net/docs/en/language.function.cycle.tpl 4) http://smarty.net/docs/en/index.tpl Link para o artigo: http://tinyurl.com/RPED28-1 0 AUTOR Escrito por Pedro Silva Estudante, é um apaixonado por computadores e tecnologia. Gosta de Web Development, sendo a área onde se inicou na programação. Também trabalha com várias tecnologia .NET. Gosta também de multimédia, desporto e fotografia. É membro do staff da comunidade Portugal-a- Programar, e autor de um blog: Blog / @Scorchpt 45
  • 47. COLUNAS CORE DUMP - O X No Quadrado Certo VISUAL (NOT) BASIC - Entity Framework 4:Model/Code-First
  • 48. CORE DUMP O X N o Qu a d ra d o C e rto O tema da escolha da universidade é um tópico sazonal e recorrente no P@P, dando aso a vários tópicos e, como é natural, a opiniões opostas. Sendo um participante assíduo dessas discussões, e estando na altura de pensar de forma clara e séria qual a universidade a escolher, vou partilhar aqui a minha opinião como profissional e empregador na área das Tecnologias de Informação (TI). Mas antes, comecemos pelo senso comum. Parece-me pacífico que um candidato escolha determinada instituição por vários parâmetros, sendo um deles o da preparação para o mercado de trabalho. Diz-nos o bom senso que optando por uma instituição que é reconhecida como boa instituição onde se licenciaram não é um dos pesos fortes pelo mercado de trabalho, a presença de um curso superior no mercado. Acontece que essa situação não é um contra- no Curriculum Vitae (CV) de um candidato é um bom cartão exemplo do que se passa. As empresas de RH vivem da de visita para ser chamado para uma entrevista. colocação de pessoas em empresas, pelo que é do seu interesse entrevistas todas as pessoas e tentar colocá-las Quem não tem experiência profissional foca de forma numa empresa, esse é o seu negócio. Há empresas, e quase exclusiva todos os créditos que tem para apresentar actividades, onde a formação de base não requer uma a um empregador no seu percurso académico. Neste preparação tão exigente, fazendo com que esses ponto, o nome da instituição que consta no CV do candidatos sejam boas escolhas, ficando contentes as três candidato é um bom cartão de visita e funciona como partes envolvidas. primeiro filtro. Este primeiro filtro é normalmente usado para fazer duas pilhas de CV, separando os candidatos cujo CV Uma vez passado o choque, voltemos ao essencial: vamos ler com atenção dos candidatos que ficam quando enviam um CV em que pilha é que querem que eliminados logo na primeira ronda. Para os que estão o mesmo seja colocado? A resposta a esta pergunta “chocados” ou “revoltados” com esta abordagem crua e até, começa muitos anos antes da larga maioria das pessoas de certa forma, cruel, tenho apenas a dizer que da mesma escrever o seu primeiro CV, começa quando colocam o X forma que eu uso a instituição como primeiro filtro, também no quadrado certo, no quadrado que vos vai permitir ser as empresas de recursos humanos (RH) o fazem. E não reconhecidos pelo mercado como estando, à partida, mais somos os únicos. Este tipo de abordagem é normal para as bem preparados. A verdade é que o mercado sabe muito empresas que operam nesta área. bem quem são as instituições que melhor preparam as pessoas para a vida profissional, e tipicamente isso é Há alguns dias atrás (re)confirmei esta situação numa valorizado. Para os que se lembram do tempo da bolha, reunião com uma empresa de RH no âmbito do nessa altura quase qualquer um podia ingressar e fazer recrutamento de um consultor. Nesta altura muitos de vós uma carreira em TI, tal era a necessidade de recursos que estão a pensar que isto não é verdade porque têm as empresas, em particular as consultoras, tinham. Mas conhecimento de pessoas que foram a entrevistas e cuja esses tempos já lá vão, e num mercado cada vez mais 48
  • 49. CORE DUMP O X N o Qu a d ra d o C e rto difícil e num país com uma taxa de desemprego tão não têm curso superior. Para todos os que não têm curso elevada, todos os argumentos são preciosos, e um carimbo superior e querem ingressar nesta vida, as dificuldades são de uma instituição reconhecida pelo mercado tem bastante acrescidas. No entanto há outras formas de começar. No peso. que toca à parte técnica e tecnológica é fácil encontrar informação e estudar por si mesmo ou tirar cursos ou Com a introdução do regime de Bolonha, algumas mesmo certificações. No entanto não se devem ter ilusões, empresas viram essa situação como um retrocesso mesmo assim será mais difícil iniciar uma carreira em TI. É educativo na preparação dos estudantes para o mercado que ao contrário do que muitos jovens pensam, numa de trabalho. Para garantir o mesmo nível de preparação, licenciatura de informática não se ensina a programar. essas mesmas empresas passaram a exigir aos seus Os conhecimentos adquiridos ao longo do curso são muitos candidatos não uma licenciatura mas sim um mestrado. O e variados, alguns até são de utilidade duvidosa, mas são mestrado é uma boa forma de aumentar os conhecimentos valiosos. Essencialmente uma licenciatura ensina a pensar, mas é também uma forma das empresas darem menos a analisar, ensina a descobrir soluções e alarga os peso à instituição onde um candidato se licenciou. No horizontes dos estudantes, fazendo com que estes tenham entanto, as regras são as mesmas da licenciatura, o valor contacto com imensas coisas novas e diferentes. Numa do carimbo das instituições que ministram mestrados têm comparação directa, não é de estranhar que quem saia de pesos diferentes no mercado de trabalho. O mestrado uma universidade reconhecida pelo mercado tenha mais proporciona também uma especialização e uma maneira de facilidade de encontrar um bom emprego e de fazer carreira preparar o direccionamento da carreira em TI. Estas duas em TI. vantagens são muito interessantes tanto para para as empresas, que valorizam os seus recursos e investem na Se após toda a minha argumentação não estão investigação e desenvolvimento, como para os candidatos, convencidos, então guiem-se pelo vosso bom senso. Esse, que podem querer evoluir por uma vertente mais aposto que vos diz para colocarem os X nos quadrados estimulante para si. certos quando preenchem o formulário de candidatura ao ensino superior. Nesta altura alguns já se estão a questionar sobre os que Link para o artigo: http://tinyurl.com/RPED28-09 AUTOR Escrito por Fernando Martins Faz parte da geração que se iniciou nos ZX Spectrum 48K. Tem um Mestrado em Informática e mais de uma década de experiência profissional nas áreas de Tecnologias e Sistemas de Informação. Criou a sua própria consultora sendo a sua especialidade a migração de dados. 49
  • 50. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst Existem três tipos de abordagens quando estamos a utilizar necessário, reutilizar em diferentes projectos. Entity Framework 4.0: database­first onde são criadas as nossas entidades (classes) usando uma base de dados já Para a criação do nosso modelo, numa abordagem model­ existente; model­first onde é criado o nosso modelo first, criamos um novo projecto no Visual Studio 201 0 conceptual e, com base nele, é gerado um script para a definindo como Framework a 4.0, e com o nome criação da base de dados; e code­first onde é utilizado “RevistaClassLibrary”. POCO (Plain Old Code CRL) para criação manual de toda a lógica de entidades e ligações, não perdendo no entanto, todas as vantagens da utilização do Entity Framework. Na edição da Revista PROGRAMAR nº 26, de Dezembro de 201 0, abordei a utilização do modelo database­first, mostrando como criar as entidades e como efectuar algumas operações CRUD (acrónico para Create, Read, Updade e Delete). Neste artigo irei abordar de uma forma geral como utilizar as restantes abordagens: model­first e code­first. Abordagem Model-First Esta abordagem permite-nos criar o nosso modelo NOTA: Após o projecto criado podemos apagar a classe conceptual, usando o Visual Studio, e depois, com base que aparece por defeito (Class1 .vb) pois não será neste, criar a base de dados. Após a criação do modelo é necessária. criada a DDL (Data Definition Language), que será guardado num ficheiro *.sql e que nos permite então criar a Adicionamos um novo item, recorrendo aos templates no base de dados. separador Data - ADO.NET Entity Data Model. Esta opção, que iremos definir com o nome RevistaModel.edmx, irá Existem algumas vantagens desta abordagem pois é uma criar um ficheiro *.edmx que irá representar o nosso forma de trabalhar onde temos o nosso modelo e não nos modelo. precisamos de preocupar com a base de dados ou como esta irá ser construída. Não necessitamos também de ter conhecimentos muito específicos de bases de dados (como criar tabelas, relações, etc.), sendo tudo feito no Visual Studio de uma forma simplificada. Além disso, ficamos com o DDL que nos permite criar a base de dados em qualquer altura (por exemplo após a instalação da aplicação). Neste exemplo será criada uma Class Library, permitindo assim isolar a lógica de acesso a dados e, caso seja 50
  • 51. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst Ainda antes de iniciarmos a construção do nosso modelo O *.edmx é um ficheiro XML que define o modelo conceptual, existe uma opção interessante, se olharmos conceptual, o modelo de dados e as relações entre as para a janela das propriedades: Pluralize New Objects. diferentes entidades. Esta opção, caso esteja definida como verdadeira (True), irá automaticamente tentar pluralizar os nomes das Na seguinte opção, podemos escolher se queremos gerar entidades. Infelizmente não funciona na versão Portuguesa, um modelo de uma base de dados, como foi abordado no mas se utilizarmos designações em Inglês, é muito artigo anterior na Revista PROGRAMAR edição 26, ou criar interessante e prática. um modelo vazio. Iremos escolher a segunda opção – Empty model. Para este exemplo vamos então criar um modelo muito simplificado que permita representar as edições da revista PROGRAMAR. Vamos criar duas entidades que vão representar os artigos e os seus autores. Com o nosso documento criado, ainda vazio, existem duas ferramentas importantes para o desenvolvimento do Por defeito, quando criamos uma nova entidade, ele inclui a modelo: a Toolbox, que tem agora objectos específicos para criação de um identificador (chave primária), que podemos, o Entity Framework e o Model Browser que permite caso não seja necessário, retirar. Não define também explorar o nosso modelo. Existem duas formas de criar o nenhuma herança, podendo esta ser indicada no “Base modelo: através da Toolbox, já referida anteriormente, ou Type”, ou seja, podemos definir heranças entre entidades, clicando com o botão direito do rato sobre a janela aberta. seleccionado a entidade correspondente. Esta segunda opção é mais simples de utilizar. Adicionando algumas propriedades, e definindo os tipos de dados correctos (ex. DataNascimento = DateTime ou Edicao = Int32), rapidamente construímos os modelos para representar as edições da revista. De notar que por defeito, quando é adicionada uma nova propriedade à entidade, o tipo de dados está definido como String, com um tamanho de armazenamento máximo para este tipo de dados (2^3-1 ) - nvarchar(max). Podemos e devemos alterar, caso seja necessário, assim como explorar e ajustar as restantes propriedades, como por exemplo, o tamanho máximo para 51
  • 52. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst uma String (Max Lenght), qual o valor por defeito (Default Value), se permite valores nulos (Nullable), etc. E já estão então criadas as duas entidades e neste o fazer é só necessário clicar com o botão direito do rato sobre o editor e seleccionar a opção “Generate Database from Model”. Irá então aparecer um wizard que nos permite seleccionar uma ligação já existente ou criar uma nova. momento só nos falta definir a relação entre ambas. Como um artigo pode ter vários autores e um autor pode ter vários artigos, necessitamos de criar uma relação muitos para muitos (many-to-many). Ao adicionarmos a relação entre as entidades, usando a opção Association, é criado um novo campo no final, Seleccionado a ligação que pretendemos, irá ser gerado um script DDL que permitirá, após execução, criar uma designado por Navigation Property, que irá permitir a navegação entre as entidades. Podemos alterar o nome da propriedade de navegação (caso seja necessário). E já está! Este foi o último passo para criar o modelo conceptual e é agora altura de gerar a base de dados. Para 52
  • 53. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst base de dados em SQL Server 2005, 2008 e Azure. Project) e a System.Data.Entity (separador .NET). É necessário também copiar a Connection String, que se encontra no ficheiro de configuração (app.config), uma vez que esta foi definida na Class Library, no momento de ligação à base de dados. <connectionStrings> <add name="RevistaModelContainer" connectionString="metadata= res://*/RevistaModel.csdl| res://*/RevistaModel.ssdl| res://*/RevistaModel.msl; provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=master;Integrated Security=True; MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> </connectionStrings> Reparem que apenas criamos duas entidades (autores e artigos), mas como definimos uma relação muitos para muitos (many-to-many), é necessário utilizar uma tabela A Connection String tem um conjunto de metadata que auxiliar. O Entity Framework fez isso por nós e no SQL indica a localização do ficheiro de CSDL (Conceptual ficamos então com três tabelas, como mostra a seguinte Schema Definition Language), do SSDL (Store Schema imagem: Definition Language) e do MSL (Mapping Schema Language). O asterisco (*) indica que estes ficaram embebidos no ficheiro binário, podendo isto ser alterado, indicando nas propriedades do modelo conceptual, que o Metadata Artifact Processing não esta Embed in Output Assembly mas sim Copy to Output Directory. Indica depois a ligação propriamente dita à base de dados. Abordagem Code-First Esta é outra abordagem que podemos utilizar em Entity Framework, além das já referidas neste artigo (model­first) Se no Solution Explorer escolhermos a opção “Show All e no artigo da edição 26 da revista PROGRAMAR Files”, podemos ver que o nosso modelo (*.edmx) tem um (database­first). ficheiro com a extensão *.vb (neste caso Uma das vantagens do code­first (ou como é também RevistaModel.Designer.vb) . Neste ficheiro podemos ver e o designado code­only), utilizando POCO (Plain Old CLR código que está por detrás do nosso modelo conceptual, e objects ), é que não ficamos “presos” ao Entity Framework, efectuar eventualmente, algumas alterações. pois todas as classes geradas automaticamente herdam da Ao adicionarmos um novo projecto a esta solução (*.sln), classe EntityObject. Além disso utilizamos as classes que que irá representar a camada de apresentação queremos, com muito menos código (um exemplo mesmo (Presentation Tier), ou usando externamente, é necessário pequeno como este tem mais de 300 linhas de código), o adicionar referências à classe que criamos (separador torna a manutenção da aplicação muito mais simples. 53
  • 54. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst Public Property Id As Integer Para usar esta abordagem, onde somos nós que Public Property Nome As String desenhamos as classes que vão representar as entidades, Public Property DataNascimento As DateTime podemos seleccionar o nosso modelo conceptual (*.edmx) e na janela de propriedades, na opção “Code Generation ' Overridable para permitir o LazyLoading Strategy”, que está definida para Default, seleccionamos Public Overridable Property Artigos() As None. Isto fará com que o código gerado automaticamente ICollection(Of Artigo) seja apagado, possibilitando desta forma o desenvolvimento personalizado. Sub New() Artigos = New List(Of Artigo) Para representar o modelo conceptual mostrando End Sub anteriormente, e tendo em conta que este é um exemplo End Class muito simples (para efeitos de demonstração apenas), necessitamos apenas de três classes: Artigo, Autor e RevistaModelContainer. IMPORTANTE : A declaração de variáveis em Visual Basic não é, como sabem, case sensitive. No entanto, na As duas primeiras classes ( Artigo e Autor), vão representar declaração das propriedades das entidades (classes) é as duas entidades e definem as propriedades da classe e a obrigatório que se declarem de acordo com o modelo associação entre ambas (usando uma ICollection). (*.edmx), ou seja, há distinção entre maiúsculas e Podemos ter mais propriedades e mais métodos nas minúsculas. classes, mas para que isto funcione, temos de ter pelo menos as que estão definidas no modelo. A terceira classe é onde se define o nosso Container, que herdas do ObjectContext, ou seja, é onde criamos a ligação Imports System.Collections entre o Entity Framework e as nossas classes anteriores. O Imports System.Data.Objects ObjectSet é novo na versão 4.0 do Entity Framework e permite-nos trabalhar os dados como colecções, permitindo Public Class Artigo também executar queries. Public Property Id As Integer Public Class RevistaModelContainer Public Property Titulo As String Inherits ObjectContext Public Property Texto As String Public Property Edicao As Integer Sub New() ' Overridable para permitir o LazyLoading ' Indica a ConnectionString (ver em Public Overridable Property Autores() As ' app.config) e nome do Container ICollection(Of Autor) MyBase.New("name=RevistaModelContainer", "RevistaModelContainer") Sub New() Autores = New List(Of Autor) ' Cria as instancias dos ObjectSets End Sub _Artigos = MyBase.CreateObjectSet(Of Artigo)("Artigos") End Class _Autores = MyBase.CreateObjectSet(Of Autor)("Autores") Public Class Autor 54
  • 55. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst ' Define que o LazyLoading está Por isso o Entity Framework permite a utilização/criação de ' activo (por defeito não está) templates que geram o código por nós. São designados por MyBase.ContextOptions.LazyLoadingEnabled T4 (Text Template Transformation Toolkit) Text Templates e = True são ficheiros de texto com uma extensão *.tt . End Sub Existe um template para a criação de classes POCO. Não está disponível nos templates do Visual Studio 201 0, mas Private _Artigos As ObjectSet(Of Artigo) se abrirmos o modelo conceptual e seleccionarmos “Add Public ReadOnly Property Artigos() Code Generation Item”, podemos pesquisar em "Online As ObjectSet(Of Artigo) Templates" e instalar. Get Return _Artigos End Get End Property Private _Autores As ObjectSet(Of Autor) Public ReadOnly Property Autores() As ObjectSet(Of Autor) Get Return _Autores End Get End Property End Class Como é possível ver neste codigo, habilitamos a opção LazyLoadingEnable do ObjectContext, colocando-a a True. Após a rápida instalação, podemos então seleccionar É necessário também definir as propriedades como ADO.NET POCO Entity Generator. Overridable para que o Entity Framework saiba que propriedades usar. O Lazy Loading permite que as entidades relacionadas sejam automaticamente carregadas da fonte de dados quando acedemos às propriedades de navegação (neste caso Autores e Artigos). E é tudo! Com poucas linhas de código criamos as nossas classes, que definem as nossas entidades, e criamos o nosso Container que permite interligar as classes com o Entity Framework. Mas este é apenas um exemplo bastante simples e caso usássemos um modelo complexo, com inúmeras entidades e associações, era muito trabalhoso criar todas estas Isto irá adicionar dois ficheiros *.tt ao projecto: classes POCO. POCOModel.tt e POCOModel.Context.tt. O POCOModel tem as classes que representam as entidades e o 55
  • 56. VISUAL (NOT) BASIC E n ti ty Fra m e wo rk 4. 0 : M o d e l - Fi rst e C o d e - Fi rst POCOModel.Context tem as classe de contexto. principal novidade a DbContext API, que é uma abstracão simples do ObjectContex e que pode ser utilizada em qualquer abordagem (Database­First, Model­First e Code­ First). Existe também algumas alterações na abordagem Code-First. Alguns endereços interessantes : ADO.NET team blog http://blogs.msdn.com/b/adonet/ NOTA: Ao adicionarmos os templates ao projecto, todo o Beginner's Guide to the ADO.NET Entity Framework código de Entity Framework será apagado. http://msdn.microsoft.com/en-us/data/ee71 2907 Desta forma, e muito rapidamente, criamos as nossas EF 4.1 Release Candidate Available classes POCO com a ajuda de templates. http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 - release-candidate-available.aspx Como foi possível ver ao londo deste artigo, e do artigo da edição nº 26 da revista PROGRAMAR, existem diferentes EF 4.1 Model & Database First Walkthrough abordagens para a utilização do Entity Framework 4.0, http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 - permitindo criar um modelo relacional de uma base de model-amp-database-first-walkthrough.aspx dados, criar um modelo e com base neste criar a base de dados ou criando as nossas classes (entidades) usando EF 4.1 Code First Walkthrough POCO, ficando desta forma independentes e com a http://blogs.msdn.com/b/adonet/archive/2011 /03/1 5/ef-4-1 - possibilidade de uma maior personalização de toda a code-first-walkthrough.aspx lógica. A existencia e utilizaçao de templates permite simplificar o processo de criação de classes POCO e podemos inclusivé criar os nossos próprios templates. No momento da criação deste artigo está já disponível o Entity Framework 4.1 Release Candidate que tem como Link para o artigo: http://tinyurl.com/RPED28-01 AUTOR Escrito por Jorge Paulino Exerce funções de analista-programador numa multinacional sediada em Portugal. É formador e ministra cursos de formação em tecnologias Microsoft .NET e VBA. É Microsoft Most Valuable Professional (MVP), em Visual Basic, pela sua participação nas comunidades técnicas . É administrador da Comunidade Portugal-a-Programar e membro de várias comunidades (PontoNetPT, NetPonto, MSDN, Experts- Exchange, CodeProject, etc). É autor do blog http://vbtuga.blogspot.com - twitter @vbtuga 56
  • 57. COMUNIDADES AndroidIPC - Inter Process-Communication Automatização de deployments em Windows Azure
  • 58. COMUNIDADE ANDROIDPT An d ro i d I PC - I n te r Pro c e s s - C o m m u n i c a ti o n As aplicações de Android correm sobre uma máquina virtual Language). Esta linguagem tem uma sintaxe bastante de Java, de nome Dalvik. Uma das particularidades desta simples, e consiste apenas na declaração da assinatura máquina virtual, é que as aplicações estão limitadas a uma dos métodos responsáveis pela comunicação. Sandbox de execução, ou seja, o seu espaço de memória é privado. Este sistema é muito semelhante ao A título de exemplo, vamos produzir 2 aplicações muito comportamento as aplicações nativas do sistema operativo simples, de nomes appA e appB, que comunicarão entre si. subjacente do Android, o GNU/Linux. A appA enviará uma mensagem à appB com o pedido para calcular o produto de 2 números inteiros. A appB receberá Uma das consequências disto, é que a troca de informação estes parâmetros na mensagens, e devolverá o resultado entre aplicações excluí logo à partida a partilha de do produto dos mesmos. Apesar da simplicidade do informação através de memória partilhada. O que resta, é a exemplo, servirá para demonstrar os problemas envolvidos troca de mensagens entre aplicações. na produção da solução, tais como, o que fazer quando a O Android fornece vários mecanismos para envio de aplicação com que estamos a comunicar não existe. mensagens entre aplicações, alguns são mais apropriados que outros, dependendo do cenário de utilização. Temos por exemplo os BroadcastReceivers, que se tratam de O primeiro passo será definir o ficheiro AIDL. Este ficheiro classes que recebem informação que é enviada para o contém a definição da função que a appA irá chamar. sistema operativo, e este trata de retransmitir a informação para as várias aplicações que se registaram como package ipc; “Receivers” para esse tipo de informação. Este método não é o ideal em muitos casos, veja-se por interface ServicoIPC { exemplo que a informação fica passível a ser enviada para int multiplicar(in int num1, in int num2); várias aplicações e não só para uma, e que a comunicação } é só numa direcção, ou seja, a mensagem é enviada, recebida, mas não há sequer confirmação de que a mesma Repare que ambos os argumentos têm o prefixo “in”. Isto foi recebida, nem é possível retornar qualquer tipo de faz parte da especificação AIDL, neste caso é “in” porque informação. Existe ainda o senão de que num ambiente em estamos a lidar com tipos de dados simples de Java, e que existe mais que um BroadcastReceiver, o sistema esses apenas podem ser do tipo “in”. operativo envia a informação para a 1 ª aplicação, e se esta assim decidir pode consumir a mensagem e não a passar O ficheiro que contem o código em cima especificado de volta para as seguintes. deverá estar presente tanto na appA como na appB, na pasta src ou em dentro de qualquer package dentro da Para resolver, este e outros cenários, a SDK fornece um mesma. O ficheiro terá obrigatoriamente de ter a extensão mecanismo de troca de mensagens entre aplicações, aquilo .aidl , uma vez que em tempo de compilação estes ficheiros que usualmente se chama de IPC (InterProcess- são tratados de forma especial atendendo à sua extensão. Communication). Do lado da appB, que é aplicação que irá receber a Este mecanismo é apoiado por uma linguagem de ligação mensagem, e fazer o cálculo, temos de declarar um Service das duas aplicações que queremos que comuniquem entre de Android para lidar com a recepção da mensagem. O si, chamada de AIDL¹ (Android Interface Definition código em baixo apresentado ilustra esta situação. 58
  • 59. COMUNIDADE ANDROIDPT An d ro i d I PC ... package com.exemplo.appb; <application …> <service android:name="ServicoRemoto" import android.app.Service; android:process="com.exemplo.appb.SetPrefsSer import android.content.Intent; vice"> import android.os.IBinder; <intent-filter> import android.os.RemoteException; <action import android.util.Log; android:name="com.exemplo.appb.IPC" /> </intent-filter> public class ServicoRemoto extends Service { </service> </application> @Override ... public void onCreate() { super.onCreate(); } Do lado da appA, temos agora de efectuar a ligação com a appB. Primeiro temos de garantir que temos o ficheiro .aidl @Override na árvore de fonte de código da mesma, como já tinha sido public IBinder onBind(Intent intent) { referido. É importante também garantir que o ficheiro AIDL esteja na mesma package de Java em ambas as return new ServicoIPC.Stub() { aplicações. Por motivos de escalabilidade convém separar a lógica da /** ligação e do envio da mensagem, do resto do código, assim * Método que calcula o produtor de num1 fica mais simples usar e manter o uso da comunicação com num2 inter-procedual conforme a aplicação vai crescendo. */ Para tal, vamos fazer uma classe que implementa o public int multiplicar(int num1, int ServiceConnection. O seguinte código exemplifica uma num2) throws RemoteException { classe deste género. Note-se que seria nesta classe que o Log.d("appB","A appB recebeu um programador pode gerir os pedidos, a altura em que são mensagem para calcular o produto de "+num1+" enviados, possíveis filas de prioridade de pedidos, etc. com "+num2); return num1 * num2; } package com.exemplo.appa; }; } import android.content.ComponentName; } import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; Após isto, temos obviamente de adicionar o Service criado em cima ao Manifest da aplicação, neste caso da appB. É public class ConServicoRemoto implements também aqui que vamos expor o Service ao exterior. ServiceConnection{ Fazemos isso adicionando as linhas coloridas ao ficheiro AndroidManifest.xml : ServicoIPC service = null; 59
  • 60. COMUNIDADE ANDROIDPT An d ro i d I PC private boolean estaVivo= false; appB"); estaVivo=true; } /** * Constructor. @Override */ public void public ConServicoRemoto() { onServiceDisconnected(ComponentName name) { // construtor vazio service=null; } estaVivo=false; Log.d("appA","Desconectou da appB"); public int adicionarRemoto(int val1, } int val2){ if (service==null) /** { * Log.d("appA","O Serviço * @return True se a ligação à  não está ligado. Causa possível: appB não aplicação appB estiver activa. False caso está instalada"); contrário. return 0; */ } public boolean ligacaoEstaActiva(){ try { return estaVivo; return } service.multiplicar(val1, val2); } catch (RemoteException e) { } Log.d("appA","RemoteException ao tentar fazer pedido de multiplicar à  appB"); Agora falta apenas fazer uma Activity de Android, ainda na e.printStackTrace(); appA, a exemplificar o uso da classe acima declarada. return 0; } Para a nossa Activity, declaramos na pasta “layout” o seguinte ficheiro main.xml que será a Interface Gráfica da mesma. } <?xml version="1.0" encoding="utf-8"?> <RelativeLayout @Override xmlns:android="http://schemas.android.com/apk public void /res/android" onServiceConnected(ComponentName name, android:orientation="vertical" IBinder boundService) { android:layout_width="fill_parent" service = android:layout_height="fill_parent" ServicoIPC.Stub.asInterface((IBinder) > boundService); <EditText android:id="@+id/valor1" Log.d("appA","Ligou-se à  60
  • 61. COMUNIDADE ANDROIDPT An d ro i d I PC E por fim temos o código da classe de nome Principal que android:layout_width="60dip" fará uso desta interface gráfica acima declarada, e da android:layout_height="wrap_content" classe ConServicoRemoto. android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="50dip" /> Conclusão <EditText android:id="@+id/valor2" Repare-se que o código é simplista, não existem android:layout_width="60dip" verificações se o utilizador de facto escreve números android:layout_height="wrap_content" inteiros, e não existe tratamento de erros na classe android:layout_below="@id/valor1" ConServicoRemoto. Isso fica ao critério do leitor, uma vez android:layout_centerHorizontal="true" que este exemplo está focado unicamente no tema android:layout_marginTop="50dip" /> abordado. <Button android:id="@+id/btn_calcular" android:layout_width="wrap_content" Bibliografia android:layout_height="wrap_content" android:layout_below="@id/valor2" 1 . AIDL na documentação oficial da SDK de Android: android:layout_centerHorizontal="true" http://developer.android.com/guide/developing/tools/aidl.htm android:layout_marginTop="50dip" l android:text="Calcular"/> <TextView android:id="@+id/resultado" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btn_calcular" android:layout_marginTop="40dip" android:layout_centerHorizontal="true" android:text="O resultado aparecerá aqui" /> </RelativeLayout> Link para o artigo: http://tinyurl.com/RPED28-03 AUTOR Escrito por Pedro Veloso Licenciado em Ciências da Computação na Universidade do Minho, trabalha actualmente na EmergeIT. Desenvolve profissionalmente para Android, e tem interesse especial na área de Unix, em particular Linux, e administração de sistemas deste tipo. Faz parte integrante das comunidades androidPT e GTUG Portugal. 61
  • 62. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re Primeiro que tudo, e para que todos nos possamos encontrar com a mesma base de conhecimento, parece- nos importante contextualizar todos os leitores quanto ao tema em questão. O que é então Cloud computing? Cloud computing é, numa definição abrangente, uma abordagem à computação assente sobre os conceitos de escalabilidade e alta disponibilidade de processamento e armazenamento online, disponível a um inúmero número de dispositivos e endpoints. bloco possibilita também o acesso através de ligações remotas para as máquinas que estivermos a usar e a Apresentando-se este como um mercado emergente e possibilidade de fazer uso de VPNs. De ressalvar que estas potencialmente bastante rentável, principalmente porque o redes virtuais não têm de ser apenas entre máquinas que “factor custo” passa a ter um papel fulcral e preponderante se encontram na cloud, mas podem também ser entre nas decisões ao longo de todo o planeamento e máquinas que se encontram na cloud e máquinas que se desenvolvimento aplicacional, algumas empresas de encontram on-premises. referência na área das TI não poderiam ficar de fora da corrida. Relativamente ao SQL Azure, este bloco possui a oferta da Microsoft ao nível dos sistemas relacionais de base de Entre as várias ofertas que existem hoje no mercado, dados. Esta versão é em tudo parecida com o SQL Server parece-nos importar salientar o caso do Google App Engine 2008 R2, apresentando no entanto algumas restrições. da Google, o AWS e o EC2 da Amazon, as inúmeras Neste momento encontram-se disponíveis dois tipos ofertas da Rackspace ou mesmo da Salesforce, e (edições) de bases de dados que podemos criar num finalmente o Windows Azure Platform da Microsoft. Será servidor SQL Azure: Web Edition e Business Edition. sobre esta última que focaremos as nossas atenções, sem qualquer desprimor para as restantes ofertas mencionadas. As diferenças fundamentais entre estas duas hipóteses pretendem-se com o tamanho máximo de uma base de A plataforma oferecida pela Microsoft é composta então por dados e com o custo associado às mesmas. As versões três grandes blocos: Windows Azure, SQL Azure e Web são bases de dados que serão normalmente utilizadas Windows Azure AppFabric. para ambientes de baixos requisitos, pois possuem limites de 1 GB e de 5GB. Já as bases de dados associadas a O Windows Azure disponibiliza capacidades de edições Business possuem limites máximos de 1 0GB, computação e armazenamento escalável, elástico e 20GB, 30GB, 40GB e 50GB e serão normalmente utilizadas altamente disponível, bem como uma gestão para suporte a aplicações de negócio complexas (Line of completamente automatizada dos serviços usados, Business Applications). Neste bloco encontram-se ainda possibilitando realizar todas estas tarefas com recurso a incluídos os sistemas de reporting e de sincronização de ferramentas, tecnologias e linguagens de programação já dados. conhecidas pelos programadores. Além de tudo isto, este 62
  • 63. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re Para por término a esta contextualização relativamente aos permite-nos fazer uso de todo esse poder de blocos disponíveis, falta pois falar do Windows Azure processamento apenas quando tal é necessário, revertendo AppFabric. Este bloco inclui então acesso a um Service para máquinas com processamento mais limitado quando Bus, a mecanismos de federação e controlo de acessos, tal não se justifique. Tal capacidade permite ter alta bem como a mecanismos de caching. Mais uma vez, todos disponibilidade quando sabemos que vamos precisar dela e estes mecanismos são geridos e mantidos de forma apenas pagar por a mesma durante o período de carência, automatizada e não imputável a nós. ao contrário do que aconteceria num data center que tivéssemos de ser nós a dimensionar e a gerir. Sendo que o objectivo deste artigo é falar sobre automatização de deployments em Windows Azure, é Quando fazemos uso de uma máquina no Windows Azure, imperativo regressarmos a este bloco para falarmos de podemos fazer uso de três perfis de execução: Worker forma mais aprofundada sobre o mesmo e sobre os Role, Web Role e VM Role. Uma Worker Role é serviços que o compõem. O poder computacional essencialmente um executável que executa no servidor disponível encontra-se seccionado em cinco segmentos com as características que nós definirmos, permitindo desta distintos: XS (Extra Small), S (Small), M (Medium), L forma implementar os mais variados cenários, como seja a (Large) e XL (Extra Large). Estes segmentos são disponibilização de servidores aplicacionais próprios, progressivos, isto é, a capacidade computacional e de Apache Tomcat, servidores de base de dados, entre muitas armazenamento local em cada uma das máquinas incluídas outras coisas. vai aumentando de forma gradual. Uma Web Role goza de todas as potencialidades e Uma instância XS possui processamento partilhado, 768MB capacidades de uma Worker Role, mas encontra-se de memória RAM e 20GB de armazenamento local, suportada no/pelo IIS (Internet Information Services), apresentado um custo de $0.05 por cada período horário, podendo correr em modo Full Trust ou Partial Trust. A VM sendo que uma instância S possui já 1 CPU Core dedicado, Role é o perfil adicionado mais recentemente à oferta que 1 .7GB de RAM e 250GB de armazenamento local, nos permite colocar uma imagem de um sistema operativo apresentando um custo horário de $0.1 2. Se precisarmos a executar no Windows Azure. Esta Role, ao contrário das de uma máquina com 2 CPU Cores dedicados com 3.5GB restantes que são completamente geridas pela plataforma, de RAM e 500GB de armazenamento, então o segmento M deixa ao nosso cuidado tudo o que tem a ver com a gestão será a resposta por um custo horário de $0.24. Se da máquina, desde actualizações ao sistema operativo a precisarmos de capacidades de processamento e garantias de segurança da própria máquina e das armazenamento superiores, poderemos então abordar as instalações/actualizações nela efectuadas, pois somos nós ofertas L ou mesmo XL. Uma máquina com o perfil L possui quem controla tudo. já 4 CPU Cores, 7GB de RAM e 1 TB de armazenamento local, apresentando um custo horário de $0.48, sendo que O Windows Azure dispõe de uma componente denominada uma máquina com o perfil XL possui 8 CPU Cores, 1 5GB Fabric que é responsável por toda a gestão de máquinas, de RAM e 2TB de armazenamento, apresentando um custo falhas e recuperações dos sistemas existentes na horário de $0.96. plataforma. Como podemos ver pelos dados fornecidos, a capacidade Tendo isto em linha de conta, é importante pois perceber computacional e de armazenamento local é efectivamente qual é então o ciclo de vida das Roles que são geridas por progressiva ao longo de todos os segmentos, bem como o este Fabric, relembrando que nos referimos às Worker custo associado a cada um deles. Se precisamos de mais Roles e às Web Roles. Para melhor ajudar a compreender processamento, o custo será necessariamente maior. No todo este ciclo, apresenta-se então graficamente o mesmo: entanto, sendo que a plataforma é totalmente elástica, isso 63
  • 64. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re Figura 1 – Ciclo de vida de uma Role Uma Role tipicamente estende o RoleEntryPoint, passando que devem ser efectuados todos os processos de término desta forma a poder ser envolvida em todo o ciclo de vida “gracioso” das aplicações que se encontrem a correr na controlado pelo Fabric. Quando o processo WaWorkerHost Role, bem como a salvaguarda de todos os dados que é iniciado (processo que representa a Role), dá-se o possam ser relevantes armazenar num armazenamento carregamento do assembly associado a essa instância, persistente. Este armazenamento persistente pode ser uma começando o Fabric por efectuar uma chamada ao método base de dados ou, tirando partido do Azure Storage que se OnStart(). encontra incluído no Windows Azure, como Blobs. Esta chamada faz com que o estado da instância seja Para melhor compreender como efectuar um deployment colocado como Busy, o que significa que o Load Balancer no Windows Azure, teremos de analisar o que esse do Azure não vai ter essa instância em conta quando processo envolve. Um serviço é então composto por dois estiver a processar pedidos para serem respondidos artefactos primordiais: um ficheiro de definição do serviço aplicacionalmente. É neste método que devem ser (*.csdef) e um ficheiro de configuração do serviço (*.cscfg). efectuados todos os processos de automatização do Quando efectuamos a compilação de um projecto para deployment, de forma a garantir que quando a instância for Windows Azure, o Visual Studio pega no código e ficheiros colocada como disponível, todos os sistemas se encontram associados e no ficheiro de definição do serviço, disponíveis e funcionais. embalando tudo num só pacote (*.cspkg), sendo que este ficheiro se encontra encriptado de forma a garantir a O método seguinte a ser chamado pelo Fabric é o método segurança da informação nele contida. Run(). Esta chamada faz com que o estado da instância passe agora para Ready, significando isto que a instância De uma forma resumida, podemos ilustrar este processo se encontra totalmente operacional e disponível para como: atender a pedidos, passando desta forma a ter tida em conta pelo Load Balancer quando este estiver a distribuir Encrypted( Zipped( Code + *.csdef ) ) == *.cspkg carga pelas várias instâncias disponíveis. Se o método Run() terminar, o Fabric invoca o método OnStop() da Role. Com este pacote disponível (*.cspkg) e com o ficheiro de Esta chamada faz com que o estado da instância seja configuração (*.cscfg), podemos então dar início à criação modificado novamente para Busy, sendo removida também e disponibilização de um novo serviço no Windows Azure. da lista de instância disponíveis para o Load Balancer poder utilizar para direccionar os pedidos. É neste método 64
  • 65. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re Figura 2 – Exemplo de um ficheiro de definição de serviço (*.csdef) Figura 3 – Exemplo de um ficheiro de configuração de serviço (*.cscfg) Tal como mencionado anteriormente, um deployment dito teremos sempre de fazer build de um novo pacote de “normal”, conterá em si todos os ficheiros necessários à deployment. Esta situação pode não ser particularmente disponibilização de uma dada aplicação/site. Apesar de gravosa caso estejamos a falar de deployments de esta ser a solução mais simples de todas, o seu custo de pequena dimensão, mas caso estejamos a falar de pacotes manutenção pode ser bastante elevado e penoso. Porquê? de vários megabytes, a gravidade aumenta consideravelmente, podendo mesmo tornar-se num factor Imaginemos que estamos a disponibilizar uma crítico. aplicação/sistema que possui inúmeros ficheiros. Cada vez que necessitarmos de efectuar uma modificação, por mais Para aumentar a complexidade do caso em questão, diminuta que ela seja e por menos ficheiros que envolve, imaginemos agora que o sistema recorre a um ficheiro de 65
  • 66. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re configurações internas, ficheiro este que é específico para Uma das soluções possíveis pode passar pela cada serviço que disponibilizarmos. Neste caso, além de disponibilização, em Azure Storage, de um arquivo termos de lidar com o problema já mencionado comprimido com todos os ficheiros comuns necessários à anteriormente, teremos ainda de lidar com a necessidade aplicação/sistema, bem como de um ficheiro de de ter pacotes de deployments em tudo em tudo configuração por cada serviço existente. Desta forma, a semelhantes, onde apenas esse ficheiro de configuração é Role, durante a chamada do Fabric ao seu método diferente. Além do crescimento exponencial que se pode OnStart(), poderia contactar o armazenamento persistente verificar ao nível da quantidade de pacotes necessários, há e descarregar e descomprimir os ficheiros comuns, bem também de ter em conta a dificuldade de manutenção como o ficheiro de configuração da aplicação/sistema. acrescida destes ficheiros. Desta forma, apenas seria necessário gerir um ficheiro comprimido partilhado por todos os serviços, minimizando Poderemos fazer alguma coisa para assim a margem de erro e facilitando a sua manutenção. minimizar/ultrapassar estas situações? Há alguma solução “mágica”? A solução anterior apresenta ainda um enorme problema no caso de o arquivo partilhado ser consideravelmente grande, A resposta à primeira pergunta é claramente afirmativa, pois quando maior for, mais tempo vai demorar a sendo que não existem silver bullets para resolver este tipo disponibilizar no armazenamento persistente. Esta de problemas, apenas abordagens mais correctas ou dificuldade pode ser ultrapassada de uma forma mais ou menos correctas, sendo que devem ser sempre analisadas menos simples através da existência de um mecanismo de caso a caso. actualizações. Ou seja, além do arquivo inicial de que a Role faria uso, seriam também disponibilizados outros 66
  • 67. COMUNIDADE NETPONTO Au to m a ti za ç ã o d e d e p l o ym e n ts e m Wi n d o ws Azu re arquivos que permitiriam ir actualizando o sistema de forma proceder a uma diminuição significativa dos custos incremental e com recurso a arquivos de tamanho envolvidos em todo o processo, não só pela diminuição da consideravelmente inferior. Não só diminuiríamos o tempo largura de banda necessária para disponibilizar um novo necessário à disponibilização de uma actualização, como serviço, mas também pela redução do espaço necessário aumentaríamos a facilidade de manutenção de todo o em Azure Storage para armazenar toda a informação. sistema, pois disponibilizaríamos de um histórico fidedigno. Há ainda um outro factor que nos deve incomodar e Páginas úteis: preocupar: a necessidade da existência de um ficheiro de configuração por cada serviço existente. A solução para Microsoft Windows Azure Homepage este problema passaria pela introdução neste ficheiro de http://www.microsoft.com/windowsazure/ wildcards, como seja por exemplo o caso de [database_name]. Esta wildcard permitiria à Role proceder Windows Azure SDK Downloads à configuração deste ficheiro, por defeito genérico, com http://www.microsoft.com/windowsazure/windowsazuresdk+ dados específicos de cada serviço. Estes dados poderiam tools/ estar configurados no ficheiro de configuração do serviço (*.cscfg) já mencionado anteriormente, ou poderíamos fazer Microsoft Windows Azure Team Blog uso de Tables, disponíveis em Azure Storage. http://blogs.msdn.com/b/windowsazure/ Recorrendo a algumas das técnicas mencionadas, existe Artigos Interessantes um enorme aumento da capacidade de manutenção dos http://blogs.msdn.com/b/jnak/archive/201 0/02/11 /windows- sistemas, bem como da facilidade com que se pode criar e azure-roleentrypoint-method-call-order.aspx disponibilizar um novo serviço. No limite, para disponibilizar http://msdn.microsoft.com/en-us/library/gg433030.aspx um novo serviço poderá ser apenas necessário um ficheiro de configuração do serviço (*.cscfg) específico e/ou Azure Storage Explorer + SQL Azure Migration Wizard configurar um conjunto de dados existentes numa dada http://azurestorageexplorer.codeplex.com/ Table existente em Azure Storage. http://sqlazuremw.codeplex.com/ É também importante relembrar a diminuição da margem de erro e de risco existentes, factores extremamente importantes quando se trata de disponibilizar novos serviços. Finalmente, há ainda a mencionar o facto de se Link para o artigo: http://tinyurl.com/RPED28-02 AUTOR Escrito por Virgílio Esteves É Research Leader do grupo de R&D de uma multi-nacional portuguesa. Nutre um enorme gosto por arquitectura de software, desenvolvimento em WPF, Silverlight e XNA, e cloud computing. Participa activamente na comunidade NetPonto e é autor do blog http://pontonetpt.org/blogs/raposo - Twitter: @vraposo 67