segunda-feira, 21 de dezembro de 2009

Aplicação FindAndReplace

Devido a problemas de Acessibilidade Web encontrados num projecto recente desenvolvido em tecnologia Sharepoint, decidiu-se construir uma pequena aplicação com o objectivo de automatizar a localização e substituição de tags html obsoletas de acordo com as normas de acessibilidade a cumprir.

Estes atributos são gerados pelo Sharepoint, aquando a inserção/edição de conteúdos em controlos do tipo RichHtmlField.



Com este controlo, o utilizador tem a possibilidade de formatar o conteúdo que insere e, após a publicação da página, o html que é gerado pelo Sharepoint nem sempre cumpre as normas de acessibilidade estabelecidas pelo W3C, entidade que define as directivas para a acessibilidade do conteúdo da Web.

Neste caso específico, poderíamos, por exemplo, pesquisar num site (e nos seus sites “filhos”) de acordo com o URL que o utilizador indicar e substituir os parâmetros indicados em Localizar pelos de Substituir, como é ilustrado na imagem seguinte.




/******************************Abrir o site indicado no campo URL*******************************/

using (SPSite site = new SPSite(tbUrl.Text))
{
SPWeb web = null;
try
{
SPContext context = SPContext.GetContext(site.RootWeb);
SPSecurity.RunWithElevatedPrivileges(delegate()
{
web = context.Site.OpenWeb(tbUrl.Text);
});
Localizar(web);

}
finally
{
if (web != null)
web.Dispose();
}


/***********************Localizar o que está indicado no campo Localizar*********************/
private void Localizar(SPWeb web)
{
try
{
SPQuery query = new SPQuery();
//Pesquisa no Field CorpoArtigoGenerico substituindo os caracteres <> pelo seu valor hexadecimal
query.Query = "<Where><And><Contains><FieldRef Name='CorpoArtigoGenerico' /><Value Type='HTML'>" + tbLocalizar.Text.Replace("<", "&#60;").Replace(">", "&#62;") + @"</Value></Contains><IsNotNull><FieldRef Name='TituloArtigoGenerico'/></IsNotNull></And></Where>";
SPListItemCollection listItem = web.Lists["Páginas"].GetItems(query);
if (listItem.Count != 0)
{
Substituir(listItem, web);
}
//se nao retornar resultados ou não tiver encontrado paginas do tipo artigos genericos
else
{
MessageBox.Show("No site " + web.ToString() + " não foi encontrado o termo pesquisado");
}
}
catch
{
MessageBox.Show("Erro");
}

//para cada site filho vai ser feita a pesquisa e substituiçao
for (int i = 0; i < web.Webs.Count; ++i)
{
Localizar(web.Webs[i]);
}

}


Para essa substituição acontecer, são percorridos os passos normais de uma edição de página em Sharepoint: a saída da página, a entrada da página e a publicação da mesma.

/***Editar a página, substituir pelo termo indicado no campo Substituir e Publicar a página******/

private void Substituir(SPListItemCollection listItem, SPWeb web)
{

foreach (SPListItem li in listItem)
{
if (PublishingPage.IsPublishingPage(li))
{
PublishingPage page = PublishingPage.GetPublishingPage(li);
try
{
page.ListItem.File.CheckOut();
string corpoAntigo = page.ListItem["CorpoArtigoGenerico"].ToString();
string corpoNovo = corpoAntigo.Replace(tbLocalizar.Text, tbSubstituir.Text);
//faz a substituiçao do texto antigo pelo novo
page.ListItem["CorpoArtigoGenerico"] = corpoNovo;
//faz o update, checkin, publish e aprove da pagina
page.Update();
page.ListItem.File.CheckIn("Actualizado pela Aplicacao Find&Replace");
page.ListItem.File.Publish("Publicado pela Aplicacao Find&Replace");
page.ListItem.File.Approve("Aprovado pela Aplicacao Find&Replace");
}
catch
{
MessageBox.Show("Houve um problema na saida do ficheiro");
}

}
}
MessageBox.Show("No site " + web.ToString() + " foram feitas alteraçoes");
}


Mais uma vez, dando como exemplo este caso, estas substituições estavam restritas a campos específicos de determinados esquemas de página. Por exemplo, a pesquisa seria feita para encontrar/substituir os parâmetros em causa apenas no campo Descrição do esquema de página Artigo.

Em suma, esta aplicação está construída com um objectivo muito específico mas pode servir como base para uma ideia com os mesmos propósitos.

segunda-feira, 30 de novembro de 2009

Pesquisa em listas Sharepoint 2007

Ao longo do tempo que fui explorando o desenvolvimento de aplicações em Sharepoint 2007, conheci diversas formas de efectuar pesquisas sobre listas. Neste post faço a comparação entre quatro métodos de pesquisar informação em listas, com o objectivo de podermos tomar decisões informadas no desenvolvimento de soluções em Sharepoint 2007.

Para a elaboração deste post desenvolvi uma pequena aplicação que permite efectuar pedidos a páginas Web e que mede o tempo decorrido entre a execução do pedido e a recepção da resposta. Esta aplicação executa pedidos em paralelo durante um determinado período de tempo.

Para cada método de pesquisa foram feitos dois testes que descrevo de seguida, ambos num conjunto de 350 pedidos distribuídos por 3 minutos:

  • Uma lista de páginas preenchida com 100 itens;
  • Uma lista de páginas preenchida com 400 itens.

Note-se que neste post apenas me foco na pesquisa numa única lista. Numa segunda parte deste post irei comparar as pesquisas com os mesmos métodos em n listas de páginas pertencentes a diferentes sites de publicação.

De seguida apresento os quatro métodos de pesquisa utilizados nos testes, não demonstrarei a implementação destes visto que este assunto se encontra amplamente difundido na blogosfera.

  • Pesquisa com Foreach: pesquisa utilizando um ciclo Foreach percorrendo o object model do Sharepoint 2007.
  • Pesquisa com SPQuery: pesquisa utilizando o objecto SPQuery que permite executar a pesquisa numa lista.
  • Pesquisa com SPSiteDataQuery: pesquisa utilizando o objecto SPSiteDataQuery que permite pesquisar sobre várias listas em simultâneo.
  • Pesquisa com CrossListQueryInfo: pesquisa utilizando o objecto CrossListQueryInfo que permite executar pesquisas em várias listas em simultâneo e tirando partido de um mecanismo de cache de dados denominado de CrossListQueryCache. Este objecto permite ainda fazer aundience target dos resultados das pesquisas.

    Deixo ainda um post que explica o conceito de audience target: SharePoint Audience Targeting vs. Item Level Security

Foreach


Clique para aumentar

O gráfico apresenta os resultados dos testes referentes ao método de Foreach. Da análise destaca-se um considerável aumento do tempo de pesquisa com o aumento de itens na lista. Destaca-se ainda que em ambos os testes existe bastante oscilação de valores entre as diferentes pesquisas o que nos indica que é um método bastante irregular. Parece ainda que com o aumentar do número de itens esta irregularidade é mais acentuada.

SPQuery

Clique para aumentar

Este gráfico apresenta os resultados referentes ao método de pesquisa com o objecto SPQuery. As grandes diferenças que se apresentam em relação ao método anterior são: maior independência quanto ao número de itens da lista e um decréscimo do tempo médio das pesquisas.

SPSiteDataQuery

Clique para aumentar

O gráfico anterior mostra os resultados dos testes efectuados com o objecto SPSiteDataQuery. Na generalidade o resultado é semelhante ao método anterior, apesar de se notar que os tempos de pesquisa são mais constantes.

CrossListQueryInfo

Clique para aumentar

Por último apresento o resultado dos testes com o objecto CrossListQueryInfo. Este teste revela resultados bastante semelhantes aos resultados dos dois testes anteriores.

Comparação

Clique para aumentar

Em cima podemos observar de uma forma mais clara a média dos resultados dos diferentes métodos de pesquisa sob as mesmas condições. Em ambos se nota que o método de Foreach tende a ser o mais demorado e por isso deve ser evitado. Nos restantes casos a diferença de resultados é pouca, o que nos deixa com alguma margem de manobra na escolha do método de pesquisa a utilizar.

Na minha opinião devem-se utilizar os métodos nas circunstâncias para as quais foram desenvolvidos. Assim para uma pesquisa em apenas uma lista e sem contemplar audience targeting utilizaria o método da pesquisa com o objecto SPQuery.

Por último gostaria ainda de observar que também seria interessante de testar a memória e o tempo de processador que utiliza cada um dos métodos. Assunto que, com muita pena minha, não foi contemplado nos testes efectuados.