<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5645812914185429411</id><updated>2011-08-02T06:41:51.277-07:00</updated><category term='celesc'/><category term='xml'/><category term='caché'/><category term='carreira'/><category term='testes'/><category term='javascript'/><category term='soap'/><category term='mangás'/><category term='divertido'/><category term='imagens'/><category term='sockets'/><category term='ensemble'/><category term='citações'/><category term='games'/><category term='requisitos'/><category term='bancos de dados'/><category term='curioso'/><category term='TI'/><category term='pepinos e tabajarices'/><category term='paralisação'/><category term='pesquisa'/><category term='programação'/><category term='suprimentos'/><category term='soapUI'/><category term='oracle'/><category term='webservice'/><category term='segurança'/><category term='algoritmo DES'/><category term='video'/><category term='apresentação'/><category term='opinião'/><category term='livros'/><category term='alphalinc'/><category term='criptografia'/><category term='rede'/><category term='trabalho'/><category term='google'/><title type='text'>A casa caiu</title><subtitle type='html'>Coisas sobre meu trabalho, Caché, Ensemble, Java e tecnologia em geral</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3369076887752481483</id><published>2008-10-24T03:07:00.001-07:00</published><updated>2008-10-24T03:12:33.253-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='divertido'/><title type='text'>CIO</title><content type='html'>- Qual é a sua posição na empresa?&lt;br /&gt;- C.I.O.&lt;br /&gt;- Quer dizer que você fica na "posição de cio"?&lt;br /&gt;- Isso não soou legal... ¬¬&lt;br /&gt;&lt;br /&gt;/***********************************************************&lt;br /&gt;&lt;br /&gt;C.I.O - Chief Information Officer&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3369076887752481483?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3369076887752481483/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3369076887752481483&amp;isPopup=true' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3369076887752481483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3369076887752481483'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/10/cio.html' title='CIO'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3651421621580724668</id><published>2008-10-15T17:43:00.000-07:00</published><updated>2008-10-15T17:45:39.258-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bancos de dados'/><category scheme='http://www.blogger.com/atom/ns#' term='mangás'/><title type='text'>Aprender banco de dados? É com mangás!</title><content type='html'>Ah, se já tivesse isso nos meus tempos de faculdade...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/SPaLiadlIcI/AAAAAAAAD_0/HaB9S_G56hA/s1600-h/MangaGuideDatabases.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/SPaLiadlIcI/AAAAAAAAD_0/HaB9S_G56hA/s400/MangaGuideDatabases.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5257543038336836034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Mais no &lt;a href="http://estou-sem.blogspot.com/2008/10/mangs-sobre-estatstica-e-bancos-de.html"&gt;outro blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3651421621580724668?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3651421621580724668/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3651421621580724668&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3651421621580724668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3651421621580724668'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/10/aprender-banco-de-dados-com-mangs.html' title='Aprender banco de dados? É com mangás!'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0AukCty4MP0/SPaLiadlIcI/AAAAAAAAD_0/HaB9S_G56hA/s72-c/MangaGuideDatabases.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6051636335047822402</id><published>2008-08-28T17:25:00.000-07:00</published><updated>2008-08-28T17:29:16.786-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='divertido'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Programador também é gente</title><content type='html'>Por isso, abrace o seu hoje.&lt;br /&gt;&lt;br /&gt;Claro que eu prefiro abraçar uma colega programadora. =P&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://blip.tv/play/gYwjwZJqjdEh" type="application/x-shockwave-flash" width="440" height="350" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt; &lt;br /&gt;&lt;br /&gt;Via &lt;a target="_blank" href="http://www.wtfbrasil.com/wtf/voce-ja-abracou-seu-programador-hoje/"&gt;WTFBrasil&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6051636335047822402?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6051636335047822402/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6051636335047822402&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6051636335047822402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6051636335047822402'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/08/programador-tambm-gente.html' title='Programador também é gente'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3182199419095385101</id><published>2008-06-26T14:29:00.000-07:00</published><updated>2008-06-26T14:36:39.041-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='imagens'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Javascript é power, também com imagens</title><content type='html'>Que Javascript é poderoso, todo mundo que usa os aplicativos do Google deve saber (o Gmail é um bom exemplo), afinal, praticamente todos esses novos aplicativos Web 2.0, que exibem grande interação, usam AJAX e consequentemente, Javascript.&lt;br /&gt;&lt;br /&gt;Mas e que tal aplicações menos... sérias? Já imaginou jogar no seu browser, totalmente feito em &lt;b&gt;Javascript&lt;/b&gt;, clássicos como &lt;b&gt;Wolfenstein 3D&lt;/b&gt;, &lt;b&gt;Super Mario Bros.&lt;/b&gt; ou mesmo &lt;b&gt;Super Mario Kart&lt;/b&gt;?&lt;br /&gt;&lt;br /&gt;Jacob Seidelin, que tem o blog &lt;a target="_blank" href="http://blog.nihilogic.dk/"&gt;Nihilogic&lt;/a&gt;, não só pensou nisso, mas colocou as mãos na massa. Tá certo que os jogos não estão completos, mas só pelo fato de terem sido totalmente escritos em Javascript, é um feito e tanto!&lt;br /&gt;&lt;br /&gt;Veja algumas imagens:&lt;br /&gt;&lt;br /&gt;&lt;a target="_blank" href="http://blog.nihilogic.dk/2008/05/javascript-super-mario-kart.html"&gt;Super Mario Kart em Javascript&lt;/a&gt;: &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzLKr-RkI/AAAAAAAAChI/ZXg1isjtWGo/s1600-h/mario_kart1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzLKr-RkI/AAAAAAAAChI/ZXg1isjtWGo/s400/mario_kart1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216280166598067778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzE6fPi-I/AAAAAAAAChA/jo_T6wiuLQg/s1600-h/mario_kart2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzE6fPi-I/AAAAAAAAChA/jo_T6wiuLQg/s400/mario_kart2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216280059170491362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a target="_blank" href="http://blog.nihilogic.dk/2008/04/javascript-wolfenstein-3d.html"&gt;Wolfenstein 3D, em Javascript&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzb0nL5GI/AAAAAAAAChY/WgwNfDrlqL0/s1600-h/wolf3d_1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/SGPzb0nL5GI/AAAAAAAAChY/WgwNfDrlqL0/s400/wolf3d_1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216280452730184802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/SGPzX_5djUI/AAAAAAAAChQ/_WTahGDMA08/s1600-h/wolf3d_2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/SGPzX_5djUI/AAAAAAAAChQ/_WTahGDMA08/s400/wolf3d_2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216280387040152898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a target="_blank" href="http://blog.nihilogic.dk/2008/04/super-mario-in-14kb-javascript.html"&gt;Super Mario Bros. em apenas 14 Kb, em Javascript&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/SGPyxldsdCI/AAAAAAAACgw/VzCeSqzMd0o/s1600-h/mario1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/SGPyxldsdCI/AAAAAAAACgw/VzCeSqzMd0o/s400/mario1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216279727109338146" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/SGPy4XagamI/AAAAAAAACg4/ymr4Q2ZBPVE/s1600-h/mario2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/SGPy4XagamI/AAAAAAAACg4/ymr4Q2ZBPVE/s400/mario2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5216279843596954210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Além desses jogos, o cara, que deve ser fera em &lt;b&gt;manipulação de imagens com Javascript&lt;/b&gt;, tem muitos outros projetos em seu blog. Como por exemplo, um pequeno editor de imagens: &lt;a target="_blank" href="http://blog.nihilogic.dk/2008/06/pixastic-photo-editing-with-javascript.html"&gt;Pixastic : Photo editing with JavaScript and canvas&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Por causa das diferenças entre browsers, em especial o suporte ao canvas, alguns projetos do cara podem não rodar muito bem no Internet Explorer. Se bem que, com o Firefox 3, quem é que precisa do IE? =)&lt;br /&gt;&lt;br /&gt;Post originalmente feito para o &lt;a target="_blank" href="http://estou-sem.blogspot.com/2008/06/javascript-power.html"&gt;meu blog pessoal&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3182199419095385101?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3182199419095385101/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3182199419095385101&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3182199419095385101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3182199419095385101'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/06/javascript-power-tambm-com-imagens.html' title='Javascript é power, também com imagens'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_0AukCty4MP0/SGPzLKr-RkI/AAAAAAAAChI/ZXg1isjtWGo/s72-c/mario_kart1.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-2069314607501016003</id><published>2008-05-16T07:58:00.000-07:00</published><updated>2008-05-16T09:53:57.331-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Hackeando o Caché - parte 2</title><content type='html'>No &lt;a href="http://a-casa-caiu.blogspot.com/2008/05/hackeando-o-cach.html"&gt;post anterior&lt;/a&gt; eu alertei sobre um bug em como o &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt; lida com requisições &lt;a href="http://pt.wikipedia.org/wiki/HTTP"&gt;HTTP&lt;/a&gt; para as suas páginas &lt;a href="http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=GCSP_intro"&gt;CSP (Caché Server Pages)&lt;/a&gt;, bug este que pode ser explorado em um ataque de &lt;a href="http://pt.wikipedia.org/wiki/Ataque_de_nega%C3%A7%C3%A3o_de_servi%C3%A7o"&gt;negação de Serviço&lt;/a&gt; (DoS, em inglês).&lt;br /&gt;&lt;br /&gt;Neste post, detalharei não somente o bug, mas todas as circunstâncias que levaram a descoberta deste bug, suas consequências e detalhes técnicos.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Como tudo começou&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Num dia como qualquer outro, de repente começam a me dizer que o &lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble&lt;/a&gt; (o "&lt;a href="http://en.wikipedia.org/wiki/Enterprise_service_bus"&gt;ESB&lt;/a&gt;" construído sobre o Caché) estava com problemas, que os &lt;a href="http://en.wikipedia.org/wiki/Web_services"&gt;Web Services&lt;/a&gt; estavam retornando com erro, e que a página na Internet que fazia uso deste Web Service (é uma página em PHP) estava com caracteres malucos por causa dos erros.&lt;br /&gt;&lt;br /&gt;Estranhei, não porque o Ensemble/Caché seja tão livre de bugs assim (porque o que tem de bugs e &lt;a href="http://thedailywtf.com/"&gt;WTFs&lt;/a&gt; dentro dele não é nada desprezível), mas porque eu não havia colocado nada de novo em produção, nem mexido em configuração alguma. E também tinha certeza de que mais ninguém havia alterado nada no servidor há pelo menos dois dias.&lt;br /&gt;&lt;br /&gt;Resolvi testar o Web Service usando o &lt;a href="http://www.soapui.org/"&gt;soapUI&lt;/a&gt; (versão 1.6), um programa open-source feito em Java que é uma mão na roda para se testar Web Services padrão SOAP (e do qual eu &lt;a href="http://a-casa-caiu.blogspot.com/2007/09/hoje-vou-falar-sobre-um-programa-muito.html"&gt;já até falei neste outro post&lt;/a&gt;). Tudo pareceu OK, o Web Service estava retornando sem erro, e com os dados corretos. Fui falar com a pessoa que havia me alertado, e disse que estava tudo bem.&lt;br /&gt;&lt;br /&gt;Logo mais, esta pessoa volta e me diz que ainda está ocorrendo erro. Desta vez resolvo abrir a página web que utiliza o Web Service, e realmente estava com erro. Pensei que talvez estivesse exibindo algum cache, então testei novamente com o soapUI, e mais uma vez, o resultado veio correto. WTF, pensei... Perguntei para a pessoa que havia me dito do erro, EXATAMENTE o que havia acontecido, como ela havia descoberto o erro. Então me disse que havia tentado invocar o Web Service utilizando o &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt;, e como neste retornava erro, checava depois a página web, a qual também mostrava erro.&lt;br /&gt;&lt;br /&gt;Fiquei intrigado, e como tenho o Netbeans 6 instalado aqui, resolvi fazer os mesmos passos. E não é que usando o Netbeans para testar o Web Service, dava erro mesmo? E pior, depois de usar o Netbeans, as chamadas ao Web Service, pela página web, começavam a dar erro também. Tentei então entrar no Portal de Administração do Caché/Ensemble, e até estas páginas estavam retornando erro. Nem mesmo a página de login funcionava! Só o que eu via era a página padrão de erro do CSP.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/SC2h78CV4JI/AAAAAAAACDM/V-2t5TGmdv0/s1600-h/erro_padrao_csp.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/SC2h78CV4JI/AAAAAAAACDM/V-2t5TGmdv0/s400/erro_padrao_csp.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5200991195783094418" /&gt;&lt;/a&gt;&lt;br /&gt;Pronto, era o que faltava, o Netbeans derrubava o Caché/Ensemble! =P&lt;br /&gt;&lt;br /&gt;Reiniciei o Caché/Ensemble, já que aquele ali era o servidor de produção, e pedi pra que ninguém mais acessasse ele pra fazer testes, pra não prejudicar os outros sistemas em produção, que usavam o infeliz. Fui então para o servidor de desenvolvimento e testes, a fim de descobrir o que raios estava acontecendo.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Fazendo trabalho de detetive&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A primeira dica para a resolução do caso foi que no Netbeans ocorria erro, mas no soapUI não. Nos testes, mesmo depois de "derrubar" o Caché/Ensemble com o Netbeans, acessando via soapUI não ocorria erro. Resolvi investigar bem a fundo, e coloquei o &lt;a href="http://www.ethereal.com/"&gt;Ethereal&lt;/a&gt; pra rodar, um bom programa &lt;a href="http://en.wikipedia.org/wiki/Packet_sniffer"&gt;sniffer&lt;/a&gt;, open-source, pra analisar todo o tráfego que chegava no Caché/Ensemble, no nível de stream &lt;a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol"&gt;TCP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Como a página de erro (na figura acima) mostrava um erro relativo ao &lt;a href="http://en.wikipedia.org/wiki/Character_encoding"&gt;CharSet&lt;/a&gt;, fui verificar como o soapUI e o Netbeans enviavam as suas requisições. O CharSet é enviado junto com a requisição HTTP, fazendo parte dos &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_headers"&gt;cabeçalhos (Headers) HTTP&lt;/a&gt;, e serve para identificar qual o conjunto de caracteres que está sendo usado para enviar dados.&lt;br /&gt;&lt;br /&gt;Abaixo uma requisição que não gerava erro, vinda do soapUI:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;POST /csp/ensemble/pacote.Classe.cls HTTP/1.1&lt;br /&gt;Content-Type: text/xml;charset=UTF-8&lt;br /&gt;SOAPAction: "http://namespace/pacote.Classe.Metodo"&lt;br /&gt;User-Agent: Jakarta Commons-HttpClient/3.0.1&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;E uma requisição que gerava erro, vinda do Netbeans 6.0:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;POST /csp/ensemble/pacote.Classe.cls HTTP/1.0&lt;br /&gt;SOAPAction: "http://namespace/pacote.Classe.Metodo"&lt;br /&gt;Content-Type: text/xml;charset="utf-8"&lt;br /&gt;User-Agent: JAX-WS RI 2.1.2-b05-RC1&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Modifiquei as informações referentes às classes reais e endereços, por questões de privacidade; também retirei o corpo xml pelo mesmo motivo.)&lt;br /&gt;&lt;br /&gt;Aparentemente, as duas chamadas são bem parecidas, apesar do Netbeans enviar alguns cabeçalhos HTTP a mais (que eu retirei do exemplo acima, pra não ficar poluído demais), mas que nada influem. A versão do HTTP neste caso, também não influenciava no problema.&lt;br /&gt;&lt;br /&gt;Analisando o Content-Type, a primeira vista não parece que haja uma grande diferença entre eles. O fato do conteúdo do CharSet ser utf-8 ou UTF-8 não influi. Entretanto, na requisição gerada pelo Netbeans, o valor do CharSet é enviado entre aspas. E isso fez TODA A DIFERENÇA.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&amp;lt;?xml version='1.0' encoding='UTF-8' standalone='no' ?&amp;gt;&lt;br /&gt;&amp;lt;SOAP-ENV:Envelope&amp;gt;&lt;br /&gt;  &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br /&gt;   &amp;lt;SOAP-ENV:Fault&amp;gt;&lt;br /&gt;    &amp;lt;faultcode&amp;gt;SOAP-ENV:Server&amp;lt;/faultcode&amp;gt;&lt;br /&gt;    &amp;lt;faultstring&amp;gt;Internal Server Error&amp;lt;/faultstring&amp;gt;&lt;br /&gt;    &amp;lt;detail&amp;gt;&lt;br /&gt;      &amp;lt;error xmlns='http://tempuri.org' &amp;gt;&lt;br /&gt;        &amp;lt;text&amp;gt;ERROR #5911: Character Set "utf-8" not installed, unable to perform character set translation&amp;lt;/text&amp;gt;&lt;br /&gt;      &amp;lt;/error&amp;gt;&lt;br /&gt;    &amp;lt;/detail&amp;gt;&lt;br /&gt;   &amp;lt;/SOAP-ENV:Fault&amp;gt;&lt;br /&gt;  &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br /&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Se repararmos na tela de erro, ou na mensagem SOAP-Fault acima, veremos que a mensagem é &lt;i&gt;Character Set '"utf-8"' not installed...&lt;/i&gt;. Ou seja, ele considerava o CharSet com ASPAS!&lt;br /&gt;&lt;br /&gt;Apesar de ser desejável o servidor aceitar o CharSet entre aspas normalmente, retirando as aspas para "entender" qual o CharSet usado, não encontrei nada que diga que isso seja uma obrigação ou mesmo uma recomendação da &lt;a href="http://www.w3.org/Protocols/Specs.html"&gt;especificação do HTTP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;O erro propagado&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;O erro ocorrer na resposta da requisição "defeituosa" é o procedimento esperado. Entretanto, depois de ter chamado o Web Service e ter recebido o erro, depois de alguns momentos, ao acessar o portal de Administração do Caché/Ensemble, este também retorna erro, e logo tudo que depende de CSPs é inutilizado, pois para qualquer requisição via browser a página de erro é mostrada. Tipicamente, os browsers não enviam o cabeçalho Content-Type, o que torna a mensagem de erro bem peculiar.&lt;br /&gt;&lt;br /&gt;Fiz um pequeno programa em Java, para poder manipular livremente todos os cabeçalhos HTTP e enviar ao servidor. Modificando o valor de CharSet para qualquer valor, este apareceria na tela, junto com a mensagem de erro.&lt;br /&gt;&lt;br /&gt;Além disso, comecei a testar fazendo não requisições SOAP, usando o método POST do HTTP, mas usando o método GET, que é o método usado geralmente pelos navegadores para pegar páginas Web. E não para minha surpresa, colocando-se um endereço de página CSP válido, e usando o cabeçalho com o CharSet alterado, o erro também acontecia.&lt;br /&gt;&lt;br /&gt;Por exemplo, enviando a requisição HTTP abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;GET /csp/ensemble/pacote.Classe.cls HTTP/1.0&lt;br /&gt;Content-Type: text/xml;charset=Uma Mensagem Qualquer Aqui&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Depois de alguns instantes, qualquer chamada a qualquer página CSP retornaria a seguinte tela de erro:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/SC28DMCV4LI/AAAAAAAACDc/0RaXbtmLFy8/s1600-h/erro_csp_mensagem_qquer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/SC28DMCV4LI/AAAAAAAACDc/0RaXbtmLFy8/s400/erro_csp_mensagem_qquer.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5201019907639468210" /&gt;&lt;/a&gt;&lt;br /&gt;Aparentemente, o Caché mantém algumas estruturas/objetos que ele reutiliza entre as chamadas, o que causa a propagação do erro. Entretanto, se o servidor for altamente requisitado, no início o Caché já mantém vários objetos instanciados, e a chamada defeituosa vai afetar apenas aquele objeto que for usado na chamada, deixando os outros normais. Por isso, num servidor muito acessado, que mantém vários objetos instanciados, o erro fica intermitente entre as requisições HTTP posteriores, ora retornando com problema (porque usou nesta chamada o objeto com erro), ora retornando OK (porque usou outro objeto já instanciado, que não fora afetado).&lt;br /&gt;&lt;br /&gt;Pude constatar isso ao fazer o 'ataque' na página de documentação do Caché 2007, no site da Intersystems. Ali, depois de fazer uma requisição HTTP defeituosa com o programinha que desenvolvi, algumas requisições via browser retornavam erro, enquanto outras retornavam OK, independente do endereço requisitado.&lt;br /&gt;&lt;br /&gt;O bug provavelmente se encontra no objeto que representa uma requisição CSP, o &lt;a href="http://docs.intersystems.com/cache20071/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25CSP.Request"&gt;%CSP.Request&lt;/a&gt;. Notem que este objeto é reutilizado, como podemos ver pela existência do método Reset, onde provavelmente reside o erro.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Explorando o bug&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Alguém mal intencionado pode explorar o bug, realizando um ataque de negação de serviço em um site que use CSP. Para tal, nem é preciso realizar um imenso número de requisições, basta umas poucas requisições de tempos em tempos. Se o site tiver pouco movimento, uma ou duas requisições a cada 10 minutos seria suficiente para torná-lo inoperável.&lt;br /&gt;&lt;br /&gt;Durante os testes, fiz uma pequena classe em Java para facilitar os testes, abrindo um Socket e escrevendo direto na stream TCP, ou seja, enviando os comandos e cabeçalhos HTTP como eu quisesse. Este programa acaba sendo uma &lt;a href="http://en.wikipedia.org/wiki/Proof_of_Concept#In_security"&gt;Prova de Conceito&lt;/a&gt; ou do inglês, Proof of Concept.&lt;br /&gt;&lt;br /&gt;Abaixo, listo a classe, que é bem simples (e com comentários dentro do código):&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;div align="left" class="java"&gt;&lt;table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff"&gt;   &lt;tr&gt;   &lt;td nowrap="nowrap" valign="top" align="left"&gt;&lt;br /&gt;    &lt;code&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;package&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;testes;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;java.io.*;&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;import&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;java.net.*;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;&lt;/font&gt;&lt;font color="#7f9fbf"&gt;@author&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;Emilio,&amp;nbsp;o&amp;nbsp;r&amp;aacute;qui.&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;class&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Main&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;/**&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*&amp;nbsp;Uso:&amp;nbsp;java&amp;nbsp;testes.Main&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f5fbf"&gt;*/&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;public&amp;nbsp;static&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;main&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;String&lt;/font&gt;&lt;font color="#000000"&gt;[]&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;args&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;throws&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Exception&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;try&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Cria&amp;ccedil;ão&amp;nbsp;e&amp;nbsp;abertura&amp;nbsp;de&amp;nbsp;um&amp;nbsp;Socket.&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//O&amp;nbsp;primeiro&amp;nbsp;par&amp;acirc;metro&amp;nbsp;&amp;eacute;&amp;nbsp;um&amp;nbsp;endere&amp;ccedil;o&amp;nbsp;ou&amp;nbsp;IP,&amp;nbsp;no&amp;nbsp;exemplo,&amp;nbsp;o&amp;nbsp;host&amp;nbsp;da&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Intersystems&amp;nbsp;que&amp;nbsp;cont&amp;eacute;m&amp;nbsp;a&amp;nbsp;documenta&amp;ccedil;ão&amp;nbsp;do&amp;nbsp;Cach&amp;eacute;&amp;nbsp;em&amp;nbsp;CSP.&amp;nbsp;Pode&amp;nbsp;ser&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//alterado&amp;nbsp;para&amp;nbsp;qualquer&amp;nbsp;endere&amp;ccedil;o.&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//O&amp;nbsp;segundo&amp;nbsp;par&amp;acirc;metro&amp;nbsp;&amp;eacute;&amp;nbsp;a&amp;nbsp;porta&amp;nbsp;TCP,&amp;nbsp;como&amp;nbsp;estamos&amp;nbsp;lidando&amp;nbsp;com&amp;nbsp;HTTP,&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//o&amp;nbsp;padrão&amp;nbsp;&amp;eacute;&amp;nbsp;a&amp;nbsp;porta&amp;nbsp;80.&amp;nbsp;A&amp;nbsp;não&amp;nbsp;ser&amp;nbsp;que&amp;nbsp;o&amp;nbsp;site&amp;nbsp;use&amp;nbsp;outra&amp;nbsp;porta&amp;nbsp;não-&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//padrão,&amp;nbsp;esse&amp;nbsp;par&amp;acirc;metro&amp;nbsp;não&amp;nbsp;precisa&amp;nbsp;ser&amp;nbsp;alterado.&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;Socket&amp;nbsp;s&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Socket&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;docs.intersystems.com&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;,&amp;nbsp;&lt;/font&gt;&lt;font color="#990000"&gt;80&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Monta&amp;nbsp;uma&amp;nbsp;String&amp;nbsp;com&amp;nbsp;o&amp;nbsp;comando&amp;nbsp;e&amp;nbsp;os&amp;nbsp;cabe&amp;ccedil;alhos&amp;nbsp;HTTP&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Primeiro,&amp;nbsp;colocamos&amp;nbsp;o&amp;nbsp;comando&amp;nbsp;GET,&amp;nbsp;apontando&amp;nbsp;para&amp;nbsp;uma&amp;nbsp;p&amp;aacute;gina&amp;nbsp;CSP&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//v&amp;aacute;lida,&amp;nbsp;no&amp;nbsp;caso,&amp;nbsp;a&amp;nbsp;p&amp;aacute;gina&amp;nbsp;gerada&amp;nbsp;com&amp;nbsp;a&amp;nbsp;documenta&amp;ccedil;ão&amp;nbsp;do&amp;nbsp;Cach&amp;eacute;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;String&amp;nbsp;cabecalho&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;GET&amp;nbsp;/cache20071/csp/docbook/DocBook.UI.Page.cls&amp;nbsp;HTTP/1.0&amp;nbsp;\r\n&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;+&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Este&amp;nbsp;cabe&amp;ccedil;alho,&amp;nbsp;Content-Type,&amp;nbsp;que&amp;nbsp;pode&amp;nbsp;ser&amp;nbsp;alterado&amp;nbsp;para&amp;nbsp;causar&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//o&amp;nbsp;bug.&amp;nbsp;Basta&amp;nbsp;alterar&amp;nbsp;o&amp;nbsp;charset&amp;nbsp;para&amp;nbsp;um&amp;nbsp;valor&amp;nbsp;inv&amp;aacute;lido&amp;nbsp;(ou&amp;nbsp;uma&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Content-Type:&amp;nbsp;text/xml;charset=Uma&amp;nbsp;Mensagem&amp;nbsp;Qualquer&amp;nbsp;Aqui\r\n&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;+&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//outros&amp;nbsp;cabe&amp;ccedil;alhos&amp;nbsp;HTTP&amp;nbsp;podem&amp;nbsp;ser&amp;nbsp;colocados.&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Connection:&amp;nbsp;keep-alive&amp;nbsp;\r\n&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;+&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;\r\n&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//Cria&amp;nbsp;e&amp;nbsp;abre&amp;nbsp;objetos&amp;nbsp;para&amp;nbsp;escrever&amp;nbsp;e&amp;nbsp;ler&amp;nbsp;na&amp;nbsp;stream&amp;nbsp;de&amp;nbsp;dados&amp;nbsp;TCP&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;DataOutputStream&amp;nbsp;dos&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;DataOutputStream&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;s.getOutputStream&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;DataInputStream&amp;nbsp;dis&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;DataInputStream&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;s.getInputStream&lt;/font&gt;&lt;font color="#000000"&gt;())&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//envia&amp;nbsp;a&amp;nbsp;requisi&amp;ccedil;ão&amp;nbsp;previamente&amp;nbsp;montada&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;dos.writeBytes&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;cabecalho&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;System.out.println&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Enviado&amp;#34;&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#3f7f5f"&gt;//C&amp;oacute;digo&amp;nbsp;para&amp;nbsp;ver&amp;nbsp;na&amp;nbsp;sa&amp;iacute;da&amp;nbsp;padrão&amp;nbsp;o&amp;nbsp;que&amp;nbsp;foi&amp;nbsp;retornado&amp;nbsp;pelo&amp;nbsp;servidor.&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;byte&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;[]&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;buff&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;byte&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;font color="#990000"&gt;32000&lt;/font&gt;&lt;font color="#000000"&gt;]&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;dis.read&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;buff&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;System.out.println&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#2a00ff"&gt;&amp;#34;Recebido:\n&amp;#34;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;+&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;String&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;buff&lt;/font&gt;&lt;font color="#000000"&gt;))&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;buff&amp;nbsp;=&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;byte&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;font color="#990000"&gt;32000&lt;/font&gt;&lt;font color="#000000"&gt;]&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;dis.read&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;buff&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;System.out.println&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new&amp;nbsp;&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;String&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;buff&lt;/font&gt;&lt;font color="#000000"&gt;))&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#000000"&gt;Exception&amp;nbsp;e&lt;/font&gt;&lt;font color="#000000"&gt;)&amp;nbsp;{&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;e.printStackTrace&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;/font&gt;&lt;font color="#000000"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;br /&gt;&lt;font color="#ffffff"&gt;&lt;/font&gt;&lt;font color="#ffffff"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/code&gt;&lt;/table&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Providências&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Se você roda aplicações CSP, especialmente sites na Internet, e que rodem em versões do Caché afetadas (anteriores a 2008), é altamente aconselhável que procurem a Intersystems para obter um patch.&lt;br /&gt;&lt;br /&gt;Como aqui na empresa este patch já está instalado, e aparentemente o erro foi corrigido, o processo de obtenção do patch deve ser razoavelmente rápido (ao contrário da maioria das requisições de suporte que tivemos até agora), já que ele já foi feito.&lt;br /&gt;&lt;br /&gt;Agora, se você preferir dar uma de 'hacker', pode fuçar e mexer no %CSP.Request. Claro que para isso, você deve tirar a base de dados CACHELIB do modo somente leitura, que é o padrão. Nesta classe, no método CSPGatewayReset (que é um método gerador de código), você pode incluir comandos para "zerar" o CharSet. Em alguns testes, essa solução também funcionou, mas como não me aprofundei mais no assunto, não aconselho a fazerem isso em um ambiente de produção.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-2069314607501016003?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/2069314607501016003/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=2069314607501016003&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/2069314607501016003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/2069314607501016003'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/05/hackeando-o-cach-parte-2.html' title='Hackeando o Caché - parte 2'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_0AukCty4MP0/SC2h78CV4JI/AAAAAAAACDM/V-2t5TGmdv0/s72-c/erro_padrao_csp.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-8372423821489291744</id><published>2008-05-05T13:59:00.000-07:00</published><updated>2008-05-05T14:03:19.406-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><category scheme='http://www.blogger.com/atom/ns#' term='segurança'/><title type='text'>Hackeando o Caché</title><content type='html'>Bem, o título chamativo acima não é verdadeiro, pois não se trata de um hack no &lt;a href="http://pt.wikipedia.org/wiki/Hacker#A_controv.C3.A9rsia_sobre_o_termo"&gt;sentido original da palavra&lt;/a&gt;, nem no sentido de invasão de sistemas. Se trata mais de um ataque (isso sim) de &lt;a href="http://pt.wikipedia.org/wiki/Ataque_de_nega%C3%A7%C3%A3o_de_servi%C3%A7o"&gt;Negação de Serviço&lt;/a&gt;, ou como é conhecido em inglês, DoS (Denial of Service), que pode comprometer sistemas desenvolvidos usando a tecnologia &lt;a href="http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=GCSP_intro"&gt;CSP&lt;/a&gt; (Caché Server Pages) do &lt;a href="http://www.intersystems.com/cache/"&gt;Caché da Intersystems&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O bug que torna possível o ataque afeta as versões anteriores a versão 2008 - nos meus testes pessoais, com máquinas que eu tinha controle, testei no Caché 5.0 e 5.2. No próprio site da Intersystems, a documentação online (que é gerada em CSP) da &lt;a href="http://docs.intersystems.com/cache20071/csp/docbook/DocBook.UI.Page.cls"&gt;versão 2007&lt;/a&gt; também é afetada por este bug.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Como pode acontecer o ataque?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Um bug faz com que, depois de uma requisição HTTP a um endereço legítimo que use CSP (e isso inclui chamadas a &lt;a href="http://pt.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt; do Caché), as páginas CSP chamadas depois, gradualmente comecem a retornar erro. Este erro persiste por algum tempo, até que depois de alguns minutos, que nos meus testes pareceu aleatório (mas que ficou em torno de 30 minutos), as páginas CSP retornam à normalidade.&lt;br /&gt;&lt;br /&gt;Um hacker 'do mal' pode aproveitar este bug para tornar um site construído em CSP inoperável, simplesmente, fazendo com que de tempos em tempos, uma requisição HTTP especialmente preparada, seja enviada. Ou seja, você pode causar um ataque de Negação de Serviço (DoS) enviando uns poucos pacotes a um servidor, de tempos em tempos.&lt;br /&gt;&lt;br /&gt;Este bug já foi reportado a &lt;a href="http://www.intersystems.com/"&gt;Intersystems&lt;/a&gt;, por meio da parceira regional, e apesar de não haver encontrado nenhuma menção a este bug (nem na documentação nem na web, via google), parece que o pessoal já sabia dele, pois a versão 2008 do Caché aparentemente não apresenta este problema.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Que providências tomar?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Se você identificar que seu sistema pode ser afetado, você tem duas alternativas: ou migrar para a versão 2008, ou solicitar um "patch" para a Intersystems, para a sua versão de Caché.&lt;br /&gt;&lt;br /&gt;Apesar de eu ser um entusiasta dos upgrades, nem tudo são flores: uma migração de versão, especialmente se for uma versão mais antiga, pode se tornar muito trabalhosa, inserir novos bugs, quebrar funcionalidades, etc... Se for este o caso, sugiro que peça emergencialmente um patch para a sua versão do Caché.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Detalhes Técnicos&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Por enquanto, como ainda não obtive resposta da Intersytems, não vou liberar todos os detalhes técnicos do bug aqui no blog, nem o código que eu usei pra explorar o bug (a  chamada &lt;a href="http://en.wikipedia.org/wiki/Proof_of_Concept"&gt;prova de conceito&lt;/a&gt;). Esperarei mais algum tempo, e se o suporte (que conosco, não tem sido dos melhores) não responder satisfatoriamente, divulgarei assim mesmo o código.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-8372423821489291744?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/8372423821489291744/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=8372423821489291744&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8372423821489291744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8372423821489291744'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/05/hackeando-o-cach.html' title='Hackeando o Caché'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-8992835472707688423</id><published>2008-04-25T11:19:00.000-07:00</published><updated>2008-04-25T12:15:15.327-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Sincronizando Business Objects e Business Processes no Ensemble</title><content type='html'>O cenário: temos algumas informações que devem ser replicadas em diferentes bases de dados. Esta escolha de se replicar os dados, se deve a diversos fatores, que não convém mencionar aqui.&lt;br /&gt;&lt;br /&gt;No &lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble da Intersystems&lt;/a&gt;, temos um serviço de atualização de dados em duas bases de dados distintas, inclusive com estruturas diferentes. A primeira das bases de dados, em Oracle, é acessada diretamente via ODBC, pelo Ensemble. A segunda, também em Oracle, não permite o acesso direto (pois como é usada por um software de terceiros, perderia-se a garantia de performance caso o acesso fosse liberado). Para tanto, a empresa que desenvolveu este software criou uma camada utilizando &lt;a href="http://pt.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt; (WS) padrão &lt;a href="http://pt.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt;, para a atualização dos dados.&lt;br /&gt;&lt;br /&gt;Além de ter uma estrutura diferente, a segunda base de dados possui algumas restrições (constraints), o que faz com que alguns dados possam ser válidos na primeira base, mas não na segunda. Essas restrições se devem a interações que alguns dados possuem dentro do segundo banco, especialmente em se tratando da codificação das entidades dentro dele (isto é, do formato/geração das chaves). Isto ocasiona que para alguns dados, a segunda base rejeita os dados, mas a primeira base os aceita.&lt;br /&gt;&lt;br /&gt;Pois então, com estes requisitos em mente, construímos um Business Process (BP) no Ensemble, mostrado na figura abaixo simplificadamente (exclui alguns passos do processo que são irrelevantes para o entendimento deste post):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/SBIjhbDM6MI/AAAAAAAAB5I/tUJdfavxu-g/s1600-h/bp_simples.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_0AukCty4MP0/SBIjhbDM6MI/AAAAAAAAB5I/tUJdfavxu-g/s400/bp_simples.PNG" alt="" id="BLOGGER_PHOTO_ID_5193252377415444674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notem que a primeira chamada é para um Business Object (BO) que lida com a chamada para o WS. O Studio, a IDE integrada do &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble&lt;/a&gt; tem um wizard para a criação de toda a estrutura de invocação de um Web Service SOAP, bastando ter o &lt;a href="http://pt.wikipedia.org/wiki/Web_Services_Description_Language"&gt;WSDL&lt;/a&gt; correspondente. Além de montar as classes de dados e a classe cliente do Web Service, no Ensemble você pode gerar já a estrutura de BO e mensagens de Request/Response.&lt;br /&gt;&lt;br /&gt;O Web Service retorna como resposta uma String. Se a atualização se deu sem erros, é retornado "OK". Caso contrário, é retornado uma breve descrição do erro. Bem, o segundo elemento do BP é justamente uma checagem para ver se aconteceu algum erro. Se aconteceu algum erro, retorna imediatamente. Caso contrário, faz a chamada para dois BOs que cuidarão da atualização na primeira base, via ODBC. Note como as estruturas são diferentes: uma única estrutura de dados da segunda base (atualizada via WS) equivale a duas estruturas na primeira base (atualizada via SQL-ODBC).&lt;br /&gt;&lt;br /&gt;Rodando diversos testes, com usuários inclusive, surgiu um problema. De vez em quando, mais frequentemente do que eu gostaria, por alguma razão, o Adapter SQL perde a conexão e/ou sessão com o Oracle, gerando exceções. Falarei mais sobre isso em um outro post, mas fica registrado que esses problemas podem ser tão graves, que necessitam até de shutdown de todo o Caché, para o Caché/Ensemble se recuperar do erro.&lt;br /&gt;&lt;br /&gt;Acontecendo isso, você, astuto leitor, deve ter percebido que o processo no BP tem um grave problema: ele pode atualizar a segunda base via WS, e não atualizar a primeira, causando inconsistências (lembrando que o WS é simples, não tem nada de &lt;a href="http://en.wikipedia.org/wiki/WS-Transaction"&gt;WS-Transactions&lt;/a&gt;, por exemplo). A solução é colocar a chamada do Web Service dentro do contexto da transação da primeira base, e se o WS falhar, executar um rollback nos SQLs já executados. Mas... como fazer isso?&lt;br /&gt;&lt;br /&gt;Uma solução é jogar todo o código dentro de um mesmo BO (que já iria ficar enorme, já que pra colocar tudo numa mesma transação, as duas BOs que usam ODBC-SQL se tornariam uma só). Então, pra evitar mais código-macarrão dentro de um único BO, resolvi aproveitar a estrutura do BO que faz a chamada do Web Service, e manter Business Objects separados para atualizar via WS e via ODBC.&lt;br /&gt;&lt;br /&gt;Então, eu deveria: executar as atualizações no banco via SQL, mas não dar Commit; chamar o Web Service, e caso de sucesso na atualização do segundo banco, executar o Commit, senão dar um Rollback.&lt;br /&gt;&lt;br /&gt;Como fazer isso, usando dois BOs separados, sendo que ao terminar a execução de uma chamada, o BO com o Adapter SQL pode não necessariamente manter a sessão (pode ser até outra instância do BO a ser invocado)? A solução é deixar tudo dentro de uma única chamada do BO. Então, surge a necessidade de comunicar/sincronizar o BO com o BP, sem terminar a execução do BO. Para isso, decidi fazer uso de globais.&lt;br /&gt;&lt;br /&gt;Simplificadamente, a solução adotada foi:&lt;br /&gt;&lt;br /&gt;- No BP, fazer um "fork", ou seja, abrir dois caminhos de execução paralelos.&lt;br /&gt;- No primeiro caminho, colocar o BO com o Adaptador SQL.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Neste BO, setar controle de Commit como manual.&lt;br /&gt;&lt;li&gt;Executar os comandos SQL.&lt;br /&gt;&lt;li&gt;Se ocorrer algum erro, pode sair do BP e retornar o erro.&lt;br /&gt;&lt;li&gt;Se não ocorreu erro, sinaliza usando a global, e espera pelo sinal de retorno do WS (também sinalizado via global).&lt;br /&gt;&lt;li&gt;Se o WS retornou "OK", executa o Commit.&lt;/ul&gt;&lt;br /&gt;- No segundo caminho:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Coloca um código de espera, até o BO com o Adaptador SQL sinalizar.&lt;br /&gt;&lt;li&gt;Fazer a chamada do BO que invoca o Web Service.&lt;br /&gt;&lt;li&gt;Sinaliza para o BO com o SQL Adapter, o resultado da invocação do WS.&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Todas as sinalizações foram feitas usando uma global. Como podemos ter mais de uma instância, usamos como controle uma chave de sessão simples, para acessar a global, e evitar conflitos.&lt;br /&gt;&lt;br /&gt;Toda esta mega-gambiarra pode ser vista no BP abaixo:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/SBIkoLDM6NI/AAAAAAAAB5Q/i-aJebNwFiU/s1600-h/bp_gambi.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/SBIkoLDM6NI/AAAAAAAAB5Q/i-aJebNwFiU/s400/bp_gambi.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5193253592891189458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A primeira parte do código responsável pela sincronização é mostrada abaixo. Nele, que está na BP como "Seta chave sessão para global", configuramos uma chave que identificará a "sessão", usando um timestamp ($h ou $horolog, que retorna o dia/hora atual), mais um número aleatório. Usando esta chave, acessamos uma global que será a área de dados compartilhados entre a BO e a BP.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;br /&gt; set context.chaveGlobal = $h _ $random($piece($h,",",1))&lt;br /&gt; set ^globalSync(context.chaveGlobal) = 0&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ainda na BP, colocamos na parte de código "Espera por Oracle", o código abaixo, que é basicamente um loop, que de tempos em tempos, checa se o valor na global mudou. Note que o comando HANG faz com que a execução do código seja interrompida por algum tempo, mais especificamente o tempo passado como parâmetro do comando, em segundos. No código abaixo, 200 ms, ou seja, o código checa se houve mudança na variável global de 200 em 200 milisegundos.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;br /&gt; while (^globalSync(context.chaveGlobal) &lt; 1) {&lt;br /&gt;     hang 0.2&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dentro da BO, depois de realizar os comandos SQL, mas antes de efetuar o COMMIT, usa-se o código abaixo. Nele, a variável global muda de valor, sinalizando para o código na BP que ela pode continuar a execução. Além disso, também temos um loop de espera, pois o COMMIT só pode ser realizado depois que o Web Service retornar. Note que enquanto no código da BP a chave global está dentro de &lt;i&gt;context&lt;/i&gt;, na BO ela está dentro da mensagem &lt;i&gt;pRequest&lt;/i&gt; enviada à BO.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;br /&gt; set ^globalSync(pRequest.chaveGlobal) = 1&lt;br /&gt; &lt;br /&gt; while (^globalSync(pRequest.chaveGlobal) = 1) {&lt;br /&gt;     hang .2&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voltando a BP, depois que a BO que invoca o Web Service retorna, verificamos se este retornou OK ou se aconteceu algum erro. Em ambos os casos, sinalizamos o resultado na variável global, como mostra o código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;br /&gt; if (context.statusWS.StringValue = "OK") {&lt;br /&gt;     set ^globalSync(context.chaveGlobal) = 2&lt;br /&gt; }&lt;br /&gt; else {&lt;br /&gt;     set ^globalSync(context.chaveGlobal) = 3&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Por fim, nos últimos passos da BO, depois de passar pelo loop de espera, temos certeza de que o Web Service retornou (ou ocorreu um erro de timeout, por exemplo). Só resta então checar o status na variável global, e realizar o COMMIT ou ROLLBACK, como mostra (simplificadamente) o código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;&lt;br /&gt; if (^globalSync(pRequest.chaveGlobal) = 2) { &lt;br /&gt;     set st = ..Adapter.Commit()&lt;br /&gt; }    &lt;br /&gt; else {&lt;br /&gt;     do ..Adapter.Rollback() &lt;br /&gt; } &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-8992835472707688423?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/8992835472707688423/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=8992835472707688423&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8992835472707688423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8992835472707688423'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/04/sincronizando-business-objects-e.html' title='Sincronizando Business Objects e Business Processes no Ensemble'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/SBIjhbDM6MI/AAAAAAAAB5I/tUJdfavxu-g/s72-c/bp_simples.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-9200445398625918225</id><published>2008-03-25T09:28:00.000-07:00</published><updated>2008-03-25T09:29:30.140-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='carreira'/><title type='text'>Um dos segredos do Google: Cerveja, churrascos e muitos sushis - tudo de graça!</title><content type='html'>O ex-chef no Google, Charlie Ayes, fora contratado pelo Google antes da companhia se tornar se tornar o monstro que é hoje. &lt;br /&gt;&lt;br /&gt;No seu livro, &lt;i&gt;In Eat Yourself Smart&lt;/i&gt;, o chef relata as suas experiências ao ser contratado pelos dois fundadores do Google, Sergey Brin e Larry Page, e como a política do Google de recursos humanos, passando pela comida, tornou a empresa o que ela é. &lt;br /&gt;&lt;br /&gt;Para atrair as mentes brilhantes que são o insumo da empresa, comida e bebida grátis (sempre!), e de qualidade. Inclusive cerveja e churrasco, yeah!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/R-knVecyAAI/AAAAAAAABSc/cq0FV-sLVZI/s1600-h/wine_news_sashimi.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/R-knVecyAAI/AAAAAAAABSc/cq0FV-sLVZI/s400/wine_news_sashimi.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5181716096170983426" /&gt;&lt;/a&gt;&lt;br /&gt;O chef ainda diz que um dos motores do crescimento do google foram as altas doses de sushi (!!), pois a gordura presente no peixe ajudaria as células do cérebro.&lt;br /&gt;&lt;br /&gt;A matéria completa, do &lt;a href="http://www.smh.com.au/news/technology/googles-free-beer-and-bigass-barbies/2008/03/23/1206206979578.html"&gt;The Sunday Morning Herald&lt;/a&gt; (em inglês, claro), você encontra aí no link.&lt;br /&gt;&lt;br /&gt;Via &lt;a href="In Eat Yourself Smart"&gt;TechCrunch&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Não dá uma inveja do povo que trabalha lá?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-9200445398625918225?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/9200445398625918225/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=9200445398625918225&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9200445398625918225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9200445398625918225'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/03/um-dos-segredos-do-google-cerveja.html' title='Um dos segredos do Google: Cerveja, churrascos e muitos sushis - tudo de graça!'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0AukCty4MP0/R-knVecyAAI/AAAAAAAABSc/cq0FV-sLVZI/s72-c/wine_news_sashimi.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1392252003005953956</id><published>2008-03-05T04:00:00.000-08:00</published><updated>2008-03-05T04:35:33.613-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Coisas esquecidas pelo caminho</title><content type='html'>Tentando descobrir uma solução para alguns problemas no &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble&lt;/a&gt; da Intersystems, me deparo com o seguinte pedaço de código:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;i ..sqlcode'=-0 q&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Para os não-iniciados em Caché Object Script (a linguagem do Caché):&lt;br /&gt;&lt;br /&gt;&lt;b&gt;i&lt;/b&gt; - abreviação do comando &lt;b&gt;if&lt;/b&gt;!!! Oh yeah baby, em Caché ou você escreve &lt;i&gt;if&lt;/i&gt; ou abrevia para um singelo &lt;i&gt;i&lt;/i&gt;. Só isso já mereceria um WTF pra ele.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;..&lt;/b&gt; - indica que o elemento a seguir pertence a classe. Em Java seria &lt;i&gt;this&lt;/i&gt;, em Pascal, &lt;i&gt;self&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;sqlcode&lt;/b&gt; - apenas o identificador de uma variável local&lt;br /&gt;&lt;br /&gt;&lt;b&gt;'=&lt;/b&gt; - operador de diferença. Em Java seria &lt;i&gt;!=&lt;/i&gt;, em Pascal, &lt;i&gt;&lt;&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;q&lt;/b&gt; - abreviação do comando &lt;b&gt;quit&lt;/b&gt;. O comando &lt;i&gt;quit&lt;/i&gt;, ou &lt;i&gt;q&lt;/i&gt;, como queiram, serve para: sair de um loop ou sair de um método. Em Java seria um &lt;i&gt;break&lt;/i&gt; ou um &lt;i&gt;return&lt;/i&gt;, respectivamente.&lt;br /&gt;&lt;br /&gt;Agora o que não tem explicação é o "-0".&lt;br /&gt;&lt;br /&gt;Por que alguém compara alguma coisa com menos zero, e não com zero? Tá certo que o Caché não é muito fã de matemática (vide a &lt;a href="http://a-casa-caiu.blogspot.com/2007/06/operadores.html"&gt;precedência de operadores&lt;/a&gt;), mas ele sabe que menos zero e zero são a mesma coisa. Ou será que não, para nossos intrépidos colegas da &lt;a href="http://www.intersystems.com/"&gt;Intersystems&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Eu acho que alguém acabou esquecendo o sinal lá...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1392252003005953956?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1392252003005953956/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1392252003005953956&amp;isPopup=true' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1392252003005953956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1392252003005953956'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/03/coisas-esquecidas-pelo-caminho.html' title='Coisas esquecidas pelo caminho'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5371758814672641792</id><published>2008-02-28T16:36:00.000-08:00</published><updated>2008-02-28T16:43:48.416-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='divertido'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><title type='text'>Nova propaganda para o Caché</title><content type='html'>Olhem a imagem da propaganda do &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/R8dUp8KIm0I/AAAAAAAAAyA/BzTpIsuw2j4/s1600-h/cache.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/R8dUp8KIm0I/AAAAAAAAAyA/BzTpIsuw2j4/s400/cache.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172195776558308162" /&gt;&lt;/a&gt;&lt;br /&gt;E você, meu caro desenvolvedor, cansado das tabajarices que encontra no Caché? Cansou de ouvir o pessoal de marketing dizendo 'bla bla bla', e você encontrar só bug? Não, não é bug. É feature.&lt;br /&gt;&lt;br /&gt;Pois esta é a imagem que reflete melhor o que eu tenho encontrado:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/R8dUSMKImzI/AAAAAAAAAx4/iXYMAuG879M/s1600-h/notabug.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/R8dUSMKImzI/AAAAAAAAAx4/iXYMAuG879M/s400/notabug.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5172195368536415026" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Imagem via &lt;a href="http://usuariocompulsivo.blogspot.com/"&gt;UsuárioCompulsivo&lt;/a&gt;, neste post: &lt;a href="http://usuariocompulsivo.blogspot.com/2008/02/no-bug-recurso.html"&gt;Não é bug... É recurso&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5371758814672641792?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5371758814672641792/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5371758814672641792&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5371758814672641792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5371758814672641792'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/02/nova-propaganda-para-o-cach.html' title='Nova propaganda para o Caché'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0AukCty4MP0/R8dUp8KIm0I/AAAAAAAAAyA/BzTpIsuw2j4/s72-c/cache.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-736732151678311766</id><published>2008-02-26T09:25:00.000-08:00</published><updated>2008-02-26T09:31:04.921-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Argumentos variáveis (varargs) são para os fracos - ou Como o Ensemble lida com isso</title><content type='html'>Em &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS"&gt;Caché Object Script&lt;/a&gt; (a linguagem padrão pra se desenvolver no &lt;a href="http://www.intersystems.com/cache/"&gt;Caché da Intersystems&lt;/a&gt;) não conseguimos definir métodos que podem ter um número arbitrário de parâmetros, como as &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html"&gt;VarArgs do Java&lt;/a&gt;, ou mesmo as &lt;a href="http://www.codersource.net/c++_variable_argument_functions.html"&gt;funções com argumentos variáveis do C/C++&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Entretanto, ainda podemos passar como parâmetro, um array ou uma List.&lt;br /&gt;&lt;br /&gt;Então, quando me deparo com uma definição de método como esta abaixo... (consta no &lt;a href="http://a-casa-caiu.blogspot.com/2008/01/sql-adapter-no-ensemble-probleminha.html"&gt;Adapter&lt;/a&gt; EnsLib.SOAP.OutboundAdapter, do &lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;Method InvokeMethod(pMethodName As %String, Output pResult As %RegisteredObject, ByRef pArg1, ByRef pArg2, ByRef pArg3, ByRef pArg4, ByRef pArg5, ByRef pArg6, ByRef pArg7, ByRef pArg8, ByRef pArg9, ByRef pArg10, ByRef pArg11, ByRef pArg12) As %Status&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;E não estando satisfeito, fui olhar como é que este método estava implementado. Uma pequena amostra abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 90%"&gt;&lt;code&gt;        If $D(pArg12)    { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7,.pArg8,.pArg9,.pArg10,.pArg11,.pArg12) }&lt;br /&gt;        elseif $D(pArg11){ Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7,.pArg8,.pArg9,.pArg10,.pArg11) }&lt;br /&gt;        elseif $D(pArg10){ Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7,.pArg8,.pArg9,.pArg10) }&lt;br /&gt;        elseif $D(pArg9) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7,.pArg8,.pArg9) }&lt;br /&gt;        elseif $D(pArg8) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7,.pArg8) }&lt;br /&gt;        elseif $D(pArg7) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6,.pArg7) }&lt;br /&gt;        elseif $D(pArg6) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5,.pArg6) }&lt;br /&gt;        elseif $D(pArg5) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4,.pArg5) }&lt;br /&gt;        elseif $D(pArg4) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3,.pArg4) }&lt;br /&gt;        elseif $D(pArg3) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2,.pArg3) }&lt;br /&gt;        elseif $D(pArg2) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1,.pArg2) }&lt;br /&gt;        elseif $D(pArg1) { Set pResult = $zobjmethod(..%Client,pMethodName,.pArg1) }&lt;br /&gt;        else             { Set pResult = $zobjmethod(..%Client,pMethodName) }&lt;br /&gt;        $$$sysTRACE(&amp;quot;Got Result &amp;quot;_pResult)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Tá certo que pela maneira como foi concebida, essa solução nem é tão ruim assim. Isso porque no caso acima, os parâmetros estão sendo sempre passados por referência.&lt;br /&gt;&lt;br /&gt;O que me incomoda nem são os trocentos elseifs, ou a "beleza" do código. É a limitação do número de parâmetros. Tá certo que dificilmente são usados 12 argumentos, mas sempre surgem aquelas situações-limite, e um décimo terceiro argumento pode ser necessário. E aí? &lt;br /&gt;&lt;br /&gt;Uma solução é ficar alterando a própria API do Ensemble. Como foi feito &lt;a href="http://a-casa-caiu.blogspot.com/2008/01/sql-adapter-no-ensemble-probleminha.html"&gt;neste outro post, sobre um problema no Adapter de SQL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Uma outra solução é largar mão, e procurar outra ferramenta. =P&lt;br /&gt;&lt;br /&gt;Eu acho que essa merecia ir pro &lt;a href="http://thedailywtf.com/"&gt;The Daily WTF&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-736732151678311766?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/736732151678311766/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=736732151678311766&amp;isPopup=true' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/736732151678311766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/736732151678311766'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/02/argumentos-variveis-varargs-so-para-os.html' title='Argumentos variáveis (varargs) são para os fracos - ou Como o Ensemble lida com isso'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1129645079717381553</id><published>2008-02-11T06:14:00.000-08:00</published><updated>2008-02-11T07:59:20.049-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Variáveis de contexto no Ensemble BPL - Business Process Language</title><content type='html'>Trabalhando com o &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt;, a ferramenta de &lt;a href="http://en.wikipedia.org/wiki/Enterprise_application_integration"&gt;EAI&lt;/a&gt; da Intersystems, as vezes trabalhamos com o que é denominado Business Process, ou processos de negócios. &lt;br /&gt;&lt;br /&gt;Business Process (abreviados para BP, de agora em diante) dentro do Ensemble são componentes que encapsulam regras de negócios, modelados visualmente, e que para executarem código real, devem chamar outros módulos "menores". Você pode traçar um paralelo da abordagem dos BPs no Ensemble com o &lt;a href="http://en.wikipedia.org/wiki/Business_Process_Execution_Language"&gt;WS-BPEL&lt;/a&gt;, substituindo os &lt;a href="http://en.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt; por outras construções internas do Ensemble, em especial, os componentes que ele chama de Business Operations (ou BOs, pra encurtar).&lt;br /&gt;&lt;br /&gt;De fato, o pessoal marketeiro da Intersystems até mesmo batizou a "linguagem" utilizada no Ensemble de &lt;a href="http://www.intersystems.com/ensemble/docs/4/PDFS/BusinessProcessLanguage.pdf"&gt;Ensemble BPL (ou E-BPL)&lt;/a&gt;, uma clara alusão ao WS-BPEL. Apesar do E-BPL ser bem menos complexo e completo do que o WS-BPEL (o "E" faz muita diferença, já que um Executa, e outro não), ele inclui em sua definição a notação de elementos gráficos. Neste aspecto, ele se aproxima do &lt;a href="http://en.wikipedia.org/wiki/BPMN"&gt;Business Process Modeling Notation, o BPMN&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Qualquer dia falo mais sobre a BPEL/BPMN e o Ensemble BPL, mas hoje quero me focar em algo que acontece especificamente com o BPL do Ensemble, no qual eu trabalho.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/R7Bvx8KIlwI/AAAAAAAAApE/Vb8rV51hTX0/s1600-h/bpl.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/R7Bvx8KIlwI/AAAAAAAAApE/Vb8rV51hTX0/s400/bpl.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5165751676346865410" /&gt;&lt;/a&gt; (Um BPL de exemplo, na tela de edição do Ensemble)&lt;br /&gt;&lt;br /&gt;Como já disse diversas vezes, o Ensemble foi construído sobre o &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt; (o que os marketeiros da Intersystems chamam de banco de dados pós-relacional e blá-blá), e é todo baseado nele. Por isso, herda do Caché também algumas definições, nem sempre muito explícitas. E é isso o que estava ocasionando uns erros aqui...&lt;br /&gt;&lt;br /&gt;No BPL, podemos criar algumas variáveis no "contexto" do Business Process (BP). Essas variáveis podem ser tanto objetos como tipos básicos, e podem ser usadas para qualquer coisa.&lt;br /&gt;&lt;br /&gt;Pois bem, um dia desses, um BP começou a dar erros, depois de eu ter adicionado um Business Operation (BO). Entretanto, nada relacionado ao BO, ele estava correto. Estava dando erro no BP mesmo.&lt;br /&gt;&lt;br /&gt;Olhei no log de eventos do Ensemble, e logo uma linha vermelha dizia o motivo: uma variável de contexto, definida como %String, estava acusando erro de tamanho; o tamanho máximo estava definido como 50, e a string tinha tamanho superior a isso.&lt;br /&gt;&lt;br /&gt;Como disse num &lt;a href="http://a-casa-caiu.blogspot.com/2008/01/sql-adapter-no-ensemble-probleminha.html"&gt;post anterior&lt;/a&gt;, ao se definir algo como %String, o Caché/Ensemble acaba automaticamente estipulando um limite máximo pra sua string, e até nesta versão que uso (Caché 5.2, Ensemble 4.0), esse tamanho é 50.&lt;br /&gt;&lt;br /&gt;Entretanto, isso não explicava porque o erro começara a aparecer somente depois da adição de um novo BO ao BP... Mas alguns testes depois, e tudo começou a fazer sentido.&lt;br /&gt;&lt;br /&gt;Vejamos: Com apenas uma BO, podemos atribuir à variável um String extremamente grande, sem nenhum erro. Se você adicionar outra BO, vai dar erro. Por que? &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/R7Bs-sKIluI/AAAAAAAAAo0/Xikx1lnlmeU/s1600-h/bo1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/R7Bs-sKIluI/AAAAAAAAAo0/Xikx1lnlmeU/s400/bo1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5165748596855314146" /&gt;&lt;/a&gt; (Assim não dá erro.)&lt;br /&gt;&lt;br /&gt;Porque quando se usa apenas uma BO, todo o processo da BP permanece em memória. E em memória, você pode fazer quase tudo o que quiser. Até violar alguma constraint da classe, como o tamanho de um campo. Ou atribuir uma String a um campo %Date&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/R7BtTsKIlvI/AAAAAAAAAo8/dgesUs_Gr0M/s1600-h/bo2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/R7BtTsKIlvI/AAAAAAAAAo8/dgesUs_Gr0M/s400/bo2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5165748957632567026" /&gt;&lt;/a&gt; (Assim dá erro.)&lt;br /&gt;&lt;br /&gt;Quando você adiciona uma segunda BO, parte do processamento é gravado em disco (não sei porquê, mas suspeito que seja para "pausar" e recuperar o estado depois...). E quando se grava em disco, o Caché antes faz as checagens nos campos das classes. E isso inclui o tamanho de uma %String...&lt;br /&gt;&lt;br /&gt;A solução? Colocar um (MAXLEN=32000) na definição da variável no contexto. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/R7BrKsKIltI/AAAAAAAAAos/AF7C1zqWfz8/s1600-h/contexto.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/R7BrKsKIltI/AAAAAAAAAos/AF7C1zqWfz8/s400/contexto.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5165746603990488786" /&gt;&lt;/a&gt;&lt;br /&gt;Infelizmente, no meu BP "real", esta tática não funcionou. Ao fazer isso e mandar compilar, o Caché simplesmente entrava num loop infinito e travava o Studio (pra quem não sabe, o Studio é a "IDE" do Caché/Ensemble). Não descobri o motivo ali, e como estava com pressa, contornei o bug com outra solução (ou seja, gambiarra, para os íntimos).&lt;br /&gt;&lt;br /&gt;Entretanto, no meu BP de testes, funcionou perfeitamente... Vai entender...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1129645079717381553?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1129645079717381553/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1129645079717381553&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1129645079717381553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1129645079717381553'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/02/variveis-de-contexto-no-ensemble-bpl.html' title='Variáveis de contexto no Ensemble BPL - Business Process Language'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/R7Bvx8KIlwI/AAAAAAAAApE/Vb8rV51hTX0/s72-c/bpl.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5888949804790332238</id><published>2008-01-25T04:55:00.000-08:00</published><updated>2008-01-25T04:58:30.425-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Java Gateway no Ensemble e alternativas via Web Services</title><content type='html'>Já mencionei num post anterior sobre &lt;a href="http://a-casa-caiu.blogspot.com/2007/08/criptografia-em-cachensemble.html"&gt;Criptografia em Caché/Ensemble&lt;/a&gt;, que precisei usar criptografia. Como a API do &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; não contemplava nem de longe o que eu precisava (e mesmo a versão mais nova - que eu não uso - contempla, apesar de ter melhorado), fui em busca de outras soluções.&lt;br /&gt;&lt;br /&gt;Como já havia trabalhado com Java, e sabia que tinha uma boa e vasta API, pensei porque não usá-la? Vasculhando na documentação, achei o recurso do &lt;a href="http://www.intersystems.com/ensemble/docs/4/PDFS/UsingJavaGateway.pdf"&gt;Java Gateway, do Ensemble&lt;/a&gt;, que nas próprias palavras da Intersystems é:&lt;br /&gt;&lt;br /&gt;"... um jeito fácil do Ensemble interoperar com componentes Java. O Java Gateway pode instanciar objetos java externos e manipulá-los como se fossem objetos nativos do Ensemble."&lt;br /&gt;&lt;br /&gt;Como isso acontece? Bem, o Ensemble gera alguns "proxies" para as classes Java que você quer manipular. Estes proxies são classes dentro do Ensemble, em &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS"&gt;Caché Object Script (COS)&lt;/a&gt;, que fazem chamadas ao Java Gateway. O Java Gateway nada mais é que um conjunto de classes/objetos que fazem a comunicação entre uma &lt;a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine"&gt;JVM&lt;/a&gt; (máquina virtual Java) e as classes do Ensemble. Dê uma olhada na figura abaixo, que mostra como é a arquitetura dessa solução:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/R5ncejf_BDI/AAAAAAAAAgs/K1ESPxWJhMA/s1600-h/ejvg_gateway_architecture.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/R5ncejf_BDI/AAAAAAAAAgs/K1ESPxWJhMA/s400/ejvg_gateway_architecture.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5159397265613194290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Se você já estudou &lt;a href="http://pt.wikipedia.org/wiki/Computa%C3%A7%C3%A3o_distribu%C3%ADda"&gt;Sistemas Distribuídos&lt;/a&gt;, ou tem uma noção de como EJBs trabalham, deve reconhecer o design desta solução. O que o Java Gateway faz é nada menos que um pequeno "framework" (&lt;a href="http://pt.wikipedia.org/wiki/Middleware"&gt;Middleware&lt;/a&gt;, na realidade) de chamadas remotas. Neste caso, o cliente é dentro do Ensemble e o objeto remoto, dentro da JVM. Simplificadamente, o processo é o seguinte:&lt;br /&gt;&lt;br /&gt;- No Ensemble, você efetua uma chamada a um método da classe proxy.&lt;br /&gt;- A classe proxy serializa/transforma os parâmetros para serem enviados via TCP/IP para a instância do Java Gateway que deve estar rodando em uma JVM (não necessariamente na mesma máquina).&lt;br /&gt;- As classes do Java Gateway dentro da JVM recebem uma conexão TCP/IP, identificam que é uma chamada de um método, e reconstroem os parâmetros para serem reconhecidos em Java.&lt;br /&gt;- Através de reflection, fazem a chamada ao objeto Java.&lt;br /&gt;- O objeto Java retorna do método, possivelmente com algum valor.&lt;br /&gt;- Esse valor passa pelo processo de serialização/transformação, e é enviado via TCP/IP para o Ensemble.&lt;br /&gt;- A classe proxy recebe o valor pela conexão TCP/IP, transforma o(s) valor(es) para o formato usado no Caché e retorna para quem efetuou a chamada.&lt;br /&gt;&lt;br /&gt;Nota: o processo de formatar/transformar/serializar os dados para serem enviados via rede, e o seu inverso, na literatura de Sistemas Distribuídos é geralmente chamado de &lt;a href="http://en.wikipedia.org/wiki/Marshalling"&gt;marshaling/unmarshaling&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pois bem, a descrição de todo o processo é muito legal, muito bonita, mas a implementação de qualquer middleware não é trivial, mesmo num ambiente restrito, como é o Java Gateway (só um tipo de cliente, um tipo de objeto servidor, e outros). Por isso, a ocorrência de bugs não é de todo inesperada.&lt;br /&gt;&lt;br /&gt;E é exatamente isso o que aconteceu: bugs, bugs e mais bugs. Utilizando o Java Gateway na mesma máquina que rodava o Ensemble (não testei com uma JVM remota), a maioria das vezes, travava tudo. Depois de uma ou duas chamadas, a máquina parava de responder. Algumas vezes, só o Ensemble, mas em outras, congelava todo o computador, de maneira que só reiniciando no dedão.&lt;br /&gt;&lt;br /&gt;Conclusão: desisti de usar o Java Gateway. Depois de dois dias investigando sem sucesso, e sem pista do que poderia estar acontecendo, desisti (note que a classe em Java era bem simples, servindo de proxy para umas funções de criptografia, e funcionava perfeitamente bem numa JVM stand-alone). No meu caso particular, achei melhor implementar o algoritmo de criptografia nativamente em Caché Object Script.&lt;br /&gt;&lt;br /&gt;Mas nem sempre isso é possível, ou mesmo vantajoso. Imagine implementar em COS tudo o que já foi implementado em Java ou PHP, por exemplo, em termos de bibliotecas. Impraticável.&lt;br /&gt;&lt;br /&gt;Eis que uns tempos atrás, na &lt;a href="http://groups.google.com/group/intersystems-public-cache/"&gt;lista de discussão de Caché&lt;/a&gt;, o &lt;a href="http://www.mgateway.com/"&gt;Rob Tweed&lt;/a&gt; compartilhou uma idéia que ele teve, e que está na thread &lt;a href="http://groups.google.com/group/intersystems-public-cache/browse_thread/thread/e2b161301c2febf5/294420842f5f6735"&gt;Extending Cache using PHP&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;O que ele fez? Simplesmente montou uma página em PHP simples, que retornava algo do tipo: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;retorno=valor&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Usando a classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Net.HttpRequest"&gt;%Net.HttpRequest&lt;/a&gt;, ele estabeleceu uma conexão para a página PHP, obteve o retorno, e simplesmente fez um parsing simples de "retorno=valor" usando a função &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fpiece"&gt;$PIECE&lt;/a&gt;. Um esquema bem simples.&lt;br /&gt;&lt;br /&gt;Se você anda por dentro das últimas notícias, deve ter notado que esse esquema é bem parecido (na verdade, praticamente uma simplificação) de arquiteturas &lt;a href="http://www.xfront.com/REST-Web-Services.html"&gt;Web Services utilizando chamadas estilo REST&lt;/a&gt;. Implementando-se um padrão para a troca de valores (em vez de uma String customizada, um XML ou &lt;a href="http://pt.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt;), você estaria construindo a sua primeira arquitetura Web Service REST =P.&lt;br /&gt;&lt;br /&gt;Veja que esta abordagem não se limita a utilizar PHP, podendo implementar a página web com qualquer linguagem/plataforma, passando por Java e Ruby. &lt;br /&gt;&lt;br /&gt;E apesar de haver algumas implicações não mostradas, por exemplo, falhas na conexão, re-tentativas de acesso, segurança, etc., pelo menos você tem liberdade para cobrir quais casos se aplicam ao seu ambiente. Por exemplo, se o servidor que roda o PHP estiver na mesma máquina que o Caché/Ensemble, não precisará lidar com falhas de conexão. No caso de uso do Java Gateway, você provavelmente também lidará com essas implicações, a diferença é o nível de controle que você terá, bem menor. E claro, estará sujeito a bugs que você provavelmente não terá como de lidar/corrigir.&lt;br /&gt;&lt;br /&gt;Ainda no espírito de Web Services, o Caché provê algum suporte ao que se convencionou chamar de estilo ou &lt;i&gt;stack&lt;/i&gt; WS-*, que utiliza padrões mais robustos, e consequentemente mais complexos (WSDL, UDDI, WS-Security, entre outros). Para problemas simples, talvez seja pedir demais, mas a idéia permanece a mesma: extender as capacidades do Caché/Ensemble usando invocações de provedores externos.&lt;br /&gt;&lt;br /&gt;Conclusão: para extender as capacidades do Ensemble, prefira outras alternativas, como a utilização de Web Services, do que o uso do Java Gateway. Como o Java Gateway também cria um processo separado para a execução da JVM, não existem ganhos significativos em relação ao uso de um outro servidor leve, como por exemplo, um Tomcat. Em suma, talvez o Java Gateway tenha servido há algum tempo atrás, mas hoje em dia, deve ser usado somente em caso de código legado que faça uso deste.&lt;br /&gt;&lt;br /&gt;Em tempo: a versão nova do Ensemble parece não ter novidades em relação ao Java Gateway, pelo menos não encontrei nada olhando a &lt;a href="http://www.intersystems.com/ensemble/docs/200712/pdfs/EJVG.pdf"&gt;documentação da nova versão&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5888949804790332238?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5888949804790332238/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5888949804790332238&amp;isPopup=true' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5888949804790332238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5888949804790332238'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/01/java-gateway-no-ensemble-e-alternativas.html' title='Java Gateway no Ensemble e alternativas via Web Services'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0AukCty4MP0/R5ncejf_BDI/AAAAAAAAAgs/K1ESPxWJhMA/s72-c/ejvg_gateway_architecture.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5060588691103357463</id><published>2008-01-10T06:44:00.000-08:00</published><updated>2008-01-10T07:11:49.699-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>SQL Adapter no Ensemble - probleminha</title><content type='html'>Faz tempo que não posto nada, mas hoje vi algo que me fez postar.&lt;br /&gt;&lt;br /&gt;Até agora, usando o &lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble da Intersystems&lt;/a&gt;, não havia ainda precisado usar um adaptador de entrada SQL (ou no original em inglês, um SQL Inbound Adapter). OK, estou indo muito rápido no assunto. Se você já conhece a estrutura do Ensemble, pule os dois parágrafos abaixo.&lt;br /&gt;&lt;br /&gt;O Ensemble é uma ferramenta que serve como várias coisas, entre elas &lt;a href="http://en.wikipedia.org/wiki/Enterprise_service_bus"&gt;&lt;i&gt;Enterprise Service Bus (ESB)&lt;/i&gt;&lt;/a&gt; (assim ele é vendido pelo pessoal de &lt;i&gt;marketing&lt;/i&gt;, mas você deve conhecer o pessoal de &lt;i&gt;marketing&lt;/i&gt;...), mas é mais tipicamente um &lt;a href="http://en.wikipedia.org/wiki/Enterprise_application_integration"&gt;&lt;i&gt;Enterprise Application Integration (EAI)&lt;/i&gt;&lt;/a&gt; (uma abordagem mais realista do produto). O que ele basicamente faz é servir de "ponte" para que dois ou mais sistemas possam se comunicar. E eles podem se comunicar de diferentes maneiras, desde troca de arquivos e tabelas de banco de dados, até interfaces mais "modernas", como mensagens &lt;a href="http://pt.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt; (com &lt;a href="http://pt.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt;), etc... Como cada sistema tem uma interface de comunicação, o Ensemble provê adaptadores (ou &lt;i&gt;Adapters&lt;/i&gt; no original), que são interfaces entre os diferentes tipo de protocolos/estilos de comunicação e o ambiente interno do Ensemble. &lt;br /&gt;&lt;br /&gt;Por exemplo, você pode ter uma aplicação legada que produza somente arquivos texto como saída, e quer fazer uma espécie de  &lt;a href="http://en.wikipedia.org/wiki/Mashup_(web_application_hybrid)"&gt;"mashup"&lt;/a&gt; desses arquivos com dados de outro sistema, que persiste as suas informações num banco de dados, e exibir a saída dessa "mistura" num XML via Web Service. Neste caso, pode-se usar o Ensemble com um &lt;i&gt;Adapter&lt;/i&gt; de arquivo, para conversar com a aplicação legada, um &lt;i&gt;Adapter&lt;/i&gt; SQL para conversar com o banco de dados, e um &lt;i&gt;Adapter&lt;/i&gt; SOAP para exibir o resultado em XML.&lt;br /&gt;&lt;br /&gt;Voltando ao assunto principal do post...&lt;br /&gt;&lt;br /&gt;O &lt;i&gt;Adapter&lt;/i&gt; SQL permite que se coloque uma consulta SQL, que executa de tempos em tempos, e ele "aciona" outro componente do Ensemble (um &lt;i&gt;Business Service&lt;/i&gt;), enviando cada linha da consulta retornada.&lt;br /&gt;&lt;br /&gt;É uma boa idéia, mas como de costume, alguns problemas apareceram...&lt;br /&gt;&lt;br /&gt;Pra começar, vamos ver uma parte da classe do &lt;i&gt;Adapter&lt;/i&gt; SQL:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Class EnsLib.SQL.InboundAdapter &lt;br /&gt;   Extends (Ens.InboundAdapter, EnsLib.SQL.Common) &lt;br /&gt;         [ ClassType = "", ProcedureBlock ]&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;/// The Base query string that will &lt;br /&gt;/// be repeatedly executed to look for new rows&lt;br /&gt;Property Query As %String [ Required ];&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A propriedade &lt;code&gt;Query&lt;/code&gt;, um &lt;code&gt;%String&lt;/code&gt;, guarda a consulta SQL que será executada. Entretanto, não é qualquer consulta que pode ser realizada. Veja a consulta abaixo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT id_tabela, campo1, campo2 FROM grande_tabela WHERE algum_campo &lt;= 10&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Supondo que a tabela mencionada exista, bem como os campos, essa consulta deveria funcionar. Entretanto, observe o que acontece quando se tenta colocar a consulta na configuração do &lt;i&gt;Adapter&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/R4Yvz4hKjQI/AAAAAAAAAYE/YnYg1kwR27Q/s1600-h/sql_adapter_problem.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/R4Yvz4hKjQI/AAAAAAAAAYE/YnYg1kwR27Q/s400/sql_adapter_problem.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5153859391963434242" /&gt;&lt;/a&gt;&lt;br /&gt;Depois de pesquisar um pouco, vi que o problema estava na classe do &lt;i&gt;Adapter&lt;/i&gt; SQL. Note que a propriedade Query foi definida como &lt;code&gt;%String&lt;/code&gt;. Entretanto, o que pode não ser tão visível é a restrição que isso impõe. Ao se definir uma propriedade como %String, automaticamente é estipulado também um tamanho máximo que aquela String poderá conter. Caso você não defina manualmente, o &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/"&gt;Ensemble&lt;/a&gt; usa um valor padrão, no caso, 50. Como a consulta acima tem mais de 50 caracteres, acontece o erro mostrado na figura.&lt;br /&gt;&lt;br /&gt;Para reparar esse "erro", abri a classe, alterei o código fonte (só acrescentei um parâmetro na propriedade, mostrado abaixo) e recompilei. E pronto!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Class EnsLib.SQL.InboundAdapter &lt;br /&gt;   Extends (Ens.InboundAdapter, EnsLib.SQL.Common) &lt;br /&gt;         [ ClassType = "", ProcedureBlock ]&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;/// The Base query string that will &lt;br /&gt;/// be repeatedly executed to look for new rows&lt;br /&gt;Property Query As %String(MAXLEN = 500) [ Required ];&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE1:&lt;/b&gt; Esqueci de mencionar que isso foi feito na versão 4 do Ensemble, a que utiliza o Caché 5.2. Não tenho, nem testei a versão mais nova (2007.1) pra ver como se comporta.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE2:&lt;/b&gt; Aqui vai o link para um pdf sobre SQL &lt;i&gt;Adapter&lt;/i&gt;s. Apesar de ser para a versão mais nova do Ensemble, muita coisa vale para a versão mais antiga: &lt;a href="http://www.intersystems.com/ensemble/docs/200712/pdfs/ESQL.pdf"&gt;Using SQL Adapters with Ensemble - version 2007.1.2&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5060588691103357463?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5060588691103357463/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5060588691103357463&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5060588691103357463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5060588691103357463'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2008/01/sql-adapter-no-ensemble-probleminha.html' title='SQL Adapter no Ensemble - probleminha'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/R4Yvz4hKjQI/AAAAAAAAAYE/YnYg1kwR27Q/s72-c/sql_adapter_problem.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-4695330088637209678</id><published>2007-11-28T06:14:00.000-08:00</published><updated>2007-11-28T06:15:08.224-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='divertido'/><category scheme='http://www.blogger.com/atom/ns#' term='carreira'/><title type='text'>Entrevista de Emprego</title><content type='html'>Um ótimo texto sobre carreira e entrevistas de emprego, visto no &lt;a href="http://teoriascobalisticas.blogspot.com/2007/11/quem-mandou-perguntar.html"&gt;Teorias Cobalísticas&lt;/a&gt;, creditado ao grande Max Gehringer:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Quem mandou perguntar?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Há anos, com a coloboração de colegas recrutores de pessoal, eu venho colecionando respostas reais dadas por candidatos a emprego. Mas só recentemente descobri que a coleção pode ter a finalidade prática de confortar os aflitos. Quando alguém diz: "Não sei, acho que fui mal na entrevista", e aí vê essas preciosidades verbais, percebe que não foi tão mal assim. Alguns exemplos:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - E então, você está construindo uma networking?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Veja bem, eu não sou engenheiro, sou administrador.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Como você administra a pressão?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Ah, tranqüilo. 1 por 7, no máximo 12 por 8.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Manter sempre o foco é muito importante. E me parece que você tem alguns lapsos de concentração.&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - O senhor poderia repetir a pergunta?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Como você se sente trabalhando em equipe?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Bom, desde que não tenha gente dando palpite, me sinto muito bem.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Como você se definiria em termos de flexibilidade?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Ah, eu faço academia. Sou capaz de encostar o cotovelo na nuca.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Nós somos uma empresa que nunca pára de perseguir objetivos.&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Que ótimo. E já conseguiram prender algum?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Vejo que você demonstra uma tendência para discordar.&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Muito pelo contrário.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Em sua opinião, quais seriam os atributos de um bom líder?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Ah, são várias coisas. Mas a principal é ter liderança.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Noto que você não mencionou sua idade aqui no currículo.&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - É que eu uso óculos, e isso me faz parecer mais velho.&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - E qual é a sua idade?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Com óculos ou sem óculos.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Quais seriam seus pontos fracos?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Ah, é só o joelho. Até tive de parar de jogar futebol.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Há alguma pergunta que você queira me fazer?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Eu parei meu carro aí na rua. Será que eu vou ser multado?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Por que, dentre tantos candidatos, nós deveríamos contratá-la?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Eu pensei que responder a isso fosse seu trabalho.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Como você pode contribuir para melhorar nosso ambiente de trabalho?&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Bem, eu começaria trocando a recepcionista, que é muito feia.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Quando digo "sucesso" qual é a primeira palavra que lhe vem à mente?&lt;br /&gt;Candidata - Pode ser duas palavras?&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Pode&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Milho. Nário.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Entrevistador&lt;/b&gt; - Várias pessoas que se sentaram aí nessa mesma cadeira hoje são gerentes.&lt;br /&gt;&lt;b&gt;Candidato&lt;/b&gt; - Puxa, o fabricante da cadeira vai ficar muito feliz em saber disso.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Tentei verificar se esse texto é mesmo de autoria do Mr. Max (em tempos de Internet, o que mais se vê é texto creditado erroneamente), mas o máximo que consegui foi &lt;a href="http://www.criativamarketing.com.br/criativa/paginanoticias2.asp?area=Artigos&amp;subarea=Marketing%20Pessoal&amp;cod_info=667&amp;codigo=97"&gt;esta página&lt;/a&gt;, creditando o texto ao Max Gehringer, e dizendo que fora publicado na revista &lt;a href="http://portalexame.abril.com.br/"&gt;Exame&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-4695330088637209678?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/4695330088637209678/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=4695330088637209678&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/4695330088637209678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/4695330088637209678'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/11/entrevista-de-emprego.html' title='Entrevista de Emprego'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6126697022367420730</id><published>2007-11-26T06:22:00.000-08:00</published><updated>2007-11-26T07:40:06.093-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Listas em Cache - problemas</title><content type='html'>Como eu já havia comentado no &lt;a href="http://a-casa-caiu.blogspot.com/2007/11/listas-em-cache.html"&gt;post anterior&lt;/a&gt;, e o comentário do Carlos reforçou, ao se usar listas ou arrays do Caché, temos o problema do tamanho destas. Como o Carlos bem falou, quando estamos inserindo itens numa lista em memória, tudo ocorre bem. O problema é quando vamos salvar a classe que mantém essa lista. &lt;br /&gt;&lt;br /&gt;Por que disso? A resposta passa por como o Caché persiste os objetos. No &lt;a href="http://a-casa-caiu.blogspot.com/2007/11/listas-em-cache.html"&gt;post anterior&lt;/a&gt; comentamos que as listas/arrays são do tipo serial, herdando de %SerialObject. Isso quer dizer que elas vão "embutidas" dentro de outros objetos ao serem persistidas, ou seja, essas classes não têm um ID próprio. &lt;br /&gt;&lt;br /&gt;Olhem como fica um objeto persistido da classe que o Carlos passou no comentário, contendo no exemplo abaixo, uma lista com dez elementos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;^Teste.EstouroD(1) = $lb("",11,$lb(1,2,3,4,5,6,7,8,9,10))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note como a lista vai "serializada" dentro da classe. Como no Caché um objeto persistido é na verdade um valor numa global, e valores nas globais são basicamente grandes Strings, ficamos limitados a objetos menores que 32Kb no total, já que esse é o limite de uma String (pelo menos até a versão 5.2).&lt;br /&gt;&lt;br /&gt;Se tivermos uma classe com muitas propriedades, e cada propriedade for muito grande, se esse objeto for serializado dentro de uma lista, o tamanho da lista vai ficar ainda mais enorme. Nestes casos, vale a pena deixar a classe persistente, assim na lista vão ficar guardados os IDs dos objetos, e não os objetos em si serializados.&lt;br /&gt;&lt;br /&gt;De qualquer jeito, se a sua lista contiver muitos valores, o erro deve persistir. Nestes casos, o negócio é abandonar um pouco a abordagem OO e partir para gerenciar dados nas globais mesmo.&lt;br /&gt;&lt;br /&gt;P.S. Em outro comentário, o Carlos fala sobre o &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25SYSTEM.Encryption"&gt;%System.Encription&lt;/a&gt;, pra resolver os problemas em relação a &lt;a href="http://a-casa-caiu.blogspot.com/2007/08/criptografia-em-cachensemble.html"&gt;criptografia em Caché&lt;/a&gt;. Realmente, eu não tinha visto essa classe, e o help não ajudou muito, pq eu havia procurado pelo DES, e a classe só tem suporte para o AES (considerei o DES como sendo o menor denominador comum em casos de criptografia, por ele ser um dos mais antigos, bem documentados e relativamente fácil de implementar). &lt;br /&gt;&lt;br /&gt;No caso, o AES não iria adiantar, porque no lado cliente, só tinhamos suporte pro DES. Mas, fica aqui a dica.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6126697022367420730?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6126697022367420730/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6126697022367420730&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6126697022367420730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6126697022367420730'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/11/listas-em-cache-problemas.html' title='Listas em Cache - problemas'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1058809010355402794</id><published>2007-11-14T07:27:00.001-08:00</published><updated>2007-11-14T07:27:20.733-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='citações'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Não se trata disso</title><content type='html'>Resposta genial, ilustra muito bem a sociedade e o tipo de educação que temos hoje em dia, retirado do &lt;a href="http://circuitointegrado.folha.blog.uol.com.br/arch2007-11-11_2007-11-17.html#2007_11-14_12_16_49-121774324-0"&gt;blog Circuito Integrado da Folha&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Cerf estava em uma conversa, digamos, mais animada com um dos participantes da mesa, que argumentava que o Google deveria filtrar o conteudo usando a qualidade e credibilidade como criterios tambem.&lt;br /&gt;&lt;br /&gt;"O Google nao se trata disso", disse Cerf.&lt;br /&gt;&lt;br /&gt;"Mas para meu filho de nove anos o Google eh a verdade, ele diz: esta no Google", --rebateu o palestrante.&lt;br /&gt;&lt;br /&gt;"Entao o problema nao eh com o Google, eh de criacao", rebateu Cerf, para aplausos de partes dos presentes e constrangimento de outros."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RzsTePR5pEI/AAAAAAAAASY/GmctpKVp2qA/s1600-h/vinton_cerf.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RzsTePR5pEI/AAAAAAAAASY/GmctpKVp2qA/s400/vinton_cerf.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5132717610537428034" /&gt;&lt;/a&gt; (Velhinho esperto - foto retirada da &lt;a href="http://www.icann.org/biog/cerf.htm"&gt;biografia no ICANN&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Só pra constar, &lt;a href="http://en.wikipedia.org/wiki/Vinton_Cerf"&gt;Vinton Cerf&lt;/a&gt; é um dos vice-presidentes do Google, e um dos criadores do &lt;a href="http://pt.wikipedia.org/wiki/TCP/IP"&gt;TCP/IP&lt;/a&gt;, que é uma das bases da Internet, ou seja, que possibilita vc ler isso agora.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1058809010355402794?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1058809010355402794/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1058809010355402794&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1058809010355402794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1058809010355402794'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/11/no-se-trata-disso.html' title='Não se trata disso'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0AukCty4MP0/RzsTePR5pEI/AAAAAAAAASY/GmctpKVp2qA/s72-c/vinton_cerf.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3733825437109681969</id><published>2007-11-03T12:46:00.000-07:00</published><updated>2007-11-26T06:24:20.331-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Listas em Cache</title><content type='html'>&lt;i&gt;Listas em Caché - abordagem orientada a objeto&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ao contrário do &lt;a href="http://java.sun.com/"&gt;Java&lt;/a&gt;, no &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché da Intersystems&lt;/a&gt; não temos uma grande API quando se trata de estruturas de dados de coleções (listas, filas, conjuntos, árvores, etc). De fato, quando trabalhamos com orientação a objeto no Caché, basicamente existem dois conceitos de coleção: as listas e os arrays. &lt;br /&gt;&lt;br /&gt;Vamos verificar então o que listas e arrays significam para o &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;. Listas são, como o nome bem indica, listas de objetos (como aqueles que você escreve) ou de tipos básicos (como &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_datatypes#GOBJ_B296"&gt;%Integer ou %Float&lt;/a&gt;). Cada elemento de uma lista é associado a uma posição da lista. Neste caso, listas em Caché são bem parecidas com listas em Java (em termos de &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/List.html"&gt;interface&lt;/a&gt;, de implementação não dá pra comparar bem, já que em Java podemos ter listas como &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/ArrayList.html"&gt;ArrayList&lt;/a&gt; ou &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/LinkedList.html"&gt;LinkedList&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Em Caché, a classe abstrata &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList"&gt;%Collection.AbstractList&lt;/a&gt; fornece a interface básica pela qual podemos trabalhar com listas. Adaptada da documentação, o código abaixo ilustra a criação de uma lista, quatro inserções de elementos nesta lista, e como podemos percorrer a lista, recuperando seus elementos:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;PRE&gt;&lt;br /&gt;&lt;FONT COLOR="#008000"&gt;; instancia nova lista&lt;/FONT&gt;&lt;br /&gt;&lt;FONT  COLOR="#000000" BGCOLOR="#ffffff"&gt; &lt;FONT COLOR="#0000ff"&gt;Set &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list=&lt;/FONT&gt;&lt;FONT COLOR="#000080"&gt;##class&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ListOfDataTypes"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#008080"&gt;%ListOfDataTypes&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;).&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;%New&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;()&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;; adiciona quatro elementos na lista&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Do &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#Insert"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Insert&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(&lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;&amp;quot;DArtagnan&amp;quot;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;)&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Do &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#Insert"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Insert&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(&lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;&amp;quot;Athos&amp;quot;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;)&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Do &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#Insert"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Insert&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(&lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;&amp;quot;Porthos&amp;quot;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;)&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Do &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#Insert"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Insert&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(&lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;&amp;quot;Aramis&amp;quot;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;)&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#008000"&gt;; percorre a lista&lt;br /&gt; &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;For &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;i=1:1:list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#Count"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Count&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;()  &lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;Write &lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;list.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractList#GetAt"&gt;&lt;/FONT&gt;&lt;FONT COLOR="#0000ff"&gt;GetAt&lt;/a&gt;&lt;/nobr&gt;&lt;/FONT&gt;&lt;FONT COLOR="#000000"&gt;(i),!&lt;/FONT&gt;&lt;/FONT&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Arrays no Caché, por outro lado, são bem diferentes do que o nome pode sugerir (pelo menos pra mim, que vim de linguagens como Java, Pascal, C/C++). &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray"&gt;Arrays do Caché&lt;/a&gt; são como objetos da interface &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Map.html"&gt;Map do Java&lt;/a&gt;, eles necessitam além do elemento a ser guardado na estrutura (objeto ou tipo básico de dados), uma "chave" associada, para você acessar o elemento. Essas estruturas são muito úteis ao implementar coisas como &lt;a href="http://en.wikipedia.org/wiki/Hash_table"&gt;tabelas de Hash&lt;/a&gt;, assim como a &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Hashtable.html"&gt;Hashtable&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Nada melhor que um exemplo para esclarecer, por isso vamos ver o exemplo adaptado da documentação da classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray"&gt;%Collection.AbstractArray&lt;/a&gt;, que serve como interface para as classes de array no Caché:&lt;br /&gt;&lt;br /&gt;&lt;div &gt;&lt;pre&gt;&lt;font bgcolor="#ffffff" color="#000000"&gt;&lt;/font&gt;&lt;font color="#008000"&gt;; instancia um objeto array &lt;/font&gt;&lt;br /&gt; &lt;font color="#0000ff"&gt;Set &lt;/font&gt;&lt;font color="#000000"&gt;arr=&lt;/font&gt;&lt;font color="#000080"&gt;##class&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ArrayOfDataTypes"&gt;&lt;/a&gt;&lt;/nobr&gt;&lt;/font&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ArrayOfDataTypes"&gt;&lt;font color="#008080"&gt;%ArrayOfDataTypes&lt;/font&gt;&lt;/a&gt;&lt;font color="#008080"&gt;&lt;/font&gt;&lt;font color="#000000"&gt;).&lt;/font&gt;&lt;font color="#0000ff"&gt;%New&lt;/font&gt;&lt;font color="#000000"&gt;()&lt;br /&gt; &lt;/font&gt;&lt;font color="#008000"&gt;; coloca itens no array - o segundo parâmetro é a "chave"&lt;br /&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;Do &lt;/font&gt;&lt;font color="#000000"&gt;arr.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#SetAt"&gt;&lt;/a&gt;&lt;/nobr&gt;&lt;/font&gt;&lt;a class="MethodLink" href="#SetAt"&gt;&lt;font color="#0000ff"&gt;SetAt&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#008000"&gt;"red"&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;font color="#008000"&gt;"color"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;br /&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;Do &lt;/font&gt;&lt;font color="#000000"&gt;arr.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#SetAt"&gt;&lt;/a&gt;&lt;/nobr&gt;&lt;/font&gt;&lt;a class="MethodLink" href="#SetAt"&gt;&lt;font color="#0000ff"&gt;SetAt&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#008000"&gt;"large"&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;font color="#008000"&gt;"size"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;br /&gt; &lt;/font&gt;&lt;font color="#0000ff"&gt;Do &lt;/font&gt;&lt;font color="#000000"&gt;arr.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#SetAt"&gt;&lt;/a&gt;&lt;/nobr&gt;&lt;/font&gt;&lt;a class="MethodLink" href="#SetAt"&gt;&lt;font color="#0000ff"&gt;SetAt&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#008000"&gt;"expensive"&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;&lt;font color="#008000"&gt;"price"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;br /&gt; &lt;/font&gt;&lt;font color="#008000"&gt;; iteração no array&lt;/font&gt;&lt;br /&gt; &lt;font color="#0000ff"&gt;Set&lt;/font&gt; &lt;font color="#000000"&gt;key&lt;/font&gt;=&lt;font color="#008000"&gt;""&lt;/font&gt;&lt;br /&gt; &lt;font color="#0000ff"&gt;For&lt;/font&gt;  Set &lt;font color="#000000"&gt;value&lt;/font&gt;=arr.&lt;nobr&gt;&lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#GetNext"&gt;&lt;font color="#0000ff"&gt;GetNext&lt;/font&gt;&lt;/a&gt;&lt;/nobr&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;.key) &lt;font color="#0000ff"&gt;Quit&lt;/font&gt;&lt;font color="#000000"&gt;:&lt;/font&gt;key=&lt;font color="#008000"&gt;""&lt;/font&gt;  &lt;font color="#0000ff"&gt;Write&lt;/font&gt; &lt;font color="#000000"&gt;key&lt;/font&gt;,&lt;font color="#008000"&gt;":"&lt;/font&gt;&lt;font color="#000000"&gt;,&lt;/font&gt;value,!&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;(Notem que o método &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#SetAt"&gt;SetAt&lt;/a&gt;, correspondente ao &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Map.html#put(K,%20V)"&gt;put do java.util.Map&lt;/a&gt;, tem os parâmetros invertidos com relação a este, enquanto no &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Map.html#put(K,%20V)"&gt;put&lt;/a&gt; a chave vem como primeiro parâmetro, no &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Collection.AbstractArray#SetAt"&gt;SetAt&lt;/a&gt; a chave vem no segundo.)&lt;br /&gt;&lt;br /&gt;Em ambos exemplos acima, usamos tipos de dados básicos como elementos nas lista e array, mas poderíamos ter usado objetos. Para isso, ao invés de termos usado &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ListOfDataTypes"&gt;%ListOfDataTypes&lt;/a&gt; e &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ArrayOfDataTypes"&gt;%ArrayOfDataTypes&lt;/a&gt;, usaríamos &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ListOfObjects"&gt;%ListOfObjects&lt;/a&gt; e &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.ArrayOfObjects"&gt;%ArrayOfObjects&lt;/a&gt;, respectivamente.&lt;br /&gt;&lt;br /&gt;Quando usamos &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_properties#GOBJ_C2315"&gt;coleções como propriedades de classes&lt;/a&gt;, podemos ou declarar a propriedade explicitamente como objeto das classes de Array/List (como faríamos como qualquer outra classe), ou então podemos declarar assim:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;pre&gt;&lt;br /&gt;    &lt;font color="#008000"&gt;; uma lista de %Strings: &lt;/font&gt;&lt;br /&gt;    &lt;font color="#008000"&gt;; em vez de: Property Colors As %ListOfDataTypes &lt;/font&gt;&lt;br /&gt;    &lt;font color="#000000"&gt;Property &lt;/font&gt;&lt;font color="#008000"&gt;Colors&lt;/font&gt;&lt;font color="#000000"&gt; As List Of &lt;/font&gt;&lt;font color="#0000ff"&gt;%String&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Vale lembrar que esses objetos arrays e lists são do tipo &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.SerialObject"&gt;Serial, ou seja, herdam de %SerialObject&lt;/a&gt;, e que portanto vão "serializadas" dentro de outra classe, se forem persistidas. Se a sua lista for muito grande, ou mesmo que a lista não tenha muitos elementos, mas os seus elementos sejam %SerialObject, pode ocorrer um erro de MAXSTRING. &lt;br /&gt;&lt;br /&gt;Considere a classe abaixo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Class Teste.Estouro Extends %Persistent [ ClassType = persistent ] {&lt;br /&gt;&lt;br /&gt;Property lista As list Of %String;&lt;br /&gt;&lt;br /&gt;ClassMethod teste(qtde as %Integer) &lt;br /&gt;  {&lt;br /&gt;    set a = ##class(Teste.Estouro).%New()&lt;br /&gt;    w a.%Save()&lt;br /&gt;    For i=1:1:qtde  {&lt;br /&gt;        do a.lista.Insert(i)&lt;br /&gt;    }&lt;br /&gt;    w a.%Save()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Experimente chamar de uma janela de terminal o método teste, passando diferentes valores. Ao se passar uns 10000, você já pode conferir o erro de MAXSTRING. Lembrando que isso vale para versão 5.2 do Caché. Ouvi dizer que na versão 2007, o limite de tamanho de Strings aumentou, então esse tipo de erro deve ocorrer menos frequentemente, mas não cheguei a verificar na documentação isso.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3733825437109681969?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3733825437109681969/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3733825437109681969&amp;isPopup=true' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3733825437109681969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3733825437109681969'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/11/listas-em-cache.html' title='Listas em Cache'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6528448296144790915</id><published>2007-10-31T03:31:00.001-07:00</published><updated>2007-10-31T03:33:56.920-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trabalho'/><title type='text'>Dicas de como fazer um bom curriculo</title><content type='html'>Originalmente iria postar só no &lt;a href="http://estou-sem.blogspot.com/2007/10/dicas-de-como-fazer-um-bom-curriculo.html"&gt;outro blog&lt;/a&gt;, mas achei que valia apena postar aqui tb.&lt;br /&gt;&lt;br /&gt;E aproveitando o embalo das &lt;a href="http://estou-sem.blogspot.com/2007/10/tirinhas-trabalhadoras.html"&gt;tirinhas trabalhadores&lt;/a&gt; (&lt;i&gt;assunto do outro blog&lt;/i&gt;), mais um post sobre o duro mercado de trabalho, aquele que a gente faz pra ganhar o leitinho (&lt;a href="http://www1.folha.uol.com.br/folha/cotidiano/ult95u338822.shtml"&gt;esperamos que não adulterado&lt;/a&gt;) para as crianças XD.&lt;br /&gt;&lt;br /&gt;Desta vez, umas dicas para quem está precisando fazer ou atualizar o currículo. O texto abaixo foi retirado da revista &lt;a href="http://vocesa.abril.com.br/home/"&gt;Você S/A&lt;/a&gt; do mês passado, setembro de 2007. Se você não lê, eu aconselho, é uma das poucas revistas (tirando os meus quadrinhos/mangás, claro) que eu compro na banca. &lt;br /&gt;&lt;br /&gt;Bem, esse post foi inspirado mesmo na folha online, que coincidentemente deu essas dicas, que também ajudarão a você formar um currículo nota dez (e se graças a isso ganhar um empregão, eu aceito um presentinho =P):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www1.folha.uol.com.br/folha/classificados/empregos/ult1671u340538.shtml"&gt;Objetividade no currículo é a senha para entrevista&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www1.folha.uol.com.br/folha/classificados/empregos/ult1671u340541.shtml"&gt;Dicas para turbinar o currículo&lt;/a&gt;&lt;/ul&gt;&lt;br /&gt;Então, sem mais delongas, aqui vai:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;O currículo certo e o errado&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Saiba como evitar os problemas que podem tirar o seu nome da disputa por uma vaga antes mesmo da entrevista&lt;/i&gt;&lt;br /&gt;Por Françoise Terzian&lt;br /&gt;&lt;br /&gt;Passar para a segunda fase de um recrutamento que começou com a seleção de currículos requer atenção a detalhes. Fotos inadequadas, português errado e letras coloridas chegam a derrubar um em cada quatro currículos enviados por candidatos a uma vaga. "Recebemos 180 000 currículos ao ano e 25% deles são descartados por ser muito longos ou conter erros gramaticais", diz Augusto Costa, diretor- geral da Manpower no Brasil. A consultoria de recursos humanos, de São Paulo, atende empresas como Motorola e Michelin. Aqui, Augusto e outros especialistas em recrutamento apontam quais são os sete erros fatais de um currículo. Sem eles, suas chances de conseguir a vaga aumentam. Veja, abaixo, exemplos resumidos de um currículo bom e de outro ruim.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/RycO81s1_WI/AAAAAAAAAQo/YfvDfi28-gw/s1600-h/111_cv1_400x615.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/RycO81s1_WI/AAAAAAAAAQo/YfvDfi28-gw/s400/111_cv1_400x615.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5127083139154705762" /&gt;&lt;/a&gt; (Um currículo bem feito)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RycPLFs1_XI/AAAAAAAAAQw/lgnQUAWphd0/s1600-h/111_cv2_400x615.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RycPLFs1_XI/AAAAAAAAAQw/lgnQUAWphd0/s400/111_cv2_400x615.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5127083383967841650" /&gt;&lt;/a&gt; (E outro nem tanto - veja as dicas abaixo)&lt;br /&gt;&lt;br /&gt;EVITE&lt;br /&gt;&lt;br /&gt;&lt;i&gt;FOTOS E RG&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Só mande foto (3x4 comportada, claro) se isso for pedido por quem está fazendo a seleção. "E nunca inclua o número do RG e CPF no currículo", diz Mara Turolla,consultora da Career Center,empresa de recolocação.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;POLUIÇÃO VISUAL&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Nada de firulas: a melhor apresentação são folhas brancas simples e fontes Arial ou Times New Roman — mais clássicas.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;ERROS DE PORTUGUÊS&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;São os mais comuns — como os que estão marcados em amarelo ao lado — e podem reprovar um bom candidato. "Demonstram que ele foi desleixado.Ou que não sabe escrever", diz Augusto, da Manpower.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;FALAR DIFÍCIL&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Informações demais fazem o selecionador gastar tempo — e a média que eles dedicam a um currículo é 40 segundos. Não vá escrever que fez curso de datilografia, tampouco. "Prolixidade mascara as informações relevantes", diz Alexandre Ullmann, gerente de recrutamento da CPM Braxis, empresa de tecnologia da informação.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;MENTIRAS&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Há quem diga que concluiu um curso sem ter realmente chegado ao fim. Vale o mesmo para dizer que é fluente em inglês. Por fim, errar nas datas de permanência nas empresas acaba levantando suspeitas do entrevistador.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;FALTA DE FOCO&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Realce seus resultados numéricos mais do que as tarefas que você desempenhava. Em vez de "analisava as estratégias de marketing", use "elevei as vendas da empresa em 15% após analisar a concorrência".&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;DESTACAR O INÍCIO DA CARREIRA&lt;/i&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Deixar os últimos empregos para o fim pode fazer seu currículo ser descartado prematuramente.As informações devem vir em ordem decrescente."Se sua carreira for muito longa, saliente os cargos mais recentes", diz Augusto Puliti, gerente da consultoria Michael Page.&lt;/ul&gt;&lt;br /&gt;&lt;i&gt;...Fim da matéria&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Não deixem de ler a &lt;a href="http://www.vocesa.com.br"&gt;Você S/A&lt;/a&gt;. E não, não estou ganhando nada pra fazer essa propaganda. XD&lt;br /&gt;&lt;br /&gt;P.S. No título a palavra 'currículo' está sem acento, pro blogger não comer o 'i' da palavra no link que ele gera.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6528448296144790915?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6528448296144790915/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6528448296144790915&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6528448296144790915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6528448296144790915'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/10/dicas-de-como-fazer-um-bom-curriculo.html' title='Dicas de como fazer um bom curriculo'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/RycO81s1_WI/AAAAAAAAAQo/YfvDfi28-gw/s72-c/111_cv1_400x615.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1572341047138834109</id><published>2007-10-29T14:54:00.000-07:00</published><updated>2007-10-29T15:19:50.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>A falta que um ROWNUM faz...</title><content type='html'>Hoje precisava calcular a média de um campo dentro de uma tabela no &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché, da Intersystems&lt;/a&gt;. A lógica era até bem simples: eu precisava ver a média dos preços das últimas N compras, depois de uma certa data.&lt;br /&gt;&lt;br /&gt;O &lt;a href="http://www.oracle.com"&gt;Oracle&lt;/a&gt; tem a &lt;a href="http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html"&gt;pseudo-coluna ROWNUM&lt;/a&gt;, o que facilita bastante. Num SQL do Oracle, eu teria algo parecido:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT AVG(PRECO) &lt;br /&gt;FROM COMPRAS &lt;br /&gt;WHERE DATA &gt; '01/01/01' AND ROWNUM &lt;= 20&lt;br /&gt;ORDER BY DATA DESC&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Neste exemplo simples, estamos pegando a média dos preços das 20 últimas compras, efetuadas depois do dia 01/01/01. Bem simples, não?&lt;br /&gt;&lt;br /&gt;Fui procurar algo parecido no Caché, mas não encontrei nada. Bem, tem algumas coisas, como o nro de linhas retornadas numa consulta, ou mesmo o &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_select#RSQL_C18629"&gt;TOP, usado no SELECT&lt;/a&gt;. Infelizmente, nenhuma solução apareceu, então resolvi fazer um cursor (ou poderia tb ter feito um &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GSQL_dynsql#GSQL_C10383"&gt;ResultSet&lt;/a&gt;, se quisesse), e iterar pela consulta e calcular a média 'na mão'.&lt;br /&gt;&lt;br /&gt;Bem, a consulta ficou mais ou menos assim:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT TOP 20 PRECO&lt;br /&gt;FROM COMPRAS &lt;br /&gt;WHERE DATA &gt; '01/01/01' &lt;br /&gt;ORDER BY DATA DESC&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Notem o 'TOP 20', que diz que a consulta só precisa me retornar os 20 primeiros resultados. Infelizmente, não dá pra usar no WHERE, que é onde eu precisaria, para executar a &lt;a href="http://www.w3schools.com/sql/func_avg.asp"&gt;função agregada de média, AVG&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Não vou descrever como eu fiz para &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GSQL_esql#GSQL_C10281"&gt;iterar na consulta com cursor&lt;/a&gt;, e calcular a média, até porque isso é relativamente fácil, e eu já estou muito cansado hoje.&lt;br /&gt;&lt;br /&gt;Fui.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1572341047138834109?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1572341047138834109/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1572341047138834109&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1572341047138834109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1572341047138834109'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/10/falta-que-um-rownum-faz.html' title='A falta que um ROWNUM faz...'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1551784709527686131</id><published>2007-10-26T11:38:00.000-07:00</published><updated>2007-10-26T11:45:55.018-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><title type='text'>Executando código dinamicamente no Caché</title><content type='html'>&lt;i&gt;...Ou Como avaliar e executar uma expressão entrada pelo usuário.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;O cenário: na aplicação, o usuário pode cadastrar algumas fórmulas, fórmulas que podem conter algumas variáveis previamente cadastradas. Essas variáveis podem conter valores simples, ou ainda, podem ser dependentes de um parâmetro. Um exemplo de fórmula encontrada é a seguinte:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(0.50 * ([VAR1(I)] / [VAR1(0)])) + (0.50 * [VAR2])&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;onde: &lt;br /&gt;&lt;ul&gt;&lt;li&gt; VAR1(I) é uma variável, cujo valor depende do parâmetro "I".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;VAR1(0) é uma variável, cujo valor depende do parâmetro "0".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;VAR2 é a variável simples.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Notem que por convenção, na fórmula, as variáveis estão entre colchetes []. Muitas variáveis são na verdade, séries históricas com valores. Os parâmetros para elas refletem apenas qual a época/data que o valor deve ser considerado. &lt;br /&gt;&lt;br /&gt;O problema: dado um intervalo de tempo, preciso saber do valor da fórmula. Ou seja, preciso executar a fórmula, como se fosse parte do programa, ou então fazer o parsing, etc. Em algumas outras linguagens de script, existe a função &lt;b&gt;eval()&lt;/b&gt;, que converte um texto (ou seja, uma string) em código, executando-o. Em &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS"&gt;Caché Object Script&lt;/a&gt;, temos o comando &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_cxecute"&gt;XECUTE&lt;/a&gt;, que executa o conteúdo de uma String como se fosse código, ou seja, efetua &lt;b&gt;macro substituição&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Mesmo com essa facilidade, ainda assim precisava identificar dentro da %String cada variável. Para isso, escrevi uma pequena função, que coloquei num arquivo .MAC, para ser usada. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RyI1uVs1_SI/AAAAAAAAAQI/FXzpINyYqJU/s1600-h/formula_expressao.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RyI1uVs1_SI/AAAAAAAAAQI/FXzpINyYqJU/s400/formula_expressao.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5125718396116532514" /&gt;&lt;/a&gt; (A função, o &lt;a href="http://eeyamane.googlepages.com/VARCELNOVAEXPRESSAO.txt"&gt;código-fonte está aqui&lt;/a&gt;.)&lt;br /&gt;&lt;br /&gt;Para essa função, passamos a fórmula, bem como caracteres que delimitarão o que será considerado variável, tb passamos uma String que será colocada no lugar da variável na fórmula original, bem como um caracter delimitador (coisa muito usada em sistemas &lt;a href="http://en.wikipedia.org/wiki/MUMPS"&gt;MUMPS-like&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;O resultado da função é a fórmula, com as variáveis substituídas pela String, além de todas as variáveis encontradas, separadas na String pelo caracter delimitador. Usando como String de substituição "?", e como caracter delimitador "~", a função para fórmula do exemplo acima retorna: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;(0.50 * (? / ?)) + (0.50 * ?)~VAR1(I)~VAR1(0)~VAR2&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Em seguida, resolvemos o valor de cada variável, e substituimos na fórmula, e retiramos da String as variáveis. Não vou ilustrar esses passos aqui, pois são bem específicos para o modelo de dados. Neste momento, nossa String da fórmula tem algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(0.50 * (12.3 / 10.88)) + (0.50 * 10)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note que a sentença é matematicamente bem formada, e inclusive a precedência de operadores é bem explícita com o uso de parênteses, o que deve ser sempre feito, visto que o &lt;a href="http://a-casa-caiu.blogspot.com/2007/06/operadores.html"&gt;Caché não segue o padrão matemático quanto a precedência de operadores&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bem, finalmente vamos executar a expressão. Primeiro, atribuimos o comando &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_cset"&gt;SET&lt;/a&gt; dentro de uma String, como por exemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SET umaVariavel = "SET resultado = " _ stringComFormula&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Depois fazemos o XECUTE:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;XECUTE umaVariavel&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E pronto! O valor da expressão está na variável "resultado"! Apenas tenham precaução ao usar o comando XECUTE, pois dependendo da situação (e do abuso), ele pode deixar o seu código muito ruim para manutenção.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1551784709527686131?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1551784709527686131/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1551784709527686131&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1551784709527686131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1551784709527686131'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/10/executando-cdigo-dinamicamente-no-cach.html' title='Executando código dinamicamente no Caché'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0AukCty4MP0/RyI1uVs1_SI/AAAAAAAAAQI/FXzpINyYqJU/s72-c/formula_expressao.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-7195519357100302784</id><published>2007-10-11T10:32:00.000-07:00</published><updated>2007-10-11T10:42:56.633-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><title type='text'>Fazendo upload de arquivos com Caché &amp; CSP</title><content type='html'>&lt;b&gt;Fazendo upload de arquivos com Caché &amp; CSP - ou... Meu primeiro CSP&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Como já mencionei por aqui (ou não), trabalho primariamente com o &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble da Intersystems&lt;/a&gt; (e consequentemente com o &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;, já que o &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; é construído sobre este). Portanto, praticamente não mexo com coisas que envolvam interface de usuário, mas essa semana precisei fazer uma página que desse um upload num arquivo para o servidor. Então, toca a aprender &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GCSP_intro"&gt;CSP, as famigeradas Caché Server Pages&lt;/a&gt;. Na verdade, aprender eu não aprendi não, só vi o necessário para os meus propósitos.&lt;br /&gt;&lt;br /&gt;Como diz na página de introdução ao CSP, você pode ir por dois caminhos: escrever páginas &lt;a href="http://pt.wikipedia.org/wiki/HTML"&gt;html&lt;/a&gt; e imbutir tags dentro, da mesma maneira que &lt;a href="http://java.sun.com/products/jsp/"&gt;JSP (Java Server Pages)&lt;/a&gt; ou PHP, gerando um arquivo .csp; ou escrever uma classe, e nesta classe você jogar outputs montado o html, a mesma abordagem dos &lt;a href="http://java.sun.com/products/servlet/index.jsp"&gt;Servlets&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Na parte de exemplos (namespace SAMPLES do Caché) já tinha um arquivo .csp com um exemplo de upload (adivinhe qual arquivo: csp/samples/upload.csp). Com base nesse arquivo, preparei o meu.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/Rw5ef37eXOI/AAAAAAAAANI/25aGtJ3NM78/s1600-h/upload_csp.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/Rw5ef37eXOI/AAAAAAAAANI/25aGtJ3NM78/s400/upload_csp.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5120133728049192162" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/Rw5fHn7eXPI/AAAAAAAAANQ/m7i4SAdAmfo/s1600-h/upload_csp_result.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/Rw5fHn7eXPI/AAAAAAAAANQ/m7i4SAdAmfo/s400/upload_csp_result.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5120134410948992242" /&gt;&lt;/a&gt;&lt;br /&gt;(Exemplo da página de upload em SAMPLES, e o resultado de um upload)&lt;br /&gt;&lt;br /&gt;Bem, como não consegui colocar o código fonte de maneira legal no blogger, vou colocar uma figura, e deixar um link para o &lt;a href="http://br.geocities.com/thewandererbr/post_csp_source.txt"&gt;codigo fonte&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/Rw5fhH7eXQI/AAAAAAAAANY/ltaq0dMGvTc/s1600-h/my_csp_upload_source.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/Rw5fhH7eXQI/AAAAAAAAANY/ltaq0dMGvTc/s400/my_csp_upload_source.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5120134849035656450" /&gt;&lt;/a&gt;&lt;br /&gt;(Figura com o codigo fonte)&lt;br /&gt;&lt;br /&gt;A idéia principal desta página pode ser resumida assim: ao chamar a página, verifica se o parâmetro 'campo' foi enviado, se não foi, nem precisa mostrar nada. Verifica se foi enviado para o csp um arquivo, se não foi, coloca um form html para dar o upload (sendo que o submit deste form vai para o próprio csp), e se já foi efetuado um upload, atribui o nome do arquivo a um campo do html que chamou este csp (este csp deve ter sido aberto de outra página), e exibe um link para fechar a janela.&lt;br /&gt;&lt;br /&gt;A seguir, vamos detalhar alguns aspectos.&lt;br /&gt;&lt;br /&gt;Como diria o retalhador, vamos por partes:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;CSP:CLASS INCLUDES="SOMEINCFILETOINCLUDE"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Aqui indicamos um arquivo .INC (omitindo a extensão) que vamos referenciar no código, ou seja, estamos importando o INC. Arquivos .INC no Caché geralmente são usados para definição de macros (estilo macros C/C++), tanto para código quanto para definição de constantes.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;csp:if condition='($data(%request.Data("campo",1)))'&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Aqui temos uma tag específica do csp, que determina uma condição, o famoso 'if'. A condição como é vista como o valor do atributo 'condition', da tag csp:if, e pode conter código &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_intro"&gt;COS (Caché Object Script)&lt;/a&gt;, retornando verdadeiro ou falso. Neste caso, apenas estamos checando se a requisição http (objeto %request) contém um parâmetro de nome 'campo'. Mais informações sobre o objeto %request pode ser visto na página da &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25CSP.Request"&gt;classe %CSP.Request&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;csp:if condition='($data(%request.MimeData("FileStream",1)))'&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Outra vez um if, mas desta vez, se repararmos, não verificamos o parâmetro da requisição http com %request.Data, mas com %request.MimeData. Isso porque desta vez estamos checando se foi enviado um arquivo, usando o padrão &lt;a href="http://pt.wikipedia.org/wiki/MIME"&gt;MIME&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;      Arquivo enviado: &amp;lt;b&amp;gt;#(%request.MimeData("FileStream",1).FileName)#&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;      Tamanho: &amp;lt;b&amp;gt;#(%request.MimeData("FileStream",1).Size)#&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;      Tipo: &amp;lt;b&amp;gt;#(%request.MimeData("FileStream",1).ContentType)#&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Quando enviamos um arquivo, o %request.MimeData("NOMEPARAMETRO",1) retorna um objeto &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25CSP.BinaryStream"&gt;%CSP.BinaryStream&lt;/a&gt;. No código acima, mostramos na tela, algumas informações que podem ser obtidas desta stream. Notem que os valores que serão impressos na tela, estão entre '#(' e ')#'.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;script language="Cache" runat="server"&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Aqui iniciamos um bloco de Caché Object Script que será executado no servidor, ou seja, neste bloco, se quisermos que algo apareça na tela, teremos que escrever na saída padrão, usando o comando &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_cwrite"&gt;Write&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;set dname = $$$SomeDirectory&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ainda dentro do bloco aberto acima, aqui criamos e atribuimos um valor a variável 'dname'. Este valor é uma macro, indicada pelos três cifrados ($$$). Esta macro deverá estar definida em algum dos arquivos .INC, que como vimos anteriormente, podem ser importados para este CSP.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;   Set stream=##class(%FileBinaryStream).%New()&lt;br /&gt;   Set stream.Filename= dname _ fname&lt;br /&gt;&lt;br /&gt;   do stream.CopyFrom(%request.MimeData("FileStream",1))&lt;br /&gt;   do stream.Flush()&lt;br /&gt;   do stream.SaveStream()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Aqui criamos um stream para um arquivo (classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25Library.FileBinaryStream"&gt;%FileBinaryStream&lt;/a&gt;), na variável 'stream', setamos o nome e caminho completo deste, e depois usamos o método CopyFrom, para copiar o conteúdo da stream que foi enviada via http, para o arquivo.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;csp:else&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Aqui fechamos a parte 'então' do if, e colocamos a parte 'senão'.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;form enctype="multipart/form-data" method="post" action="este_arquivo_csp.csp"&amp;gt;&lt;br /&gt; Arquivo: &amp;lt;input type=file size=30 name=FileStream&amp;gt;&lt;br /&gt; &amp;lt;p&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;script language="Cache" runat="server"&amp;gt;&lt;br /&gt;    New bytes&lt;br /&gt;    Set bytes="&amp;lt;input type=""hidden"" name=""campo"" value=""" _  %request.Data("campo",1) _ """ &amp;gt; " &lt;br /&gt;    Write bytes,!&lt;br /&gt; &amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;p&amp;gt; &amp;lt;ul&amp;gt;&amp;lt;input type="submit" value="Upload file"&amp;gt;&amp;lt;/ul&amp;gt; &amp;lt;p&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;A parte do 'else' contém a definição de um formulário html, destinado a receber o arquivo que será carregado no servidor. Notem que dentro da definição do form, misturamos uma parte com código Caché, destinado a colocar um campo escondido no form, a fim de preservar o valor que fora anteriormente passado, na requisição. Essa é uma solução, outra solução seria usar sessão, mas como este caso é bem simples, não fui verificar como o gerenciamento de sessão é realizado com os CSPs.&lt;br /&gt;&lt;br /&gt;/***********************************&lt;br /&gt;&lt;br /&gt;Bem, esse post já ficou maior do que o esperado, então terminamos por aqui. No arquivo csp existem outras funcionalidades, mas não vou comentá-las agora, tais como a parte de javascript, e as funções de diretórios do COS. E tb tirei toda a formatação, sendo um html bem simples. Além disso, como suprimi várias partes, pode ser que o csp não compile de primeira, já que eu não testei ele nessa versão 'mais light'.&lt;br /&gt;&lt;br /&gt;Como já dizia o Pernalonga, por hoje é só, pessoal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-7195519357100302784?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/7195519357100302784/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=7195519357100302784&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/7195519357100302784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/7195519357100302784'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/10/fazendo-upload-de-arquivos-com-cach-csp.html' title='Fazendo upload de arquivos com Caché &amp; CSP'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/Rw5ef37eXOI/AAAAAAAAANI/25aGtJ3NM78/s72-c/upload_csp.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6911581812865718403</id><published>2007-10-05T10:25:00.000-07:00</published><updated>2007-10-05T12:52:54.696-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><category scheme='http://www.blogger.com/atom/ns#' term='curioso'/><title type='text'>Curiosidades do Caché</title><content type='html'>Tipagem fraca (bem, seria melhor dizer inexistente) do &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché da Intersystems&lt;/a&gt; as vezes produz alguns resultados curiosos, especialmente se o leitor estiver mais acostumado com matemática do que com "as coisas" que existem em TI.&lt;br /&gt;&lt;br /&gt;Por exemplo, num &lt;a href="http://docs.intersystems.com/cache52/csp/docbook/DocBook.UI.Page.cls?KEY=GIOD_termio"&gt;terminal Caché&lt;/a&gt;, declaramos duas variáveis*:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;USER&gt;set x = "5.10"&lt;br /&gt;&lt;br /&gt;USER&gt;set y = "5.1"&lt;br /&gt;&lt;br /&gt;USER&gt;write x&lt;br /&gt;5.10&lt;br /&gt;USER&gt;write y&lt;br /&gt;5.1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Lembrando que no &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt; (assim como no bom e velho C) o 1 (um) representa verdadeiro, e 0 (zero) representa falso, e o separador padrão de casas decimais é o ponto ".", vemos o resultado de algumas comparações*:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;USER&gt;write x = y&lt;br /&gt;0&lt;br /&gt;USER&gt;write x &gt; y&lt;br /&gt;0&lt;br /&gt;USER&gt;write x &gt;= y&lt;br /&gt;1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Ou seja, (x = y) é falso, (x &gt; y) tb é falso, mas (x &gt;= y) é verdadeiro. Em bom português, "x" não é igual a "y", "x" também não é maior que "y", mas "x" é maior ou igual a "y", huhuhuhu. 8-)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/RwaVh37eXNI/AAAAAAAAANA/U5fQUgBUMqs/s1600-h/cache_terminal.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/RwaVh37eXNI/AAAAAAAAANA/U5fQUgBUMqs/s400/cache_terminal.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5117942435734772946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bem, vamos as explicações:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A primeira sentença (x = y) é falsa, pois neste caso, o Caché testa a igualdade das Strings, e a String "5.10" é diferente da String "5.1".&lt;br /&gt;&lt;br /&gt;&lt;li&gt;A segunda sentença (x &gt; y) é falsa, mas não porque o Caché compara tamanhos de Strings (x &lt; y também retorna falso), mas porque ao se usar o operador "&gt;", o Caché dinamicamente converte os valores para numéricos, e como "x" NÃO É MAIOR que "y" (numericamente, "x" É IGUAL a "y", já que 5,1 = 5,10), temos o resultado falso.&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Agora já dá pra entender porque (x &gt;= y) retorna verdadeiro, não? Ao usar operadores "&lt;", "&lt;=", "&gt;", "&gt;=", o Caché tenta converter as variáveis para tipos numéricos, e como numericamente (lembrando que no Caché o separador decimal é o ponto ".") "5.1" É IGUAL a "5.10", a expressão (x &gt;= y) é verdadeira.&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Hehehe, não mostrem isso para não iniciados, isso deve confundir pra caramba, assim como a &lt;a href="http://a-casa-caiu.blogspot.com/2007/06/operadores.html"&gt;precedência de operadores no Caché&lt;/a&gt;, que eu já comentei.&lt;br /&gt;&lt;br /&gt;* A saber: o comando "set" é usado para inicializar/atribuir um valor a uma variável, e o comando "write" escreve na saída padrão (no caso, o próprio terminal) um valor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6911581812865718403?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6911581812865718403/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6911581812865718403&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6911581812865718403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6911581812865718403'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/10/curiosidades-do-cach.html' title='Curiosidades do Caché'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/RwaVh37eXNI/AAAAAAAAANA/U5fQUgBUMqs/s72-c/cache_terminal.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3266646644059162207</id><published>2007-09-28T06:21:00.000-07:00</published><updated>2007-09-28T06:22:46.189-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pesquisa'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><title type='text'>Ensemble melhor software de integração do mercado? Não exatamente...</title><content type='html'>Outro dia estava pesquisando algo no &lt;a href="http://www.google.com"&gt;Big G&lt;/a&gt; (não lembro exatamente o quê), e me deparo com essa notícia: &lt;a href="http://www.linhadecodigo.com.br/noticias.asp?id_noticia=505&amp;sub=58"&gt;Pesquisa reconhece Ensemble como o melhor software de integração do mercado&lt;/a&gt;. Fiquei atônito! Não que o &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; seja de todo ruim, mas o fato é que ele está muuuuuito longe do que eu gostaria (OK, ele tem partes realmente horríveis).&lt;br /&gt;&lt;br /&gt;Segui o link, e lendo a página, descubro que como muitas chamadas de imprensa, essa aí tb é no mínimo incompleta. Vamos aos fatos: Realmente, uma pesquisa de mercado apontou isso. Entretanto, faltou mencionar que esse 'mercado' é bem restrito, mais especificamente o mercado de empresas de TI ligadas a saúde (Healthcare IT), nos States. Nada de mal nisso, mas a chamada ficou meio apelativa, já que a expressão 'do mercado' remete a uma idéia muito mais ampla.&lt;br /&gt;&lt;br /&gt;A empresa que fez a pesquisa é a &lt;a href="http://www.healthcomputing.com/"&gt;KLAS&lt;/a&gt;, empresa "especializada em monitoramento e relatórios de performance de vendedores e empresas de serviços profissionais de TI voltadas a área de saúde" (tradução livre que consta no relatório). A pesquisa propriamente dita não está disponível completa (pelo menos não gratuitamente no site), mas um pequeno "trailer" dela vc pode baixar &lt;a href="http://www.healthcomputing.com/Klas/Site/Store/ReportDetail.aspx?ProductID=394"&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O resultado dessa pesquisa nem me surpreendeu muito (depois de eu ler a página). O &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt; (e por tabela, o &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt;, que é construído sobre este) é muito forte na área médica (TI em hospitais, etc) nos EUA, graças a herança do MUMPS. Apesar da Intersystems não gostar muito, o Caché é uma implementação do &lt;a href="http://en.wikipedia.org/wiki/MUMPS_%28programming_language%29"&gt;MUMPS&lt;/a&gt;, algo que por questões de marketing eu acho (e não sei porquê), eles não gostam de alardear por aí.&lt;br /&gt;&lt;br /&gt;Na minha opinião, se fosse realmente uma pesquisa no mercado geral, o Ensemble não se sairia muito bem. Não tenho dados que confirmem isso, então se algum leitor que porventura tenha caído aqui souber de dados confiáveis, me avise! (por favor, sem aqueles 'white papers' da própria empresa, que o pessoal de marketing deve elaborar).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3266646644059162207?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3266646644059162207/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3266646644059162207&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3266646644059162207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3266646644059162207'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/ensemble-melhor-software-de-integrao-do.html' title='Ensemble melhor software de integração do mercado? Não exatamente...'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5520758346093280896</id><published>2007-09-21T06:49:00.000-07:00</published><updated>2007-09-21T06:53:04.705-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='celesc'/><category scheme='http://www.blogger.com/atom/ns#' term='paralisação'/><title type='text'>Paralisação na Celesc - Tempo</title><content type='html'>Depois da ameaça (e efetiva paralisação hoje de manhã), a diretoria e o presidente Pinho Moreira (da &lt;a href="http://www.celesc.com.br"&gt;Celesc&lt;/a&gt;)se sentaram para negociar. Por isso, a paralisação terminou. Vamos ver se não acontece mais nenhum perrengue, que obrigue a chegar a esse ponto (ou pontos mais fundos ainda).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5520758346093280896?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5520758346093280896/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5520758346093280896&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5520758346093280896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5520758346093280896'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/paralisao-na-celesc-tempo.html' title='Paralisação na Celesc - Tempo'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6076953684446746483</id><published>2007-09-20T17:57:00.000-07:00</published><updated>2007-09-20T18:07:24.993-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='celesc'/><category scheme='http://www.blogger.com/atom/ns#' term='paralisação'/><title type='text'>Paralisação na Celesc - Prólogo</title><content type='html'>Como já disse, trabalho na &lt;a href="http://www.celesc.com.br"&gt;Celesc&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Bem, amanhã (dia 21/09) talvez haja uma paralisação, em decorrência da diretoria ficar enrolando (e pior, ficar enrolando de uma maneira que diz: "vamos te enrolar pq vcs são trouxas"), alguns assuntos pro acordo coletivo de trabalho.&lt;br /&gt;&lt;br /&gt;Não sei se vou aderir, afinal, não pretendo continuar por muito tempo na empresa, e não quero ficar tendo dor de cabeça por causa de outras pessoas, muitas delas, mesmo tendo interesse no assunto, vão ficar só esperando pelos outros. (Isso sim é ser brasileiro: eu sou brasileiro e não desisto nunca. Não desisto de esperar alguém fazer por mim...)&lt;br /&gt;&lt;br /&gt;Se ainda não notou, já perdi as esperanças nessa humanidade...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6076953684446746483?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6076953684446746483/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6076953684446746483&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6076953684446746483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6076953684446746483'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/paralisao-na-celesc-prlogo.html' title='Paralisação na Celesc - Prólogo'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-9214159077404072916</id><published>2007-09-04T07:09:00.000-07:00</published><updated>2007-09-04T07:13:40.071-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='soap'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Web Services no Caché/Ensemble - A Saga - parte 3</title><content type='html'>Finalizando a trilogia...&lt;br /&gt;&lt;br /&gt;Como havia dito no fim do post &lt;a href="http://a-casa-caiu.blogspot.com/2007/09/web-services-no-cachensemble-saga-parte_03.html"&gt;parte 2&lt;/a&gt;, escrevendo o &lt;a href="http://www.w3schools.com/soap/soap_body.asp"&gt;SOAP-Body&lt;/a&gt; na mão, eu consegui que fosse enviada a mensagem de requisição corretamente para o Web Service. Entretanto, por algum motivo que desconhecia, a mensagem de resposta não estava chegando corretamente. Primeiro pensei que não havia funcionado, mas depois analisando o tráfego da máquina, olhando a stream TCP, vi que o serviço estava retornando corretamente. O problema é que o &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; não entendia a resposta.&lt;br /&gt;&lt;br /&gt;Testei com as classes cliente geradas automaticamente, e mesmo eu não mudando uma vírgula, o erro continuava. Conclusão: de nada adiantara toda a minha ginástica até agora. Analisando o código fonte, e pelas poucas pistas que o erro retornava, cheguei a conclusão de que o Caché não estava conseguindo instanciar uma classe com base na mensagem de resposta do Web Service:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1nVQTICFI/AAAAAAAAAKY/PZ7vcbpoKWM/s1600-h/06resposta.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1nVQTICFI/AAAAAAAAAKY/PZ7vcbpoKWM/s400/06resposta.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106351167358109778" /&gt;&lt;/a&gt;&lt;br /&gt;(exemplo de uma resposta a uma requisição bem sucedida)&lt;br /&gt;&lt;br /&gt;A esta altura, já cansado de tanto fuçar tanto a documentação quanto o código fonte das classes do pacote %SOAP do Caché, parti para o baixo nível: já que o pacote %SOAP não conseguia entender o Web Service, então desci na pilha de protocolos pra implementar de uma maneira que desse certo. O Caché puro não tem classes para lidar direto com o &lt;a href="http://pt.wikipedia.org/wiki/HTTP"&gt;HTTP&lt;/a&gt; (pelo menos eu não achei), mas o Ensemble tem um "Adapter" HTTP. Lá vou fazer testes com ele, e descubro que não consigo usar no Web Service específico, porque esse Adapter não me deixa setar no cabeçalho um campo, e o serviço exige que contenha no cabeçalho da requisição HTTP o campo SOAPAction.&lt;br /&gt;&lt;br /&gt;(Um parêntese: Adapters na linguagem do Ensemble são pedaços de softwares que têm a função de conectar o Ensemble a outros sistemas/tecnologias. A documentação desses Adapters deixa muuuito a desejar, pra ter uma idéia, na &lt;a href="http://www.intersystems.com/ensemble/technology/adapter/index.html"&gt;página que lista os Adapters&lt;/a&gt; nem está listada o Adapter HTTP, e muitos dos Adapters ali listados não consta do que eu tenho aqui disponível. Estranho, muito estranho)&lt;br /&gt;&lt;br /&gt;Não conseguindo usar o HTTP, resolvi descer mais um nível na pilha, e usar direto o TCP. O Adapter TCP do Ensemble nada mais é do que um "wrapper" para os Sockets do Caché, um assunto que eu já dei um pitáculo neste dois posts anteriores &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/sockets-em-cach.html"&gt;aqui&lt;/a&gt; e &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/ainda-sockets-em-cach-serversockets.html"&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1noQTICGI/AAAAAAAAAKg/LCxZbocAi0Q/s1600-h/07protocolos.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1noQTICGI/AAAAAAAAAKg/LCxZbocAi0Q/s400/07protocolos.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106351493775624290" /&gt;&lt;/a&gt;&lt;br /&gt;(pilha de protocolos... quase que chego no IP =P )&lt;br /&gt;&lt;br /&gt;O bom de usar TCP é que eu tenho o controle de tudo, dos cabeçalhos do HTTP, do conteúdo da mensagem XML SOAP, etc. O ruim é que você pra usar isso, além de entender boa parte de toda essa parafernália, tem que fazer tudo no braço. Mas como as ferramentas prontas do Caché/Ensemble estavam só me dando erro, não tive muita escolha. XD&lt;br /&gt;&lt;br /&gt;Olhem como ficou (mais ou menos, aqui tá simplificado):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/Rt1n4ATICHI/AAAAAAAAAKo/FvoVF4jwT1A/s1600-h/08snippet.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/Rt1n4ATICHI/AAAAAAAAAKo/FvoVF4jwT1A/s400/08snippet.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106351764358563954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;E assim, apesar de ficar com um código horrível, usando mais anti-patterns possível, finalmente funcionou. E com tudo isso chamam o Ensemble de "Integrador"... Imagina se não fosse...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-9214159077404072916?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/9214159077404072916/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=9214159077404072916&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9214159077404072916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9214159077404072916'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/web-services-no-cachensemble-saga-parte_04.html' title='Web Services no Caché/Ensemble - A Saga - parte 3'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0AukCty4MP0/Rt1nVQTICFI/AAAAAAAAAKY/PZ7vcbpoKWM/s72-c/06resposta.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-4862143516877835704</id><published>2007-09-03T12:19:00.000-07:00</published><updated>2007-09-03T12:42:06.165-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='soap'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Web Services no Caché/Ensemble - A Saga - parte 2</title><content type='html'>Continuando a saga...&lt;br /&gt;&lt;br /&gt;Eu havia me baseado na versão anterior do Web Service/Wsdl que me foi passado, pra implementar todas as estruturas internas no &lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; (a saber, o &lt;a href="http://en.wikipedia.org/wiki/BPEL"&gt;BPEL&lt;/a&gt; e as "Business Operations", na linguagem deste).&lt;br /&gt;&lt;br /&gt;Bem, na versão anterior, o wizard gerava todas as estruturas como classes, ou seja, se eu tivesse que atualizar uma estrutura "Pessoa", eu teria uma classe "Pessoa" com as propriedades "Nome", "Idade", etc... e o método receberia uma instância desta classe. Entretanto, agora o wizard gerou o método recebendo cada propriedade da estrutura como um parâmetro, ou seja, antes eu tinha:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;atualizaPessoa(p as Pessoa)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E agora ele me gerou:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;atualizaPessoa(nome as %String, idade as %Integer, ...)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E é CLARO que isso quebrou tudo o que eu havia feito. Para não ter que retrabalhar todas as outras classe, resolvi que seria melhor alterar na mão as classes que o wizard havia gerado, para se adaptarem aos objetos com que eu já trabalhava.&lt;br /&gt;&lt;br /&gt;Então lá fui eu alterar a classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25SOAP.WebClient"&gt;Web Client&lt;/a&gt; gerada:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/Rtxi0ATIB7I/AAAAAAAAAJM/mxh3XAluyLk/s1600-h/03antes.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/Rtxi0ATIB7I/AAAAAAAAAJM/mxh3XAluyLk/s400/03antes.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106064723104237490" /&gt;&lt;/a&gt;&lt;br /&gt;(antes)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RtxjIATIB8I/AAAAAAAAAJU/IJLWlaRguTo/s1600-h/04depois.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RtxjIATIB8I/AAAAAAAAAJU/IJLWlaRguTo/s400/04depois.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106065066701621186" /&gt;&lt;/a&gt;&lt;br /&gt;(depois)&lt;br /&gt;&lt;br /&gt;Pensei que só isso já bastaria para funcionar. Compilei e mandei rodar. Não funcionou... Resumindo a luta, descobri que desse modo ele não estava escrevendo o &lt;a href="http://www.w3schools.com/soap/soap_body.asp"&gt;Body&lt;/a&gt; do &lt;a href="http://www.w3schools.com/soap/soap_envelope.asp"&gt;envelope SOAP&lt;/a&gt; conforme o Web Service esperava, contendo os &lt;a href="http://www.w3schools.com/xml/xml_namespaces.asp"&gt;namespaces&lt;/a&gt; corretamente declarados. &lt;br /&gt;&lt;br /&gt;Procurando uma solução, me deparei com a propriedade "WriteSOAPBodyMethod" da classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25SOAP.WebBase"&gt;%SOAP.WebBase&lt;/a&gt;, que é superclasse de &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25SOAP.WebClient"&gt;%SOAP.WebClient&lt;/a&gt;. Essa propriedade permite definir um método que escreva de maneira personalizada o body de uma mensagem SOAP.&lt;br /&gt;&lt;br /&gt;Usando essa propriedade, temos:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RtxjVATIB9I/AAAAAAAAAJc/bfLD9t6VO-s/s1600-h/05writebody.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RtxjVATIB9I/AAAAAAAAAJc/bfLD9t6VO-s/s400/05writebody.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106065290039920594" /&gt;&lt;/a&gt;&lt;br /&gt;(escrevendo um elemento SOAP-Body personalizado)&lt;br /&gt;&lt;br /&gt;Com isso, finalmente consegui preservar todo o código que eu havia feito anteriormente, e ainda acionava corretamente o Web Service. Entretanto, a saga não acaba aqui...&lt;br /&gt;&lt;br /&gt;Continua...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-4862143516877835704?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/4862143516877835704/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=4862143516877835704&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/4862143516877835704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/4862143516877835704'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/web-services-no-cachensemble-saga-parte_03.html' title='Web Services no Caché/Ensemble - A Saga - parte 2'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0AukCty4MP0/Rtxi0ATIB7I/AAAAAAAAAJM/mxh3XAluyLk/s72-c/03antes.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3664449976408270664</id><published>2007-09-03T11:24:00.000-07:00</published><updated>2007-09-03T11:29:02.027-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='soap'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Web Services no Caché/Ensemble - A Saga - parte 1</title><content type='html'>Há um tempo atrás postei um pequeno elogio ao &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt; no que concerne a suporte a &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/cach-e-xml.html"&gt;Xml&lt;/a&gt;. Seguindo o pensamento, poderíamos crer que o suporte a &lt;a href="http://pt.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt; e &lt;a href="http://pt.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt; seria igualmente bom. Infelizmente, acabei encontrando problemas por aí. Neste post estou começando uma série, que deve ilustrar toda uma saga XD.&lt;br /&gt;&lt;br /&gt;Inicialmente, eu tinha um &lt;a href="http://pt.wikipedia.org/wiki/WSDL"&gt;Wsdl&lt;/a&gt; descrevendo alguns serviços de um software que a Celesc comprou, e que precisaríamos usar para integrar com os nossos sistemas (a saga para conseguir esse Web Service tb é longa, mas muito chata, não devo postá-la aqui).&lt;br /&gt;&lt;br /&gt;Bem, já tendo realizado alguns testes criando clientes para outros Web Services, pensei: "moleza". Ledo engano. O Wizard que gera um cliente SOAP de cara me jogou um erro. Infelizmente, como pode-se ver no print screen abaixo, o Caché/Ensemble não é muito informativo, então fiquei na dúvida: será que me enviaram um Wsdl bixado, ou o Caché não entende certas coisas? (Neste ponto, ambas as hipóteses eram igualmente prováveis).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/RtxRmgTIB5I/AAAAAAAAAI8/QBf4JrIAq9E/s1600-h/01pepino.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/RtxRmgTIB5I/AAAAAAAAAI8/QBf4JrIAq9E/s400/01pepino.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5106045799478331282" /&gt;&lt;/a&gt;&lt;br /&gt;(Tela com o erro do wizard)&lt;br /&gt;&lt;br /&gt;Resolvi testar o Web Service utilizando o &lt;a href="http://www.soapui.org/"&gt;soapUI&lt;/a&gt;, um programa feito em Java, muito bom, que permite vc testar Web Services. Eu falei dele no &lt;a href="http://a-casa-caiu.blogspot.com/2007/09/hoje-vou-falar-sobre-um-programa-muito.html"&gt;post anterior&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Usando o soapUI, eu consegui não só montar o esqueleto correto das mensagens SOAP, como também testar o serviço. Isso me levou a conclusão de que havia alguma coisa errada com o wizard do Caché. Mas como curioso que eu sou, fui procurar o que nesse Wsdl específico estava causando erro. Depois de perdido meio dia, comparando Wsdls, e fuçando nas especificações, finalmente encontrei o problema: a mensagem de requisição estava com dois elementos, quando o normal é ter apenas um:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_0AukCty4MP0/RtxSJATIB6I/AAAAAAAAAJE/o2y3D_l3rV4/s1600-h/02xml.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_0AukCty4MP0/RtxSJATIB6I/AAAAAAAAAJE/o2y3D_l3rV4/s400/02xml.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5106046392183818146" /&gt;&lt;/a&gt;&lt;br /&gt;(pedaço do Wsdl que estava me causando problema)&lt;br /&gt;&lt;br /&gt;Comentando a tag do segundo elemento da mensagem, o wizard funcionou. Um alívio que durou pouco...&lt;br /&gt;&lt;br /&gt;Numa versão antiga deste Web Service (que haviam me passado anteriormente), o wizard havia funcionado corretamente, e eu havia baseado a implementação toda nele. Claro que agora haviam algumas mudanças, mas achei que não era muitas. Eu estava totalmente errado...&lt;br /&gt;&lt;br /&gt;Continua...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3664449976408270664?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3664449976408270664/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3664449976408270664&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3664449976408270664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3664449976408270664'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/web-services-no-cachensemble-saga-parte.html' title='Web Services no Caché/Ensemble - A Saga - parte 1'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0AukCty4MP0/RtxRmgTIB5I/AAAAAAAAAI8/QBf4JrIAq9E/s72-c/01pepino.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-1293815114943803170</id><published>2007-09-03T10:37:00.000-07:00</published><updated>2007-09-04T05:16:40.290-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webservice'/><category scheme='http://www.blogger.com/atom/ns#' term='soap'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='soapUI'/><category scheme='http://www.blogger.com/atom/ns#' term='testes'/><title type='text'>SoapUI</title><content type='html'>Hoje vou falar sobre um programa muito útil que eu uso aqui, especialmente quando se trata de testar &lt;a href="http://pt.wikipedia.org/wiki/Web_service"&gt;Web Services&lt;/a&gt; &lt;a href="http://pt.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt;. O programa se chama &lt;a href="http://www.soapui.org/"&gt;soapUI&lt;/a&gt;, e é open-source, mas com uma opção paga com suporte. A instalação desse programa é simples, e está bem documentada no &lt;a href="http://www.soapui.org/gettingstarted/index.html"&gt;site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Depois de instalado, primeiramente criamos um projeto, (File -&gt; New WSDL Project). Este projeto pode conter quantas referências a web services você quiser, é mais uma maneira de se organizar logicamente do que uma imposição.&lt;br /&gt;&lt;br /&gt;Suponhamos que eu tenha criado um projeto chamado 'zzz'. Para adicionar um Wsdl, basta clicar com o botão direito em cima do projeto, e ir na opção de adicionar um Wsdl de uma &lt;a href="http://pt.wikipedia.org/wiki/URL"&gt;Url&lt;/a&gt; ou de um arquivo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1MjQTIB-I/AAAAAAAAAJk/VhRKedzNHIE/s1600-h/soapui1.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/Rt1MjQTIB-I/AAAAAAAAAJk/VhRKedzNHIE/s400/soapui1.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106321721062328290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Responda sim a questão de criar requisições padrão para todas as operações e pronto. Basta você ir abrindo na árvore a esquerda, e vai ver as operações listadas, bem como uma requisição padrão para cada uma delas. Na figura, vemos apenas uma operação, com uma requisição (mas você pode criar várias mensagens de requisição, e deixar todas ali registradas, facilitando os seus testes):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_0AukCty4MP0/RtxHfgTIB3I/AAAAAAAAAIs/212-cWXWbMk/s1600-h/soapui2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_0AukCty4MP0/RtxHfgTIB3I/AAAAAAAAAIs/212-cWXWbMk/s400/soapui2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106034684102969202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora, basta você preencher as tags com os valores que quiser testar, e clicar no botão de submeter requisição (o botão verde), e ver na no quadro a direita, o &lt;a href="http://pt.wikipedia.org/wiki/XML"&gt;Xml&lt;/a&gt; com o resultado:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_0AukCty4MP0/RtxH8QTIB4I/AAAAAAAAAI0/4m480NhGQBE/s1600-h/soapui3.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_0AukCty4MP0/RtxH8QTIB4I/AAAAAAAAAI0/4m480NhGQBE/s400/soapui3.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5106035178024208258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Agora é só instalar aí na sua máquina e testar um pouco.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-1293815114943803170?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/1293815114943803170/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=1293815114943803170&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1293815114943803170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/1293815114943803170'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/09/hoje-vou-falar-sobre-um-programa-muito.html' title='SoapUI'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0AukCty4MP0/Rt1MjQTIB-I/AAAAAAAAAJk/VhRKedzNHIE/s72-c/soapui1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-329700310732941150</id><published>2007-08-29T09:08:00.000-07:00</published><updated>2007-08-29T09:11:39.530-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Tradutores</title><content type='html'>Eu gosto bastante do &lt;a href="http://idgnow.uol.com.br/"&gt;idgnow&lt;/a&gt;, e assino as newsletters por email deles.&lt;br /&gt;&lt;br /&gt;Mas eu realmente acho que o pessoal deve deixar de usar aqueles tradutores automáticos, ou no mínimo contratar um revisor.&lt;br /&gt;&lt;br /&gt;Olhem &lt;a href="http://idgnow.uol.com.br/seguranca/2007/08/27/idgnoticia.2007-08-27.0948660148/paginador/pagina_9"&gt;neste link&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;"Paranóia nº 8: Seu provedor de internet sabe demais&lt;br /&gt;Razão nº 8: Logaritmos detalhados de tudo que você já fez online"&lt;br /&gt;&lt;br /&gt;Logaritmos? Base 10 ou base natural? =P&lt;br /&gt;&lt;br /&gt;Trocar logs por logaritmos é dureza... Mas ninguém ter visto isso é pior.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-329700310732941150?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/329700310732941150/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=329700310732941150&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/329700310732941150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/329700310732941150'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/08/tradutores.html' title='Tradutores'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-3951487651020765770</id><published>2007-08-26T09:52:00.000-07:00</published><updated>2007-08-26T09:56:14.204-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requisitos'/><title type='text'>Requisitos</title><content type='html'>Encontrei essa imagem jogada aqui no HD.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_0AukCty4MP0/RtGwZgTIB1I/AAAAAAAAAIc/GD5_ylHfICI/s1600-h/requirements.jpeg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0AukCty4MP0/RtGwZgTIB1I/AAAAAAAAAIc/GD5_ylHfICI/s400/requirements.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5103053805000853330" /&gt;&lt;/a&gt; (Clique para aumentar)&lt;br /&gt;&lt;br /&gt;É divertido porque é verdade. Pelo menos nos últimos casos que eu tenho visto.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-3951487651020765770?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/3951487651020765770/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=3951487651020765770&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3951487651020765770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/3951487651020765770'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/08/requisitos.html' title='Requisitos'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0AukCty4MP0/RtGwZgTIB1I/AAAAAAAAAIc/GD5_ylHfICI/s72-c/requirements.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5269339368041583743</id><published>2007-08-22T04:45:00.000-07:00</published><updated>2007-08-22T04:47:05.871-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='livros'/><title type='text'>A cauda longa</title><content type='html'>Um trecho do livro '&lt;a href="http://pt.wikipedia.org/wiki/A_Cauda_Longa"&gt;A Cauda Longa&lt;/a&gt;':&lt;br /&gt;&lt;br /&gt;"Para uma geração de clientes acostumados a fazer suas pesquisas de compra por meio de softwares de busca, a marca de uma empresa não é o que a empresa diz que é, mas o que o Google diz que é."&lt;br /&gt;&lt;br /&gt;Ainda não terminei de ler o livro, mas estou achando muito interessante. Junto com '&lt;a href="http://pt.wikipedia.org/wiki/Freakonomics"&gt;Freakonomics&lt;/a&gt;', uma das minhas últimas melhores aquisições.&lt;br /&gt;&lt;br /&gt;E isso contribui para algo que eu venho afirmando para um amigo meu: 'se vc quer conquistar o mundo, vai ter que passar primeiro em cima do &lt;a href="http://www.google.com"&gt;grande G&lt;/a&gt;'. XD&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5269339368041583743?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5269339368041583743/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5269339368041583743&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5269339368041583743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5269339368041583743'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/08/cauda-longa.html' title='A cauda longa'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5619185998435457838</id><published>2007-08-13T11:42:00.000-07:00</published><updated>2007-08-13T12:25:05.541-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='algoritmo DES'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='criptografia'/><title type='text'>Criptografia em Caché/Ensemble</title><content type='html'>Há uns meses atrás, estava procurando APIs de &lt;a href="http://pt.wikipedia.org/wiki/Criptografia"&gt;criptografia&lt;/a&gt; dentro do &lt;a href="http://www.intersystems.com/cache/index.html"&gt;Caché&lt;/a&gt;/&lt;a href="http://www.intersystems.com/ensemble/index.html"&gt;Ensemble&lt;/a&gt;, pois iria implementar algum nível de segurança nos Web services (algo mais simples, nem de longe o &lt;a href="http://www.oasis-open.org/specs/#wssv1.0"&gt;WS-Security - especificação aqui&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Depois de muito procurar na ajuda online e perguntar para &lt;a href="http://www.google.com.br"&gt;o grande G&lt;/a&gt;, desisti, me dei por vencido e vi que realmente não tem nenhuma API do Caché para isso. Fato aliás, que eu achei e acho estranho, já que até o Oracle tem a sua API de criptografia. &lt;br /&gt;&lt;br /&gt;Deixando isso de lado, fui procurar uma solução. A primeira idéia foi a de usar um gateway Java. O que é isso? É nada mais nada menos do que instanciar uma máquina virtual Java de dentro do Ensemble, e poder interagir com objetos Java. Como Java tem uma boa API em se tratando de criptografia, pensei, tudo beleza... Infelizmente, essa integração JVM/Caché não foi muito feliz, sofrendo demais com bugs (que me fizeram inclusive reiniciar a máquina).&lt;br /&gt;&lt;br /&gt;Com isso, me dei por vencido. Ou esperaria alguns anos até que alguém resolvesse colocar alguma API de criptografia, ou escreveria eu mesmo. Resolvi escrever eu mesmo. &lt;br /&gt;&lt;br /&gt;A primeira decisão: qual algoritmo implementar? O esquema não era muito complexo, então já descartei de cara os algoritmos de &lt;a href="http://pt.wikipedia.org/wiki/Criptografia_de_chave_p%C3%BAblica"&gt;chave pública/privada&lt;/a&gt;. Então, qual algoritmo simétrico implementar? Como eu não ia ganhar aumento de qualquer jeito, resolvi pegar um mais fácil (mas não a ponto de ser besta quebrar, como o de &lt;a href="http://pt.wikipedia.org/wiki/Cifra_de_C%C3%A9sar"&gt;César&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Vi que realmente não tinha um muito fácil. Então, escolhi um que pelo menos tivesse um bom material disponível. Acabei escolhendo o &lt;a href="http://pt.wikipedia.org/wiki/Data_Encryption_Standard"&gt;DES&lt;/a&gt;. Não lembro de muito material de referência em português, então vou deixar aqui os links das páginas em inglês que eu usei pra entender o funcionamento e ajudar na implementação: &lt;a href="http://www.aci.net/kalliste/des.htm"&gt;The DES Algorithm Illustrated&lt;/a&gt; e &lt;a href="http://www.tropsoft.com/strongenc/des.htm"&gt;DES Encryption&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Acabou que toda a implementação ficou em 3 classes (se bem que uma delas é mais enfeite). UPDATE: Não reproduzo aqui as classes, pq elas são enormes. Se quiser, baixe o fonte &lt;a href="http://br.geocities.com/thewandererbr/DES.zip"&gt;aqui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A classe &lt;code&gt;DadosLoginBean&lt;/code&gt; é só usada como um container para o usuário/senha. &lt;br /&gt;&lt;br /&gt;A classe &lt;code&gt;Util&lt;/code&gt; contém alguns métodos específicos para o algoritmo DES, mas também possui vários que podem ser usados em outras situações, como por exemplo, conversão de Strings ASCII para hexadecimal, ou de valores para/de bitstring (que é um array especial de bits, usado pelo Caché).&lt;br /&gt;&lt;br /&gt;A classe &lt;code&gt;DESCrypto&lt;/code&gt; é a principal. Não vou entrar em pormenores da implementação, basta dizer que essa classe cifra/decifra usando o algoritmo DES, com CBC (um modificador de bloco), e padding pkcs#5, com vetor de inicialização zerado.&lt;br /&gt;&lt;br /&gt;Não se preocupe se vc não entendeu nada. Levei um bom tempo também, até entender todas essas letrinhas =P. De qualquer forma, o último método de &lt;code&gt;DESCrypto&lt;/code&gt;, o método de classe &lt;code&gt;decifraLogin&lt;/code&gt; ilustra como usar toda essa parafernália. Este método recebe como parâmetro uma mensagem criptografada (em formato hexadecimal, na primeira %String), e uma chave (tb em hexa, na segunda %String), e retorna um objeto contendo usuário e senha. O código aqui:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/// &lt;br /&gt;/// *******************************************************************&lt;br /&gt;/// &lt;br /&gt;/// Método estático para decifrar uma mensagem contendo usuario/senha.&lt;br /&gt;/// &lt;br /&gt;/// Instancia um objeto DESCrypto, seta a chave (chave padrão ou&lt;br /&gt;/// não), converte o hexadecimal retornado para caracteres ASCII,&lt;br /&gt;/// e retorna um bean com usuario e senha.&lt;br /&gt;/// &lt;br /&gt;/// Caso aconteça algum erro, retorna vazio.&lt;br /&gt;/// &lt;br /&gt;ClassMethod decifraLogin(msg As %String, chave As %String = "5C6F2F5F45793A50") As eey.security.bean.DadosLoginBean&lt;br /&gt;{&lt;br /&gt; set $ztrap = "EXCEPTION"&lt;br /&gt; &lt;br /&gt; set des = ##class(eey.security.DESCrypto).%New()&lt;br /&gt; set st = des.setKey(chave)&lt;br /&gt; if ($System.Status.IsError(st)) goto EXCEPTION&lt;br /&gt; &lt;br /&gt; set st = des.performChainCrypto(msg, .desc, "D")&lt;br /&gt; if ($System.Status.IsError(st)) goto EXCEPTION&lt;br /&gt; &lt;br /&gt; set userSenha = ##class(eey.security.Util).strHexToStringAscii(desc)&lt;br /&gt;&lt;br /&gt; if (userSenha = "") goto EXCEPTION&lt;br /&gt;&lt;br /&gt; set user = $piece(userSenha, "/")&lt;br /&gt; set pass = $piece(userSenha, "/", 2)&lt;br /&gt; &lt;br /&gt; set bean = ##class(eey.security.bean.DadosLoginBean).%New()&lt;br /&gt; set bean.usuario = user&lt;br /&gt; set bean.senha = pass&lt;br /&gt; &lt;br /&gt; kill des&lt;br /&gt; &lt;br /&gt; Quit bean&lt;br /&gt;EXCEPTION&lt;br /&gt; Quit ""&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Se interessar, dê uma espiada no código, e qualquer dúvida, deixe um comentário.&lt;br /&gt;&lt;br /&gt;P.S.: se interessar, o código acima está sob a licença &lt;a href="http://sam.zoy.org/wtfpl/"&gt;WTFPL&lt;/a&gt;. =P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5619185998435457838?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5619185998435457838/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5619185998435457838&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5619185998435457838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5619185998435457838'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/08/criptografia-em-cachensemble.html' title='Criptografia em Caché/Ensemble'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-7097184381309358570</id><published>2007-07-24T07:20:00.000-07:00</published><updated>2007-07-24T07:24:55.938-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>O parâmetro esquecido</title><content type='html'>Enquanto pesquisava o código fonte do &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;%IO.ServerSocket&lt;/a&gt; para escrever os posts anteriores (sobre &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/sockets-em-cach.html"&gt;sockets&lt;/a&gt; e &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/ainda-sockets-em-cach-serversockets.html"&gt;ServerSockets criando processos&lt;/a&gt;), me deparei com algo inusitado, para dizer o mínimo. &lt;br /&gt;&lt;br /&gt;O método &lt;code&gt;ListenJob&lt;/code&gt; da classe &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;%IO.ServerSocket&lt;/a&gt; tem como sexto parâmetro &lt;code&gt;pForeground&lt;/code&gt;, um valor booleano cujo padrão é zero (0 - falso em Caché). A documentação deste método nem menciona este parâmetro. Pelo nome do parâmetro, tem-se a idéia de que poderíamos controlar os processos filhos que o método cria, deixando que eles rodassem em background ou não, ou ainda, se o próprio método rodaria em background ou não.&lt;br /&gt;&lt;br /&gt;Bem, depois de fazer alguns testes, vi que o comportamento do método não mudava, apesar de alterar este parâmetro. Resolvi ver o código fonte da classe, e para minha surpresa, esse parâmetro NÃO É USADO EM LUGAR ALGUM. Sim, ele está lá declarado na assinatura do método, e em mais nenhum lugar.&lt;br /&gt;&lt;br /&gt;Tabajarice, pensei...&lt;br /&gt;&lt;br /&gt;Bem, resolvi dar uma chance, e verificar as possibilidades que levaram a tal fato. &lt;br /&gt;&lt;br /&gt;Primeira teoria: esta classe deveria ser usada em versões antigas, e pra manter a compatibilidade, deixaram a assinatura do jeito que estava. Status da teoria: inválida. &lt;a href="http://platinum.intersystems.com/csp/documatic/%25CSP.Documatic.cls"&gt;Aqui na documentação da versão 5.0&lt;/a&gt;, NEM EXISTE essa classe...&lt;br /&gt;&lt;br /&gt;Segunda teoria: na versão mais nova, devem usar pra alguma coisa. Status da teoria: altamente improvável. Não tenho a versão 2007.1 instalada aqui, então não tenho como ver o fonte, mas pela &lt;a href="http://docs.intersystems.com/cache20071/csp/documatic/%25CSP.Documatic.cls"&gt;documentação desta versão&lt;/a&gt;, não encontrei mudança nenhuma na &lt;a href="http://docs.intersystems.com/cache20071/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;classe&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Última teoria: alguém simplesmente esqueceu o pobre coitado do parâmetro ali, deixado sozinho e sem utilidade. Status da teoria: é a que eu aceito atualmente.&lt;br /&gt;&lt;br /&gt;Só para constar, eu uso a versão 5.2, portanto geralmente quando posto links para a documentação, é para esta versão. Assim, nos posts anteriores sobre sockets, os links todos apontam para a 5.2, apesar de que pelo menos naquelas classes, eu olhei a documentação da 2007.1 e não vi diferença.&lt;br /&gt;&lt;br /&gt;Certas coisas que eu vejo... ¬¬&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-7097184381309358570?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/7097184381309358570/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=7097184381309358570&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/7097184381309358570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/7097184381309358570'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/07/o-parmetro-esquecido.html' title='O parâmetro esquecido'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6120028476058688663</id><published>2007-07-23T11:49:00.000-07:00</published><updated>2007-07-23T11:50:34.595-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='rede'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Ainda Sockets em Caché - ServerSockets</title><content type='html'>Continuando a explorar o assunto do post passado, sobre &lt;a href="http://en.wikipedia.org/wiki/Socket"&gt;sockets&lt;/a&gt; em &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt;, vamos explorar outra possibilidade.&lt;br /&gt;&lt;br /&gt;No &lt;a href="http://a-casa-caiu.blogspot.com/2007/07/sockets-em-cach.html"&gt;post passado&lt;/a&gt;, mostrei um exemplo simples de como fazer para criar sockets, tanto do lado servidor, quanto do lado cliente. Entretanto, aquele exemplo tinha uma grande limitação: na parte do servidor, o código aceitava somente uma requisição depois encerrava. Como exemplo é válido, mas num cenário real, é muito limitador.&lt;br /&gt;&lt;br /&gt;Entretanto, o objeto &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;%IO.ServerSocket&lt;/a&gt; possui outro método, que nos permite deixar o socket servidor mais parecido com um &lt;a href="http://java.sun.com/javase/6/docs/api/java/net/ServerSocket.html"&gt;ServerSocket em java&lt;/a&gt;. Este método é o &lt;code&gt;ListenJob&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Antes de mais nada, vamos ver como fica um código simples:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Class teste.ServerSpawnSocket Extends %RegisteredObject&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;ClassMethod server()&lt;br /&gt;{&lt;br /&gt; set sock = ##class(%IO.ServerSocket).%New()&lt;br /&gt; set st = $$$OK&lt;br /&gt; &lt;br /&gt; w "Starting server...", !&lt;br /&gt; &lt;br /&gt; // open serverSocket, param:&lt;br /&gt; // port, timeOut, status&lt;br /&gt; w sock.Open(7777, -1, st), !&lt;br /&gt; w st, !&lt;br /&gt; &lt;br /&gt; // server to listen incoming connections, &lt;br /&gt; // and when it arrives, spawns a new job in background&lt;br /&gt; // params:&lt;br /&gt; // &lt;br /&gt; // timeOut, &lt;br /&gt; // classNameContainingMethodToBeCalled,&lt;br /&gt; // jobArguments,&lt;br /&gt; // socketClassName (default: %IO.ServerSocket),&lt;br /&gt; // maxNumberOfJobs (default: -1),&lt;br /&gt; // runInForeground (default: 0 - no),&lt;br /&gt; // status&lt;br /&gt; w sock.ListenJob(-1, "teste.ServerSpawnSocket", "", , , , st), !&lt;br /&gt; w st, !&lt;br /&gt;&lt;br /&gt; w "Closing server...", !&lt;br /&gt;        quit&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//===================================================&lt;br /&gt;&lt;br /&gt;ClassMethod OnConnected(StreamHandler As %IO.DeviceStream, AnotherArgs)&lt;br /&gt;{&lt;br /&gt; set st = $$$OK&lt;br /&gt;&lt;br /&gt; // reading from socket, param:&lt;br /&gt; // maxStringSize, timeout, status, lineTerminator &lt;br /&gt; set ^someVar("read from tcp") = StreamHandler.ReadLine(50, 30, st, $c(13))&lt;br /&gt;&lt;br /&gt; // writing to socket, param: &lt;br /&gt; // stringToBeWritten, automaticFlush, status&lt;br /&gt; d StreamHandler.Write("Goodbye Dolly", 1, st)&lt;br /&gt; &lt;br /&gt; d StreamHandler.Close(st)&lt;br /&gt; set ^someVar("status") = st&lt;br /&gt; &lt;br /&gt; quit&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O método &lt;code&gt;server()&lt;/code&gt; é bem simples, tendo mais linhas de comentário do que propriamente código =P. Depois de criado o objeto, chamamos novamente o método &lt;code&gt;open&lt;/code&gt; deste, definindo em que porta o socket ficará escutando. O método que mais nos interessa agora, é o seguinte, &lt;code&gt;ListenJob&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Este método executa o seguinte: ao chegar nova requisição no socket, se não houver restrição ao endereço da requisição, o método cria um novo job (processo) que rodará em background, passando como parâmetro, um objeto &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.DeviceStream"&gt;%IO.DeviceStream&lt;/a&gt;, que contém a stream (fluxo) de dados criado pelo socket. Mas qual método o Caché invoca? Bem, depois de passear pelo código-fonte do &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;%IO.ServerSocket&lt;/a&gt;, descubro que depois de invocar alguns métodos internos da própria classe, o objeto invoca o método de classe (em Java, seria um método &lt;code&gt;static&lt;/code&gt;) &lt;code&gt;OnConnected&lt;/code&gt;, da classe passada como segundo parâmetro na chamada de &lt;code&gt;ListenJob&lt;/code&gt;. &lt;br /&gt;&lt;br /&gt;O &lt;code&gt;ListenJob&lt;/code&gt; ainda pode controlar o número máximo de jobs simultâneos, que é o quinto parâmetro. O primeiro parâmetro é o conhecido timeout, que se passado -1, nunca expira. O terceiro parâmetro pode ser composto de uma lista, contendo parâmetros adicionais a serem passados para o método &lt;code&gt;OnConnected&lt;/code&gt;. O sexto parâmetro é inútil (mais sobre isso em um futuro post), e o último parâmetro é o conhecido objeto que retorna o status da execução do método.&lt;br /&gt;&lt;br /&gt;No exemplo, pode-se ver que foi passado como parâmetro o nome da própria classe, mas poderia muito bem ser outra qualquer. O importante é que a classe passada contenha o método &lt;code&gt;OnConnected&lt;/code&gt;, cuja assinatura pode ser vista no exemplo (IMPORTANTE: essa assinatura não é fixa, nem definitiva, muito menos oficial, já que na documentação não consta nada disso - pelo menos eu não achei em lugar algum, se você leitor, sabe onde está, deixe um comentário dizendo, por favor).&lt;br /&gt;&lt;br /&gt;Dentro do método &lt;code&gt;OnConnected&lt;/code&gt;, manipulamos a stream de dados como quisermos, o exemplo simplesmente lê algo da stream, jogando em uma variável global, e escreve algo na stream, antes de fechar a conexão.&lt;br /&gt;&lt;br /&gt;Se foi ou não proveitoso o exemplo, deixe um comentário aqui embaixo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6120028476058688663?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6120028476058688663/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6120028476058688663&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6120028476058688663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6120028476058688663'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/07/ainda-sockets-em-cach-serversockets.html' title='Ainda Sockets em Caché - ServerSockets'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6824402121100018856</id><published>2007-07-19T09:44:00.000-07:00</published><updated>2007-07-19T10:37:46.635-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='sockets'/><category scheme='http://www.blogger.com/atom/ns#' term='rede'/><category scheme='http://www.blogger.com/atom/ns#' term='programação'/><title type='text'>Sockets em Caché</title><content type='html'>Outro dia, na &lt;a href="http://groups.google.com/group/intersystems-public-cache"&gt;lista de Caché em inglês no google groups&lt;/a&gt;, alguém perguntou sobre como usar &lt;a href="http://en.wikipedia.org/wiki/Socket"&gt;sockets&lt;/a&gt; em &lt;a href="http://www.intersystems.com/cache/"&gt;Caché&lt;/a&gt;. Como eu também nunca havia usado sockets diretamente, resolvi investigar. Como já disse, a documentação do Caché está longe dos &lt;a href="http://java.sun.com/javase/6/docs/api/"&gt;javadoc da Sun&lt;/a&gt;, então boa parte do descobri foi por "feeling" mesmo, até porque neste caso não precisei testar muito.&lt;br /&gt;&lt;br /&gt;Então, abaixo vai o código exemplo que eu mandei, e que vc pode colocar em qualquer classe pra testar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ClassMethod connect()&lt;br /&gt;{&lt;br /&gt; set sock = ##class(%IO.Socket).%New()&lt;br /&gt; set st = $$$OK&lt;br /&gt; &lt;br /&gt; w "Starting", !&lt;br /&gt; &lt;br /&gt; // connecting, param:&lt;br /&gt; // address, port, timeout, status&lt;br /&gt; w sock.Open("127.0.0.1","7777",-1, st), !&lt;br /&gt; w st, !&lt;br /&gt;&lt;br /&gt; // reading from socket, param:&lt;br /&gt; // maxStringSize, timeout, status, lineTerminator &lt;br /&gt; w sock.ReadLine(50, 30, st, $c(13)), !&lt;br /&gt;&lt;br /&gt; // writing to socket, param: &lt;br /&gt; // stringToBeWritten, automaticFlush, status&lt;br /&gt; d sock.Write("We are the champions", 1, st)&lt;br /&gt; &lt;br /&gt; quit&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//===================================================&lt;br /&gt;&lt;br /&gt;ClassMethod server()&lt;br /&gt;{&lt;br /&gt; set sock = ##class(%IO.ServerSocket).%New()&lt;br /&gt; set st = $$$OK&lt;br /&gt; &lt;br /&gt; w "Starting server...", !&lt;br /&gt; &lt;br /&gt; // open serverSocket, param:&lt;br /&gt; // port, timeOut, status&lt;br /&gt; w sock.Open(7777, -1, st), !&lt;br /&gt; w st, !&lt;br /&gt; &lt;br /&gt; // server to listen incoming connections, param:&lt;br /&gt; // timeOut, status&lt;br /&gt; w sock.Listen(-1, st), !&lt;br /&gt; w st, !&lt;br /&gt; &lt;br /&gt; // writing to socket, param: &lt;br /&gt; // stringToBeWritten, automaticFlush, status&lt;br /&gt; d sock.Write("I am the champion", 1, st)&lt;br /&gt; &lt;br /&gt; // reading from socket, param:&lt;br /&gt; // maxStringSize, timeout, status, lineTerminator &lt;br /&gt; w sock.ReadLine(50, 30, st, $c(13)), !&lt;br /&gt; &lt;br /&gt; w sock.Close(), !&lt;br /&gt; &lt;br /&gt; w "Closing server...", !&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;O primeiro método, &lt;code&gt;connect()&lt;/code&gt;, usa &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.Socket"&gt;%IO.Socket&lt;/a&gt;, que implementa um socket básico. Se você já programou com sockets em Java, verá que é muito simples o seu uso. Na verdade, depois de criado o objeto, basta executar o método &lt;code&gt;Open&lt;/code&gt;, passando o endereço do host, a porta, um timeout para conexão e como referência, o status.&lt;br /&gt;&lt;br /&gt;Depois de conectado, pode-se usar os métodos de &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.DeviceStream"&gt;%IO.DeviceStream&lt;/a&gt; para ler e escrever no stream de dados.&lt;br /&gt;&lt;br /&gt;//===================================================&lt;br /&gt;&lt;br /&gt;O segundo método, &lt;code&gt;server()&lt;/code&gt;, usa &lt;a href="http://docs.intersystems.com/cache52/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25IO.ServerSocket"&gt;%IO.ServerSocket&lt;/a&gt;. A diferença é que o ServerSocket implementa o servidor, ou seja, um socket que fica 'escutando' requisições, ao passo que o %IO.Socket se conecta a um socket servidor. Ao contrário do Java, por exemplo, que um ServerSocket retorna um objeto Socket, no Caché o próprio objeto ServerSocket pode ser usado como se fosse um socket comum. No código acima, nota-se que os mesmos métodos usados para escrever/ler da stream são usados nos dois objetos socket.&lt;br /&gt;&lt;br /&gt;Também é possível deixar o ServerSocket escutando e ao chegar uma conexão, iniciar outro Job (processo) em background, para lidar com a conexão. Entretanto, não explorei essa possibilidade, quem sabe mais para frente...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6824402121100018856?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6824402121100018856/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6824402121100018856&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6824402121100018856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6824402121100018856'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/07/sockets-em-cach.html' title='Sockets em Caché'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-2249258278401850197</id><published>2007-07-18T07:20:00.001-07:00</published><updated>2007-07-18T07:20:54.521-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><title type='text'>Caché e XML</title><content type='html'>Pra não dizerem que eu só falo mal, hoje vou elogiar um aspecto do &lt;a href="http://www.intersystems.com/cache"&gt;Caché&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O suporte nativo a Xml é muito bom, e o que é melhor, é bem simples. Basta declarar que uma determinada classe extende a classe padrão, &lt;a href="http://docs.intersystems.com/cache20071/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&amp;LIBRARY=DOCBOOK&amp;CLASSNAME=%25XML.Adaptor"&gt;XML.Adaptor&lt;/a&gt;, que a sua classe já pode ser usada para enviar e/ou receber Xml. Como o Caché aceita herança múltipla, extender esta classe é mero detalhe.&lt;br /&gt;&lt;br /&gt;No caso de se usar Web services, é o que basta. Claro que no caso dos Web services, o Caché já gera toda a estrutura de parsing e binding, o que não quer dizer que não dê pra fazer na mão. Além disso, este esquema é flexível o suficiente para se alterar algumas propriedades, como por exemplo, se você quer que no Xml determinada propriedade da classe seja mapeada com um nome diferente, isso é possível (alterando o parâmetro 'XMLNAME' da propriedade).&lt;br /&gt;&lt;br /&gt;Infelizmente, nem tudo são flores. Apesar de ser muito bom, e ter uma ótima flexibilidade, a documentação é pobre, e por vezes confusa (o que aliás, se repete por muitos lugares da documentação). Isso faz com que: 1 - você tenha que ficar testando algumas coisas, porque a documentação não te esclarece; 2 - ou você se aventure por uns códigos que porventura já existam e tente entender, ou por exemplo, que o próprio Caché gera (no assistente de cliente de Web Services, por exemplo).&lt;br /&gt;&lt;br /&gt;Vou ficando por aqui, deixando o link pra esse mini artigo (pessoalmente, não gosto deste tipo de artigo ser chamado de white paper, pois não gosto da definição de white paper como um produto de marketing, mas isso é outra história XD): &lt;a href="http://www.intersystems.com/cache/whitepapers/xml_standards.html"&gt;Caché and XML-based Data Exchange Standards&lt;/a&gt;. Não é um artigo técnico, então caso você ainda não tenha familiaridade com Xml, pode ler tranquilo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-2249258278401850197?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/2249258278401850197/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=2249258278401850197&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/2249258278401850197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/2249258278401850197'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/07/cach-e-xml.html' title='Caché e XML'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-9107822773091623581</id><published>2007-06-27T10:41:00.000-07:00</published><updated>2008-07-24T05:10:09.421-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='celesc'/><category scheme='http://www.blogger.com/atom/ns#' term='alphalinc'/><category scheme='http://www.blogger.com/atom/ns#' term='suprimentos'/><title type='text'>A demo é do "demo"</title><content type='html'>Bem, eu já mencionei que trabalho aqui na Celesc, mas creio que nunca disse exatamente o que eu faço. Bem, nem vai ser hoje, porque eu acabo fazendo um monte de coisas, hehehe XD.&lt;br /&gt;&lt;br /&gt;Uma das tarefas a qual fui designado, foi acompanhar a implantação do novo sistema de suprimentos. Este sistema, chamado &lt;b&gt;Alphalinc&lt;/b&gt;, foi comprado/licenciado pela Celesc, e é originalmente desenvolvido pela &lt;a href="http://www.disclinc.com/"&gt;Disclinc&lt;/a&gt;, empresa australiana.&lt;br /&gt;&lt;br /&gt;Este sistema, originalmente desenvolvido como sendo um gerenciador de cadeia de suprimentos, está sendo atualmente sendo adequado para o uso aqui na Celesc, pois como empresa 'pública', tem uma série de peculiaridades com relação ao resto do mundo. Estas modificações, o pessoal da empresa, da própria &lt;b&gt;Disclinc-br&lt;/b&gt; e sua parceira &lt;b&gt;E-biz&lt;/b&gt;, chamam de "customizações". &lt;br /&gt;&lt;br /&gt;Só para esclarecer, meu papel neste projeto não é exatamente de desenvolvedor, arquiteto, gerente, ou coisa alguma. Na verdade, eu até ajudo alguma coisa como desenvolvedor, mas a minha verdadeira atribuição é "ficar de olho", já que por um bom tempo, ninguém do DPTI (o departamento de informática) sabia o que acontecia. &lt;br /&gt;&lt;br /&gt;(Bem, daí dá pra ver que a Celesc não tem cultura de trabalhar em projetos)&lt;br /&gt;&lt;br /&gt;Pois bem, como todo projeto, este novo sistema de suprimentos está atrasado. Opinião pessoal (que já expressei para o mundo todo): está muuuuuuito atrasado, e nem de longe termina no prazo (que por acaso, é outubro).&lt;br /&gt;&lt;br /&gt;Hoje termina uma demonstração deste novo sistema, para alguns usuários. &lt;br /&gt;&lt;br /&gt;IMHO, esta demonstração foi um pouco a frente do tempo, já que para o usuário final, o que importa são as telas funcionando do jeito que ele quer. Como muitos módulos ainda não foram terminados, muita coisa falta. E para o usuário, não importa muito se a tela está 75% da sua funcionalidade original pronta: ele vai se focar nos 25% que faltam. &lt;br /&gt;&lt;br /&gt;Juntando isso com algumas falhas na especificação, polêmicas entre e com usuários, o que sai? Uma demonstração (demo) que deixa usuários frustrados, desenvolvedores tensos e gerentes estressados.&lt;br /&gt;&lt;br /&gt;OK, pra ser justo, não foi (ou está sendo, pois escrevo este post durante a apresentação) um pandemônio. E a frustração dos usuários também não foi tão grande (feliz ou infelizmente, com o passar do tempo, as expectativas dos usuários aqui foram ficando cada vez menores).&lt;br /&gt;&lt;br /&gt;Erros que identifiquei, e que podem ser úteis para algum leitor deste nem tanto humilde blog:&lt;br /&gt;&lt;br /&gt;- pressa em mostrar serviço: se você tem diversos módulos, e todos os módulos não estão completos (mesmo que faltem apenas 10 ou 5%), vc não tem NADA completo. Não se apresse, complete o que tem que ser completado, e depois mostre para o usuário.&lt;br /&gt;&lt;br /&gt;- tentar entregar vários módulos de uma vez: entregue poucos módulos, mas entregue-os bem feitos. Nem tudo pode ser modularizado de forma a ficar funcional, mas muitas coisas podem ser feitas. Muitos módulos são interdependentes, neste caso, talvez modularizar ainda mais a sua arquitetura seja interessante. Em vez de um módulo monstruoso, refatore. As vezes não dá, mas isso não é regra.&lt;br /&gt;&lt;br /&gt;- espera para entregar algo palpável para o usuário: entregue aos poucos, mas sempre - seja ágil, adote uma metodologia de entregas frequentes, mesmo que estes módulos sejam pequenos (mas devem ser funcionais). Isso é uma mão na roda na hora de identificar erros de especificação (pq o usuário vai chiar), um dos erros mais custosos no desenvolvimento.&lt;br /&gt;&lt;br /&gt;Vamos às conclusões e considerações finais.&lt;br /&gt;&lt;br /&gt;Listei acima alguns erros do projeto. Veja bem, eles NÃO SÃO OS ÚNICOS PROBLEMAS!! Mas são problemas que nós (da área de informática como um todo), poderíamos ter trabalhado. Muitos outros problemas, que não irei comentar aqui (porque este post iria ficar MUUUUITO maior do que já está), estão fora do nosso alcance.&lt;br /&gt;&lt;br /&gt;Este projeto vai vingar? Não sei, e ainda não desenvolvi poderes pra saber o futuro (apesar de eu ser japonês rechonchudo, não tenho nem katana nem dobro o espaço-tempo - se não entendeu, assista &lt;a href="http://www.9thwonders.net/"&gt;Heroes&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Talvez daqui a uns seis meses, eu faça outro post relatando um caso de sucesso. Ou não...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-9107822773091623581?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/9107822773091623581/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=9107822773091623581&amp;isPopup=true' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9107822773091623581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/9107822773091623581'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/06/demo-do-demo.html' title='A demo é do &quot;demo&quot;'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-8155914229698842540</id><published>2007-06-08T05:52:00.001-07:00</published><updated>2007-06-08T05:52:57.104-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Operadores</title><content type='html'>Já faz algum tempo que descobri algo no mínimo peculiar sobre a linguagem do Caché, e hoje vou publicar aqui. Não é necessariamente um bug, pois está devidamente registrado na documentação, mas que é algo não natural, isso é.&lt;br /&gt;&lt;br /&gt;Se vc se lembra das aulas de matemática do primeiro grau, deve acertar quanto é a expressão 1 + 2 * 3. Se vc respondeu 9, deve ter matado aula, pois a resposta é 7. Isso porque na matemática, o operador de multiplicação tem precedência sobre o operador de adição, ou seja, se você não coloca parênteses (que é o meio "certo" de dizer qual operação vc quer que seja efetuada primeiro), vc deve multiplicar antes de somar.&lt;br /&gt;&lt;br /&gt;Bem, a maioria das linguagens que eu conheço leva em conta a matemática (o que é absolutamente normal, visto que a computação como ciência nasceu da matemática). &lt;br /&gt;&lt;br /&gt;Exemplos:&lt;br /&gt;No oracle, faça um SELECT 1 + 2 * 3 FROM DUAL, a resposta é 7. Em java, c/c++, delphi/pascal, a resposta também é 7.&lt;br /&gt;&lt;br /&gt;Em Caché Object Script, a resposta é 9. Experimente abrir um terminal do Caché, e fazer um WRITE 1 + 2 * 3, a resposta é 9.&lt;br /&gt;&lt;br /&gt;Isso porque essa linguagem não segue o padrão matemático, muito menos o padrão da maioria das linguagens. OK, questão de implementação, e está também na documentação, mas não deixo de ver isso com maus olhos. Especialmente se vc está em conformidade com o resto do mundo, acostumado com a precedência certa dos operadores (por "certo", quero dizer conforme a matemática).&lt;br /&gt;&lt;br /&gt;Tudo bem, é questão de escolha da linguagem seguir ou não qualquer padrão. Mas isso pode produzir alguns erros. Eu fui atentar para esse fato porque um loop meu estava estourando os limites. Acostumado a programar em outras linguagens, não achava que uma simples continha pudesse estar dando errado. Depois de verificar o algoritmo umas duas vezes, uma luz se acendeu, e resolvi fazer um teste, e descobri que devia ter colocado explicitamente parênteses na expressão. Depois chequei a documentação, e realmente estava lá: a precedência é estritamente da esquerda para a direita. &lt;br /&gt;&lt;br /&gt;Mas por que os designers da linguagem fizeram esta escolha? Será que eles queriam ser "cool", diferentes do resto do mundo, ou seriam eles rebeldes com ou sem causa?&lt;br /&gt;&lt;br /&gt;Apesar de serem explicações, acredito que não. Acredito que tenha sido por causa implementação da execução do script, que é mais fácil de implementar quando não se considera precedência matemática. Ou seja: preguiça. A lei do menor esforço que move este mundo =P&lt;br /&gt;&lt;br /&gt;Se bem que mesmo sendo uma linguagem interpretada, de script, é muito desculpa. Javascript também não vai contra o mundo. Experimenta um 'document.write(1 + 2 * 3)', que ele te devolve 7.&lt;br /&gt;&lt;br /&gt;U_U&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-8155914229698842540?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/8155914229698842540/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=8155914229698842540&amp;isPopup=true' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8155914229698842540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/8155914229698842540'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/06/operadores.html' title='Operadores'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6416311866245215119</id><published>2007-06-01T04:30:00.000-07:00</published><updated>2007-06-01T04:34:05.989-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='video'/><category scheme='http://www.blogger.com/atom/ns#' term='TI'/><category scheme='http://www.blogger.com/atom/ns#' term='opinião'/><title type='text'>Juros baixinhos</title><content type='html'>Bem, quem não mora em Santa Catarina, não deve ter visto a campanha do Besc, o banco estadual (que foi federalizado e que agora está num rolo só, mas esse não é o ponto de discussão). Dentro desta campanha publicitária, que produziu alguns dos melhores comerciais que eu vi em um bom tempo, um dos comerciais (um dos últimos), me fez refletir um pouco, e exercer um paralelo com outras áreas da nossa vida, em especial, a nossa área de informática (não, eu não gosto do termo TI, mas eu acabo usando =/).&lt;br /&gt;&lt;br /&gt;O referido comercial pode ser visto no youtube, e eu coloco ele aqui embaixo. Assistam ele antes de continuarem a leitura aqui.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/iFQmFk3wqRo"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/iFQmFk3wqRo" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Agora que já devem ter assistido o vídeo, vamos ao paralelo.&lt;br /&gt;&lt;br /&gt;Assim como o gerente do banco que fica tentando "mascarar" os juros, temos vendedores e lobistas na área de informática que tentam de toda maneira, empurrar um produto ou serviço, elevando os pontos positivos às alturas, e "esquecendo" de mencionar alguma inconformidade e/ou problema que este venha a ter na empresa, tal como a integração com outros sistemas.&lt;br /&gt;&lt;br /&gt;Isso é até de certo ponto, normal e aceitável (não é crime, mas eu pessoalmente acho imoral, mas eu geralmente sou minoria...), o problema é quando esses vendedores/consultores conversam com o pessoal que não é da área de informática, usuários finais, mas que têm poder de decisão, tal como diretores e presidentes.&lt;br /&gt;&lt;br /&gt;Por exemplo, no organograma aqui da Celesc, o departamento de informática, vulgo DPTI, está subordinado a diretoria de assuntos financeiros. O que isso quer dizer na prática? Que quem toma decisões pra valer é o diretor financeiro, e que o chefe de TI da empresa, tem poderes (muito) limitados. "Nas empresas onde a área de TI está subordinada à área financeira, os sistemas são um pandemônio". Essa frase (ou melhor, algo parecido, já que eu não lembro palavra por palavra), eu li em algum lugar que eu também não lembro, mas que ilustra uma verdade, pelo menos por aqui.&lt;br /&gt;&lt;br /&gt;E então voltamos a situação do nosso gerente de "juros baixos". Representantes, vendedores, lobistas mesmo, fazendo um grande alarde, omitindo "aspectos", e tentando fazer a cabeça de diretores e usuários (isso quando não envolvemos alguns "mimos" ou presentinhos, o que já é caso pra polícia). Se você já não viu essa cena, prepare-se, porque uma hora ou outra, vai. "Do you hear it, Mr. Anderson? It´s the sound of inevitability". &lt;br /&gt;&lt;br /&gt;Nestas horas, mesmo o CIO com menos poder, mesmo sem ter CIO no crachá, deveria assumir uma postura. Uma postura que é não influenciar a decisão, mas apresentar TODOS os fatos, como eles são. Se mesmo cientes, os comandantes decidirem pelos "jurinhos mais baixos", aí temos outra discussão, por vezes técnica, mas muitas vezes ética.&lt;br /&gt;&lt;br /&gt;Este é um assunto que rende "muito pano pra manga", mas me atenho por aqui.&lt;br /&gt;&lt;br /&gt;(P.S.: Um último comentário: aqui não temos um chefe de TI, e sim uma chefa, o que é um fato muito legal. Ter uma mulher comandando TI, que ainda é uma área majoritariamente masculina, é uma alegria para mim, que ando cansado de tanto enxergar testosterona em TI =D)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6416311866245215119?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6416311866245215119/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6416311866245215119&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6416311866245215119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6416311866245215119'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/06/juros-baixinhos.html' title='Juros baixinhos'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-6527218610532159607</id><published>2007-05-25T08:50:00.001-07:00</published><updated>2007-05-25T08:50:55.374-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apresentação'/><title type='text'>A casa caiu - o início</title><content type='html'>Este blog será dedicado a parte técnica da minha vida, ou seja, trabalho. Ou coisas relacionadas, como nerdices ou geek-ices.&lt;br /&gt;&lt;br /&gt;A apresentação inicial: &lt;br /&gt;&lt;br /&gt;Sou um maluco que fez Ciência da Computação na boa e velha &lt;a href="http://www.maringa.com"&gt;Maringá&lt;/a&gt;, na &lt;a href="http://www.din.uem.br"&gt;UEM&lt;/a&gt;, que na época tinha lá seus problemas, mas era muito boa. Hoje em dia, parece que os problemas aumentaram, mas não estou lá pra afirmar nada, então considere isso só boato.&lt;br /&gt;&lt;br /&gt;Fiz mestrado aqui na UFSC, &lt;a href="http://www.guiafloripa.com.br"&gt;Florianópolis&lt;/a&gt;, ilha que muita gente acha que é o paraíso, mas que eu acho mais próximo é das profundezas abissais. Fiz no departamento de engenharia elétrica, que apesar do nome, mexe muito com computação. Por que não fiz em Computação? Porque na elétrica tinha mais bolsas XD&lt;br /&gt;&lt;br /&gt;Logo antes de defender a tese (uma semana antes, na verdade), entrei na &lt;a href="http://www.celesc.com.br"&gt;Celesc&lt;/a&gt;, empresa de distribuição de energia de SC (ou companhia de luz, como alguns preferem =D ).&lt;br /&gt;&lt;br /&gt;E hoje aqui estou, trabalhando, morcegando, trabalhando, morcegando, não necessariamente nesta ordem, nem nestas proporções.&lt;br /&gt;&lt;br /&gt;É isso, vamos começar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-6527218610532159607?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/6527218610532159607/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=6527218610532159607&amp;isPopup=true' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6527218610532159607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/6527218610532159607'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/05/casa-caiu-o-incio.html' title='A casa caiu - o início'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5645812914185429411.post-5849871335300795261</id><published>2007-05-25T08:38:00.000-07:00</published><updated>2007-05-25T08:48:57.899-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caché'/><category scheme='http://www.blogger.com/atom/ns#' term='ensemble'/><category scheme='http://www.blogger.com/atom/ns#' term='pepinos e tabajarices'/><title type='text'>Caché - problemas</title><content type='html'>Só pra contextualizar: aqui eu trabalho (também) com a plataforma de integração Ensemble, que por sua vez é construída em cima do BD Caché. &lt;br /&gt;&lt;br /&gt;Copiando de um post que fiz no fórum da &lt;a href="http://www.intersystems.com.br"&gt;Intersystems &lt;/a&gt;(a criadora das duas ferramentas acima citadas), alguns dos (muitos) problemas:&lt;br /&gt;&lt;br /&gt;/****************************&lt;br /&gt;&lt;br /&gt;Bem, não vou afirmar nada quanto a parte de gerenciamente de dados do Caché, pois Banco de Dados não é a minha área de atuação/pesquisa, nem fiz testes relevantes a esse respeito. Mas quanto a outras questões, vou colocar alguns pontos aqui.&lt;br /&gt;&lt;br /&gt;Primeiro estou me baseando na versão que utilizo, a versão do Caché que vem junto ao Ensemble 4, creio que seja a versão 5 alguma coisa XD&lt;br /&gt;&lt;br /&gt;Quanto a parte de documentação, já vi piores (as inexistentes, por exemplo). Mas a documentação da Intersystems está muuuuito longe do nível das documentações da Sun com o Java, por exemplo, ou no âmbito de BDs, da Oracle. A documentação além de ser fraca, é estruturada de maneira confusa, e parece que os técnicos não dão muita manutenção nos documentos. &lt;br /&gt;&lt;br /&gt;Só pra citar um exemplo, nesta versão que utilizo, os webservices têm opção de implementação de segurança, possivelmente a parte ws-security do stack ws-*. Possivelmente, você pergunta? Sim, porque não encontrei nada nas referências, nem nos tutoriais, só na listagem de classes (que não diz nada e que por sinal, é horrível - por favor, inspirem-se nos javadocs da sun e cia) [EDIT: pra quem não sabe, a listagem de classes do Caché é uma espécie de 'javadoc'], e creio que implemente o ws-security por causa das mensagens de erro que ele joga, quando não utilizo nenhum esquema de segurança (como era padrão na versão anterior).&lt;br /&gt;&lt;br /&gt;Anteriormente [em outro post no fórum] foi citada a migração de ferramentas de administração do Caché para a web, como o Sql Manager. Posso dizer que apesar da roupagem nova, com interface web, as funcionalidades continuaram praticamente as mesmas. Ou seja, na minha opinião, piorou, já que a interface web é mais lenta e exige mais hardware, só pra ter uma interface bonitinha (e nem tão mais funcional que a antiga). Do ponto de vista de desenvolvedor, piorou. Se eu fosse usuário comum, talvez a opinião fosse outra.&lt;br /&gt;&lt;br /&gt;Concluindo, como banco de dados, não tive problemas com o Caché, apesar de não usá-lo extensivamente com esse fim. A performance foi boa, mas no volume de dados com que trabalho, isso já é esperado de qualquer BD decente. Agora afirmar que ele tem performance semelhante a outros bancos, é no mínimo ingênuo, sem um trabalho muito grande de comparação, com uma metodologia bem definida e parâmetros claros. Neste sentido, nunca vi trabalho nenhum, e se alguém souber de algum, por favor, indique. Mas veja bem, quero um trabalho com metodologia clara, que eu possa simular ou replicar pra comprovar os resultados. "Papers" das empresas fabricantes normalmente passam longe disso.&lt;br /&gt;&lt;br /&gt;Agora, o Caché como arquitetura para desenvolvimento de aplicações, deixa muito a desejar. Muito mesmo. Fora os pontos que eu citei acima, a linguagem também não ajuda. Pra uma ferramenta que se gaba de ser OO, não ter um tratamento de exceções decentes (como é o caso - try catch? pra que isso, não?), é no mínimo, decepcionante. (Ouvi dizer que isso já está sendo melhorado nas versões mais novas, mas não fui conferir.)&lt;br /&gt;&lt;br /&gt;Terminando: como desenvolvedor, eu escolheria o Caché? Não. A ferramenta tem seus prós e contras, como outras. Mas para mim, os seus contras pesam muito mais que os prós.&lt;br /&gt;&lt;br /&gt;************************/&lt;br /&gt;&lt;br /&gt;Como diz o meu amigo "Cleiton", a casa caiu, mano&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5645812914185429411-5849871335300795261?l=a-casa-caiu.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-casa-caiu.blogspot.com/feeds/5849871335300795261/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5645812914185429411&amp;postID=5849871335300795261&amp;isPopup=true' title='6 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5849871335300795261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5645812914185429411/posts/default/5849871335300795261'/><link rel='alternate' type='text/html' href='http://a-casa-caiu.blogspot.com/2007/05/cach-problemas.html' title='Caché - problemas'/><author><name>Andarilho</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://bp0.blogger.com/_0AukCty4MP0/R5kFljf_A-I/AAAAAAAAAgE/UijunPk89WY/S220/642955.jpg'/></author><thr:total>6</thr:total></entry></feed>
