<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>(code segment) &#187; sharepoint</title>
	<atom:link href="http://oldblog.ideseg.com/category/sharepoint/feed" rel="self" type="application/rss+xml" />
	<link>http://oldblog.ideseg.com</link>
	<description>se acabarón las espinacas</description>
	<lastBuildDate>Thu, 26 Jan 2012 17:27:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cuestiones sobre el diseño de soluciones en SharePoint (4)</title>
		<link>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-4</link>
		<comments>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-4#comments</comments>
		<pubDate>Sat, 25 Jul 2009 19:21:14 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Cuestiones-sobre-el-diseno-de-soluciones-en-SharePoint-(4).aspx</guid>
		<description><![CDATA[Continuando con el tema de la organización, como ya he dicho las colecciones de sitios son un punto muy importante a tener en cuenta. Alguna de las limitaciones las podemos superar por medio de la instalación de soluciones y características a través de las cuales podemos hacer un despliegue más rápido sobre distintas colecciones de [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando con el tema de la organización, como ya he dicho las colecciones de sitios son un punto muy importante a tener en cuenta. Alguna de las limitaciones las podemos superar por medio de la instalación de soluciones y características a través de las cuales podemos hacer un despliegue más rápido sobre distintas colecciones de sitios.</p>
<p>A la hora de organizar, yo, personalmente tengo en cuenta dos cosas, que creo son muy importantes, la primera es el tema de la seguridad.</p>
<p><b>Seguridad</b></p>
<p>SharePoint cuenta con una serie de roles, grupos y acciones con las que hay que familiarizarse para poder desenvolverse correctamente. </p>
<p>Establecer a que información debe acceder cada cual, que puede ver y que puede editar, nos va a ayudar a tener una idea clara de cómo debemos organizar otras cosas.</p>
<p>Yo primero suelo hacer esto en dos pasos, en un primer paso repaso la información que va a contener la aplicación y los usuarios que van a acceder a ella; establezco una correspondencia creando una serie de grupos de usuarios. En un segundo paso, una vez tenemos clara la estructura que va a tener nuestra aplicación, colecciones de sitios, sitios y subsitios y la información que va a contener cada uno de ellos, vuelvo a ajustar los permisos.</p>
<p>Por ejemplo en el caso que comente anteriormente en donde teníamos el dilema de si establecer la jerarquía por Delegación o por Departamento, si hemos optado por establecerla por Delegación, tenemos que asegurarnos de que el jefe de almacén pueda acceder al departamento de almacén en cualquiera de las delegaciones, pero no podrá entrar en otros departamentos. </p>
<p>Cuando pensemos en la seguridad y los permisos de acceso también hay que tener en cuenta quien administrará los sitios ¿hay un departamento de sistemas encargado de ello? ¿Van a poderse crear nuevos subsitios? ¿Quién se va a encargar de mantener los permisos?</p>
<p>Existe también una jerarquía de permisos, de modo que podemos asignar permisos que se irán heredando en los distintos subsitios. Hay que recordar que los permisos no son como los de NTFS, es decir que no podemos heredar y tener permisos únicos al mismo tiempo, es o una cosa o la otra.</p>
<p><b>Acceso y Agregación de la información<br /></b><br />La segunda cosa que suelo tener en cuenta es donde se va a localizar la información dentro de la aplicación, aspectos a tener en cuenta como el hecho de cómo se quieren agregar los datos y donde van a estar localizados los mismos son de vital importancia.</p>
<p>En MOSS disponemos del “Cotent Query Web Part” que nos va a permitir agregar datos de la misma colección de sitios, pero en WSS debemos hacerlo nosotros mismos, hay que tener en cuenta que información debemos agregar y como deseamos verla, para poder pensar cómo vamos a hacerlo.</p>
<p><b><i>Cuestiones que me han preguntado estos días </i></p>
<p>Bases de datos de Contenido</b></p>
<p>Como comente anteriormente cada aplicación web al menos contiene una base de datos de contenido, en ella se almacenará la colección de sitios principal y si lo deseamos otras colecciones. También una aplicación web puede tener más de una base de datos de contenido, que contendrán una o más colecciones de sitios, pero una colección de sitios no puede usar más de una base de datos.</p>
<p>Finalmente todo el almacenamiento de SharePoint recae en una base de datos, tenemos que tener en cuenta la capacidad de almacenamiento que esperamos tengan nuestras colecciones de sitios, no es lo mismo una aplicación web pública realizada con las características de CMS, que una intranet en donde vamos a almacenar miles de documentos de office. </p>
<p>Además y como es lógico debemos prever un plan de contingencias y de mantenimiento para nuestras bases de datos, pensad no es lo mismo una base de datos de 50GB que de 500GB, tiempo de respaldo, soportes necesarios, mantenimiento, horarios, etc…</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-4/feed</wfw:commentRss>
		<slash:comments>549</slash:comments>
		</item>
		<item>
		<title>Cuestiones sobre el diseño de soluciones en SharePoint (3)</title>
		<link>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-3</link>
		<comments>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-3#comments</comments>
		<pubDate>Thu, 23 Jul 2009 16:14:53 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Cuestiones-sobre-el-diseno-de-soluciones-en-SharePoint-(3).aspx</guid>
		<description><![CDATA[Uno de los primeros puntos a tener en cuenta cuando se desarrolla una solución para SharePoint es cómo vamos a organizar el contenido y la información. SharePoint nos ofrece distintas posibilidades que veremos a continuación, pero también hay que tener en cuenta algunos factores importantes. Granjas, Aplicaciones Web, Colecciones de Sitios, Sitios y SubsitiosEn primer [...]]]></description>
			<content:encoded><![CDATA[<p>Uno de los primeros puntos a tener en cuenta cuando se desarrolla una solución para SharePoint es cómo vamos a organizar el contenido y la información.</p>
<p>SharePoint nos ofrece distintas posibilidades que veremos a continuación, pero también hay que tener en cuenta algunos factores importantes.</p>
<p><b>Granjas, Aplicaciones Web, Colecciones de Sitios, Sitios y Subsitios<br /></b><br />En primer lugar tenemos que comprender las opciones que nos brinda SharePoint para estructurar nuestra solución. </p>
<p>Debemos de tener claro que todos los datos de SharePoint son almacenados en distintas bases de datos en un servidor de SQL. Con lo cual desde el punto de vista del diseño de aplicaciones de SharePoint, tenemos que contemplar cuando menos un plan de contingencias y de mantenimiento de las bases de datos que conforman nuestra instalación.</p>
<p><a href="http://www.ideseg.com/MantenimientoDeBasesDeDatosSharePoint2007.aspx">Bases de datos de SharePoint 2007</a></p>
<p>Dicho esto tenemos que entender ahora 5 piezas fundamentales. No quiero extenderme más de lo necesario, a modo de resumen: </p>
<p>Una granja de servidores es un conjunto de servidores que trabajan en unidos, donde podemos dividir distintas responsabilidades entre distintos servidores. Podemos tener una granja de un único servidor donde todos los servicios funcionen sobre una única máquina (servidor web, búsquedas, Excel services, Forms services, SQL Server …) lo más lógico desde el principio es dividir en dos partes la granja, es decir dejar un servidor para el SQL Server y otro con el resto de servicios. Conforme van aumentando los clientes o la demanda de servicios podemos ir añadiendo servidores y establecer las nuevas funcionalidades de las cuales se ocuparan esos servidores, así por ejemplo podemos añadir un nuevo servidor a nuestra granja que se ocupe únicamente del servicio de búsquedas de modo que descargaremos a otros servidores de dicha responsabilidad. <br />En el caso de una granja pequeña en crecimiento, pongamos por ejemplo 3 servidores, los roles podrían ser los siguientes, servidor de SQL, servidor Web Front End, y un servidor que se ocupara del resto de los servicios, búsquedas, Excel services, Form Services, Shared Services etc…</p>
<p>En el caso de una instalación de Windows SharePoint Services, también es recomendable dividir siempre que sea posible al menos los roles de SQL Server y de Web Front End.</p>
<p>Obviamente todo esto pasa por un estudio de las licencias necesarias, para montar la infraestructura que deseemos, esto lo dejaremos al margen.</p>
<p>Una vez que tenemos clara la estructura de nuestra granja, tenemos todavía una importante labor, establecer cómo será la jerarquía de nuestros sitios. </p>
<p>En la terminología de SharePoint, tenemos otro punto importante, el de la aplicación web. Una aplicación web será el punto raíz de la estructura de una solución, cuando creamos una aplicación web, SharePoint crea un nuevo sitio de IIS en una dirección y un puerto de nuestra máquina, así como una base de datos en donde albergará el contenido de dicha aplicación web.</p>
<p>Una aplicación web, no es más que un vinculo o una dirección y una base de datos de almacenamiento con el objetivo de albergar cuando menos una colección de sitios. Es por esto que una vez creada una aplicación web a través de la administración central de SharePoint, lo siguiente es crear una colección de sitios que quedará enlazada con la raíz de la aplicación web.</p>
<p>Una aplicación web como mínimo contiene una colección de sitios, pudiendo a través de de la administración central fijar un punto de anclaje para nuevas colecciones de sitios.</p>
<p>En una granja de servidores podemos tener distintas aplicaciones web como una intranet, una extranet, o un sitio web publico), ahora bien, aunque podemos usar la misma dirección web, cada aplicación web deberá tener su propio puerto; no podemos tener dos aplicaciones corriendo sobre el mismo puerto.</p>
<p>Una colección de sitios, es como un árbol, del cual pueden colgar sitios y subsitios, una colección de sitios es el inicio de una jerarquía de sitios, y al igual que en árbol una colección de sitios tiene un sitio raíz. Todo esto es importante porque debemos de tener en cuenta diversos factores como veremos luego que afectan en su conjunto a una colección de sitios.</p>
<p>Antes de continuar, terminaré de matizar que es un sitio y que es un subsitio. Un sitio es un apartado o nivel en el cual encontraremos contenido (entender aquí, páginas, listas, bibliotecas de documentos, subsitios, etc…) y un subsitio es un sitio que tiene padre.</p>
<p>La importancia de las colecciones de sitios consiste en que dentro de una colección de sitios existen ciertos elementos y recursos comunes dentro de la colección y este es un aspecto muy importante a la hora de diseñar una solución de SharePoint.</p>
<p>Dentro de esos elementos comunes estan:</p>
<blockquote><p>-&nbsp;&nbsp; &nbsp;Flujos de trabajo<br />-&nbsp;&nbsp; &nbsp;Tipos de contenido<br />-&nbsp;&nbsp; &nbsp;Columnas de sitio<br />-&nbsp;&nbsp; &nbsp;Seguridad por grupos<br />-&nbsp;&nbsp; &nbsp;Ámbito de búsquedas (WSS)<br />-&nbsp;&nbsp; &nbsp;Características (features)<br />-&nbsp;&nbsp; &nbsp;Papelera de reciclaje<br />-&nbsp;&nbsp; &nbsp;Informes de uso<br />-&nbsp;&nbsp; &nbsp;Web Parts<br />-&nbsp;&nbsp; &nbsp;Páginas maestras<br />-&nbsp;&nbsp; &nbsp;Plantillas de sitios<br />-&nbsp;&nbsp; &nbsp;Plantillas de listas<br />-&nbsp;&nbsp; &nbsp;Quotas (limites de espacio)<br />-&nbsp;&nbsp; &nbsp;Copias de seguridad</p></blockquote>
<p>Para que quede claro, dentro de una aplicación web como he dicho anteriormente puede haber más de una colección de sitios, pero todos estos elementos son dependientes de la colección de sitios, de modo que en una colección podemos tener una plantilla personalizada para crear listas de tipo “Pedido” pero en la otra colección esta plantilla puede no existir.</p>
<p><b>Organización</b></p>
<p>Al igual que las empresas y corporaciones tienen una estructura determinada debemos establecer cómo queremos estructurar nuestras aplicaciones web en SharePoint. Esto aunque puede parecer sencillo, es sin duda una de las cosas más complicadas.</p>
<p>Veamos un pequeño ejemplo, tomemos una organización dedicada a la fabricación de muebles, supongamos que tiene tres fábricas ó delegaciones en Madrid (central), Barcelona y Sevilla. Dentro de cada delegación, hay diversas divisiones&nbsp; ó departamentos, Almacén, Fabricación, Ventas, Financiero y Postventa.</p>
<p>Podemos hacer una estructura por delegación </p>
<p>-&nbsp;&nbsp; &nbsp;Madrid<br />
<blockquote>o&nbsp;&nbsp; &nbsp;Almacén<br />o&nbsp;&nbsp; &nbsp;Fabricación<br />o&nbsp;&nbsp; &nbsp;Ventas<br />o&nbsp;&nbsp; &nbsp;…</p></blockquote>
<p>-&nbsp;&nbsp; &nbsp;Barcelona<br />
<blockquote>o&nbsp;&nbsp; &nbsp;Almacén<br />o&nbsp;&nbsp; &nbsp;…</p></blockquote>
<p>-&nbsp;&nbsp; &nbsp;Sevilla<br />
<blockquote>o&nbsp;&nbsp; &nbsp;Almacén</p></blockquote>
<p>O bien podemos hacerla por departamentos</p>
<p>-&nbsp;&nbsp; &nbsp;Almacén<br />
<blockquote>o&nbsp;&nbsp; &nbsp;Madrid<br />o&nbsp;&nbsp; &nbsp;Barcelona<br />o&nbsp;&nbsp; &nbsp;Sevilla</p></blockquote>
<p>-&nbsp;&nbsp; &nbsp;Fabricación<br />
<blockquote>o&nbsp;&nbsp; &nbsp;Madrid<br />o&nbsp;&nbsp; &nbsp;Barcelona<br />o&nbsp;&nbsp; &nbsp;Sevilla</p></blockquote>
<p>-&nbsp;&nbsp; &nbsp;….</p>
<p>Aquí empieza el dilema, ¿Cómo estructuramos nuestra aplicación web?.</p>
<p>Cada organización es muy particular, de modo que no existen formulas magistrales. Por proponer un comienzo, deberíamos analizar qué información es la que va almacenar cada sitio y que seguridad ha de tener cada elemento. ¿Los usuarios de Sevilla solo deben ver lo de Sevilla o pueden ver también lo de Barcelona y Madrid? ¿Deben los del departamento de Almacén ver los datos de Ventas? ¿Le interesan al departamento de Posventa los incidentes de las tres delegaciones?</p>
<p>¿Debo crear una colección de sitios por cada delegación? ¿Por cada departamento? ¿Debería una delegación ser un sitio y un departamento un subsitio? ¿Debería ser al revés? ¿Debería tener dos estructuras, por departamento y por delegación? ¿En colecciones de sitios diferentes o en la misma colección?</p>
<p>A la hora de desarrollar una solución debemos tener en cuenta un montón de aspectos, cuestiones como la seguridad, la información y su flujo, las búsquedas y los recursos con los que va a contar son algunas de las más importantes.</p>
<p>Debemos empezar haciendo un análisis muy cuidadoso de todos estos aspectos para no llevarnos sorpresas luego.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-3/feed</wfw:commentRss>
		<slash:comments>296</slash:comments>
		</item>
		<item>
		<title>Cuestiones sobre el diseño de soluciones en SharePoint (2)</title>
		<link>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-2</link>
		<comments>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-2#comments</comments>
		<pubDate>Tue, 21 Jul 2009 15:37:15 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Cuestiones-sobre-el-diseno-de-soluciones-en-SharePoint-(2)-.aspx</guid>
		<description><![CDATA[Como comentaba en el post anterior, me gustaría dedicar una serie de artículos a algunas de las consideraciones sobre el diseño de soluciones en SharePoint, el en titulo olvide mencionar que me voy a centrar básicamente en el área empresarial. FeedBack Uno de los aspectos que considero más importante es el feedback de los usuarios. [...]]]></description>
			<content:encoded><![CDATA[<p>Como comentaba en el post anterior, me gustaría dedicar una serie de artículos a algunas de las consideraciones sobre el diseño de soluciones en SharePoint, el en titulo olvide mencionar que me voy a centrar básicamente en el área empresarial.</p>
<p><b>FeedBack</b></p>
<p>Uno de los aspectos que considero más importante es el feedback de los usuarios. Como mencione anteriormente muchos de sus problemas a veces se resuelven con imaginación y creatividad, siempre hay que estar atentos a lo que dicen los usuarios. </p>
<p>Por ello una de las partes principales de un desarrollo en SharePoint, puede comenzar por un simple foro de discusión en donde los usuarios puedan dejar sus opiniones tanto críticas como de mejora. </p>
<p>Evidentemente aquí no hay mucho de diseño, pero esto será un pilar fundamental si se hace un buen uso del mismo.</p>
<p>Para poder categorizar los temas que se tratarán en el foro, a la lista se le puede añadir un tipo de contenido o un campo que contenga los diversos asuntos a los que hace relación un post, así como otro campo que indique si el post es referente a una crítica o a una mejora.</p>
<p>En la mayoría de las organizaciones dinamizar un simple foro como este suele ser un problema si no existe una cultura de colaboración, en ocasiones a la gente le da vergüenza comentar cosas, pensando que lo único que van a decir son estupideces, bien, esto es una labor interna en la que hay que concienciar a la gente (y este es un buen punto de arranque) aludir a que jamás mejoraran las herramientas de las que disponen si ellos no hacen nada por mejorarlas; atacar ese pequeño orgullo que todos tenemos, tocar esa fibra, suele dar un buen resultado.</p>
<p>Esto tiene su contrapartida, si el usuario se expresa y pide cosas hay que dárselas (y rápido) si no toda labor anterior habrá caído en balde. Por parte del departamento de IT, habrá que valorar las peticiones de los usuarios y como mencione (y no dejaré de mencionar en lo sucesivo) deberemos realizar una valoración de dichas mejoras de modo que podamos encontrar quórum para llevarlas a cabo y que encajen en tiempo, coste y complejidad.</p>
<p>Según mi experiencia, el usuario tiende a pedir en ocasiones cosas como ¿no podríamos tener un botón aquí que hiciera tal o cual cosa?, nosotros tenemos que pensar en que es lo que el usuario quiere hacer realmente, ¿Por qué, quiere hacerlo?, ¿Qué ventajas encuentra en ello? Y de qué modo podemos ofrecerle algo que le ayude sin que ello suponga demasiada complejidad; Igual el botón no pude estar allí, pero tal vez podamos poner un hipervínculo aquí para hacer lo mismo o casi lo mismo.</p>
<p>El vocabulario del usuario y el nuestro es distinto, hay que hacer un esfuerzo por entenderle, comprenderle y dar a entender lo que nosotros podemos hacer por él.</p>
<p>Una pequeña encuesta en donde los usuarios voten ó valoren las mejoras, puede ser de gran ayuda a la hora de determinar por dónde empezar, así como de tener una idea de a cuanta gente vamos a contentar y/o enfadar con la realización de los cambios.</p>
<p>Un escenario como este puede complicarse todo lo que uno quiera, pero en la práctica debe ser algo sencillo, empecemos dando algo con lo que todos podamos trabajar, un foro en SharePoint y dos o tres campos personalizados (diseño 0%, evangelización y concienciación sobre el uso 100%) pongámoslo en marcha y escuchemos a nuestros usuarios, <u>ellos tienen cosas importantes que decir.</u></p>
<p><b>Vigilancia del Entorno</b></p>
<p>La rapidez con que una empresa sea capaz de reaccionar a los acontecimientos de su entorno, es una medida de los reflejos corporativos.</p>
<p>Sin duda es una parte muy importante, vigilar nuestro entorno; diseñar un portal de vigilancia del entorno dentro de una empresa es algo que aporta gran valor. Hace algún tiempo ayude a un amigo a realizar un portal de vigilancia del entorno y tuve la oportunidad de aprender algunas cosas importantes.</p>
<p>Gracias a internet tenemos a nuestro alcance una ingente cantidad de datos, muchos de ellos nos pueden ayudar a ver qué es lo que está ocurriendo en nuestro entorno, pero identificar la información que nos es útil entre tantos datos puede ser un problema.</p>
<p>Cuando mi amigo me pidió ayuda él había hecho gran parte del trabajo, el había buscado las fuentes de datos que consideraba más relevantes para el entorno de su empresa, clientes, proveedores, mercado, producto, marketing, competencia, tendencias y noticias del sector, incluso encontró algunos foros donde se mencionaba su empresa, todo ello estaba dentro de un site en donde había usado el web part de transformación de XSLT, para recuperar las feeds que él había considerado importantes y poderlas visualizar en varias páginas en función de las distintas categorías a las que hacían referencia.</p>
<p>El site, era útil, de un plumazo tenia agregadas muchas de las noticias que eran relevantes para la empresa, sin embargo la gran cantidad de noticias apabullaba a los usuarios; la gente entraba veía la ingente cantidad de noticias, leía una o dos y salía.</p>
<p>El site resolvía un problema, pero desde luego no lo hacía de la mejor manera posible, pero había algo por dónde empezar lo cual es como ya hemos comentado, bueno. </p>
<p>Le sugerí, que antes de hacer nada, hablara con los usuarios y les preguntará como se podría mejorar el site de vigilancia, tras unas cuantas sugerencias (feedback) por parte del personal de la empresa, había varios puntos en común, la focalización (o audiencia) de la información y la posibilidad de escalar noticias.</p>
<p><u>La focalización de la información</u> hace referencia al hecho de donde se debe encontrar la información,&nbsp; en vez de tener un site en donde concentrar toda la información, los usuarios opinaban que era mejor que cada web de departamento se viese un resumen de esas noticias, de este modo se orienta la información a una audiencia determinada.</p>
<p>En segundo lugar, debería existir un mecanismo de <u>escalar las noticias importantes</u>; cuando se cuenta con mucha información alguien debe poner está en su contexto, y valorarla de manera adecuada. En la empresa de mi amigo fabrican piezas con plásticos inyectados, de modo que la invención de un nuevo compuesto o mecanismo puede parecerle muy importante a la gente de producto pero a alguien de dirección un artículo más bien técnico puede parecerle intrascendente o un autentico coñazo. De modo que la información ha de ser valorada por alguien de las trincheras que la ponga en su contexto y le de la importancia que debe tener y luego la transmita dentro de su contexto al resto de la organización.</p>
<p>Eso dio pie a la creación de un site DAFO, (Debilidades, Amenazas, Fortalezas y Oportunidades).</p>
<p>Se hicieron los cambios necesarios para que cada departamento visualizara la información pertinente a su área, y como complemento de esa información con un simple click se podía llevar la información del agregador de noticias al sistema DAFO, con eso la noticia podía crear una alerta en el sistema, periódicamente se examina el site DAFO y se toman decisiones en función del contenido.</p>
<p>En un primer momento el sistema funcionaba de manera manual, es decir junto a cada noticia existía un enlace a la web DAFO, en donde el usuario debía crear un breve resumen de la noticia, el tipo de alerta Debilidad, Amenaza, Fortaleza o Oportunidad y un comentario personal de ¿Por qué? Se contempla la noticia como una alerta.</p>
<p>La gerencia de la empresa usa la web de DAFO de forma periódica en una reunión quincenal de seguimiento de diversos asuntos, se analizan todas las alertas y se hace un pequeño acta que se deja en ese mismo sitio. </p>
<p>Más adelante cuando el sistema demostró su utilidad, se mejoró sustancialmente incluyendo algo de programación y ahora permite que tras valorar la noticia, esta incluya un enlace a la fuente original, también el site DAFO cuenta ahora con una serie de gráficos y resúmenes quincenales de las alertas que se han producido así como una lista por cada departamento que permite introducir las fuentes desde donde cada departamento va a recibir las noticias así como los filtros que ha de pasar el contenido para ser agregado; de este modo se su pueden añadir y suprimir fuentes y filtros sin necesidad de programar absolutamente nada.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-2/feed</wfw:commentRss>
		<slash:comments>500</slash:comments>
		</item>
		<item>
		<title>Cuestiones sobre el diseño de soluciones en SharePoint (1)</title>
		<link>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-1</link>
		<comments>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-1#comments</comments>
		<pubDate>Mon, 20 Jul 2009 20:58:14 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Cuestiones-sobre-el-diseno-de-soluciones-en-SharePoint-(1).aspx</guid>
		<description><![CDATA[Una de las incuestionables capacidades de SharePoint, es la de poderse adaptarse rápidamente a muchas de las problemáticas que surgen en las empresas. Sin embargo a la hora de diseñar estas soluciones no todo es tan sencillo, con esto me estoy refiriendo al hecho de que nos encontramos en innumerables ocasiones con problemáticas empresariales que [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las incuestionables capacidades de SharePoint, es la de poderse adaptarse rápidamente a muchas de las problemáticas que surgen en las empresas. </p>
<p>Sin embargo a la hora de diseñar estas soluciones no todo es tan sencillo, con esto me estoy refiriendo al hecho de que nos encontramos en innumerables ocasiones con problemáticas empresariales que no son excesivamente complejas pero que sin embargo a la hora de trasladarlas a SharePoint, se convierten en un verdadero infierno.</p>
<p>Durante estos años que llevo trabajando con SharePoint, me he encontrado con multitud de casos en los que cosas que parecían relativamente sencillas por que el 80% del trabajo ya estaba hecho, funcionalidades que de por sí contempla SharePoint el 20% restante ha supuesto una cantidad de trabajo terrible. Donde ese 20% has supuesto una cantidad de tiempo y un coste tan elevado que es casi imposible de justificar.</p>
<p>Vamos a dejar al margen las ocasiones en que el diseño de una solución debe ser estrictamente fiel a un procedimiento empresarial, y debe reflejar de manera completa y exacta dicho procedimiento; en este punto la postura es clara; tendremos que hacer lo que sea para que la solución cumpla al 100% los requerimientos del procedimiento.</p>
<p>En el resto de ocasiones, tenemos la disyuntiva de hasta qué punto debemos ser flexibles en el desarrollo de la solución. Según mi experiencia debemos ser flexibles y agiles. </p>
<p>Muchos de estos procesos requieren que seamos agiles, no podemos esperar meses a tener una herramienta para poder gestionar eficazmente. A esto debemos añadir el hecho de que muchos de estos procesos están vivos, es decir se empieza haciendo cosas de una manera, y tras evaluaciones sucesivas del procedimiento así como de la experiencia que se va adquiriendo del uso del mismo, se va optimizando, suprimimos, añadimos y cambiamos pasos, información y flujos de la información. </p>
<p>Tenemos que contemplar el diseño como una negociación Win-to-Win, en donde todos ganamos por una parte tendremos que adaptar los requisitos o los procedimientos para que estos sin perder en esencia su objetivo sean los menores para no tener que realizar complejos sistemas para sustentarlos. De esta manera y solo de esta manera seremos capaces de diseñar sistemas cuyo ROI, sea positivo desde el comienzo.</p>
<p>En esta negociación, se deben poner sobre la mesa los requerimientos y los recursos de que disponemos para trasladar estos a la plataforma. </p>
<p>Un sencillo ejercicio de ponderación, donde valoramos los requisitos de modo que los que más valor aportan tendrán una puntuación más elevada y los que menos valor aportan una puntuación inferior y del mismo modo, evaluamos la complejidad que entrama desarrollar cada una de las partes del sistema, valorando en términos de tiempo, coste y complejidad cada uno de los pasos necesarios para cumplimentar dichos requisitos.</p>
<p>A través de un ejercicio de esta índole, debemos suprimir todo aquello que en esencia sea superfluo y buscar alternativas a aquellas partes del sistema que por su tiempo, coste o complejidad vayan a ser cuellos de botella tanto en el uso como en el desarrollo de las mismas.</p>
<p>Otro punto importante, es el de la rapidez; cuanto antes demos a nuestros usuarios una herramienta y algo básico con lo que trabajar empezaremos a recibir feedback que deberemos tener en cuenta, muchas de las propuestas del usuario final son imaginativas y creativas (y generalmente más baratas).</p>
<p>En muchas ocasiones esto conlleva exprimir lo que tenemos al máximo, más adelante siempre tendremos oportunidades de realizar esas complejas partes que harán de nuestra solución una solución perfecta.</p>
<p>En próximos posts me gustaría comentar algunas experiencias tanto mías como de algunos colegas sobre el diseño de soluciones con SharePoint. </p>
<p><b>Cualquier comentario o aportación será bienvenido.</b></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/cuestiones-sobre-el-diseno-de-soluciones-en-sharepoint-1/feed</wfw:commentRss>
		<slash:comments>204</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (3) in CodePlex</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex#comments</comments>
		<pubDate>Tue, 26 May 2009 23:47:39 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(3)-in-CodePlex.aspx</guid>
		<description><![CDATA[Bueno, esta es la última entrega a partir de hoy el proyecto se encuentra en CodePlex (yacamlqt.codeplex.com).En esta última parte solo unas pequeñas notas para el usuario final.Bien, para usar YACAMLQT, dentro de tus proyectos, solo hay que referenciar la dll (IdeSeg.SharePoint.Caml.QueryParser.dll)&#160; y el uso sería el siguiente: 1: try 2: { 3: var parser [...]]]></description>
			<content:encoded><![CDATA[<p>Bueno, esta es la última entrega a partir de hoy el proyecto se encuentra en CodePlex (<FONT color=#ff0000><B><A href="http://yacamlqt.codeplex.com/">yacamlqt.codeplex.com</A></B></FONT>).<BR><BR>En esta última parte solo unas pequeñas notas para el usuario final.<BR><BR>Bien, para usar YACAMLQT, dentro de tus proyectos, solo hay que referenciar la dll (<B>IdeSeg.SharePoint.Caml.QueryParser.dll</B>)&nbsp; y el uso sería el siguiente:<BR><BR><BR><br />
<P></P><!-- code formatted by http://manoli.net/csharpformat/ --><br />
<DIV class=csharpcode><PRE class=alt><SPAN class=lnum>   1:  </SPAN>            <SPAN class=kwrd>try</SPAN></PRE><PRE><SPAN class=lnum>   2:  </SPAN>            {</PRE><PRE class=alt><SPAN class=lnum>   3:  </SPAN>                var parser = <SPAN class=kwrd>new</SPAN> NParser(textTSql, <SPAN class=kwrd>new</SPAN> ASTNodeCAMLFactory());</PRE><PRE><SPAN class=lnum>   4:  </SPAN>                var generator = <SPAN class=kwrd>new</SPAN> CodeGenerator(parser.Parse());</PRE><PRE class=alt><SPAN class=lnum>   5:  </SPAN>                generator.Generate();</PRE><PRE><SPAN class=lnum>   6:  </SPAN>                <SPAN class=kwrd>return</SPAN> _formatTools.FormatXml(generator.Code);</PRE><PRE class=alt><SPAN class=lnum>   7:  </SPAN>            }</PRE><PRE><SPAN class=lnum>   8:  </SPAN>            <SPAN class=kwrd>catch</SPAN> (ParserException ex)</PRE><PRE class=alt><SPAN class=lnum>   9:  </SPAN>            {</PRE><PRE><SPAN class=lnum>  10:  </SPAN>                _view.Status = ex.Message;</PRE><PRE class=alt><SPAN class=lnum>  11:  </SPAN>            }</PRE><PRE><SPAN class=lnum>  12:  </SPAN>            <SPAN class=kwrd>catch</SPAN> (ScannerException ex)</PRE><PRE class=alt><SPAN class=lnum>  13:  </SPAN>            {</PRE><PRE><SPAN class=lnum>  14:  </SPAN>                _view.Status = ex.Message;</PRE><PRE class=alt><SPAN class=lnum>  15:  </SPAN>            }</PRE></DIV><br />
<P>Instanciamos el Parser (<B>NParser</B>), le pasamos la consulta en TSQL (<B>textSql</B>) y la factoría correspondiente a lo que queremos generar, por el momento solo está disponible la de <B>CAML</B>, en breve completaré la de <B>CAML.Net</B>; Por último inyectamos el Parser en el Generador de código, llamamos al método <B>Generate</B> y recogemos la consulta en CAML en <B>generator.Code</B>.</P><br />
<P><BR>Las posibles excepciones tanto del Parser como del generador de código se pueden atrapar con <B>ParserException</B> y <B>ScannerException</B>.</P><br />
<P><BR>En el proyecto se incluye un pequeño subproyecto con una interfaz WinForms (no es que se me de especialmente bien)<BR><BR></P><br />
<DIV align=center><IMG src="http://oldblog.ideseg.com/content//YACAMLQT_Sample_Gui.PNG" border=0><BR><BR><B><A href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux2.aspx">Parte 2 http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux2.aspx</A></B><BR><B><A href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx">Parte 1 http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx</A></B><BR></DIV></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-3-in-codeplex/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (2)</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2#comments</comments>
		<pubDate>Fri, 22 May 2009 09:50:52 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(2).aspx</guid>
		<description><![CDATA[Continuando con la explicación del código de YACAMLQT. Habíamos visto la parte relacionada con el Lexer el analizador morfológico. Como es obvio detrás debe haber un analizador sintáctico y semántico el Parser. El analizador sintáctico y semántico (NParser) se ha implementado siguiendo el patrón interpeter, (seguramente sea uno de los que menos se ven), el [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando con la <a href="http://www.ideseg.com/YACAMLQTYetAnotherCAMLQueryToolRedux1.aspx">explicación del código de YACAMLQT</a>.</p>
<p>Habíamos visto la parte relacionada con el Lexer el analizador morfológico. Como es obvio detrás debe haber un analizador sintáctico y semántico el <a href="http://en.wikipedia.org/wiki/Parsing">Parser</a>.</p>
<p>El analizador sintáctico y semántico (<b>NParser</b>) se ha implementado siguiendo el patrón interpeter, (<i>seguramente sea uno de los que menos se ven</i>), el objetivo es obtener los distintos Tokens desde el Scanner y montar un árbol sintáctico (<a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">AST</a>) este árbol contiene Nodos (<b>ASTNodeBase</b>) y estos nodos representan de manera abstracta y simplificada la estructura sintáctica de la consulta en SQL.</p>
<p>(diagrama NParser)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_nparser.gif" border="0" width="467" height="445"></div>
<p>A la clase <b>NParser </b>se le puede inyectar una factoria (<b>ASTNodeFactoryBase</b>) en función del código que queramos generar, por el momento solo esta implementado el CAML, pero se puede extender sencillamente para generar <a href="http://www.codeplex.com/camldotnet">CAML.Net</a>.</p>
<p>Partiendo de un nodo abstracto (<b>ASTNodeBase</b>) podemos definir las distintas unidades sintácticas, por medio de la herencia. Estos nodos abstractos (heredados de <b>ASTNodeBase </b>) conforman las distintas expresiones que se usan en el analizador sintáctico y semántico (<b>NParser</b>), para ello se ha definido una clase para cada uno de los Tokens a modo de plantilla (template),&nbsp; y estas clases son a su vez son las distintas expresiones abstractas, que se usan en&nbsp; el patrón interpreter implementado en el parser. (<b>NParser</b>).</p>
<p>Todos estos nodos que forman las expresiones abstractas al fin al cabo son plantillas (templates), y podrían a su vez ser clases abstractas, yo opte por una implementarlas como clases normales. Ya que algunos de los nodos son terminales y otros intermedios y no tienen por qué ser heredados, de este modo la factoria base (<b>ASTNodeFactoryBase</b>) usa miembros virtuales parar crear dichos nodos.</p>
<p>(diagrama parcial de ASTNodeBase)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_ast.gif" border="0"></div>
<p>Para crear todos estas expresiones abstractas existe una factoría abstracta (<b>ASTNodeFactoryBase </b>) a través de la cual creamos los distintos nodos. Como puede verse, para añadir una variante como <a href="http://www.codeplex.com/camldotnet">CAML.Net</a>, solamente hay que añadir las expresiones abstractas heredando de las ya existentes e implementando <b>PreCode()</b> y <b>PostCode()</b>. </p>
<p>Todos estos nodos que forman las expresiones abstractas al fin al cabo son plantillas (templates), y podrían a su vez ser clases abstractas, yo opte por una implementarlas como clases normales, debido a que algunos de los nodos son terminales y otros intermedios y no tienen por qué ser heredados, de este modo la factoria base (<b>ASTNodeFactoryBase</b>) usa miembros virtuales parar crear dichos nodos terminales e intermedios.</p>
<p>Después para poder inyectar en el parser dichas expresiones debemos crear una nueva factoría heredada de la factoría base (ASTNodeFactoryBase).</p>
<p>(diagrama ASTNodeFactoryBase)
<div align="center"><img src="http://oldblog.ideseg.com/content//yacamlqt_nodefactory.gif" border="0"></div>
<p>Para generar CAML lo que he hecho es heredar de cada plantilla ó expresión abstracta definida, una nueva clase que redefine los métodos virtuales <b>PreCode()</b> y <b>PostCode()</b> que son los encargados de sustituir cada nodo del árbol sintáctico en CAML.</p>
<p>Y crear una factoría (<b>ASTNodeCAMLFactory</b>) que se encarga de crear las expresiones.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YACAMLQT (Yet another CAML query tool) Redux (1)</title>
		<link>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1</link>
		<comments>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1#comments</comments>
		<pubDate>Mon, 27 Apr 2009 13:26:05 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[caml]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/YACAMLQT-(Yet-another-CAML-query-tool)-Redux-(1).aspx</guid>
		<description><![CDATA[Hace un mes, John Holliday, me pidió a ver si podíamos integrar su CAML.net con mi YACAMLQT, a la vez que ampliar mi herramienta para soportar otro tipo de consultas como adds y updates. YACAMLQT, es una utilidad que convierte una sentencia SQL en CAML, el lenguaje de consulta de Sharepoint. (Véase YACAMLQT, YACAMLQT2 y [...]]]></description>
			<content:encoded><![CDATA[<p>Hace un mes, <a href="http://www.johnholliday.net/">John Holliday</a>, me pidió a ver si podíamos integrar su <a href="http://www.codeplex.com/camldotnet">CAML.net</a> con mi <b><a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryTool2.aspx">YACAMLQT</a></b>, a la vez que ampliar mi herramienta para soportar otro tipo de consultas como adds y updates.</p>
<p>YACAMLQT, es una utilidad que convierte una sentencia SQL en CAML, el lenguaje de consulta de Sharepoint. (Véase <a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryToolAlaSQL.aspx">YACAMLQT</a>, <a href="http://www.ideseg.com/SharePointYetAnotherCAMLQueryTool2.aspx">YACAMLQT</a>2 y <a href="http://www.ideseg.com/SharePointCAMLNetGenial.aspx">YACAMLQT-CAML.Net</a>)</p>
<p>Estos días entre rato bueno y rato malo, he reescrito totalmente el código de YACAMLQT, para hacerlo más sencillo (por supuesto usando TDD), en principio el objetivo ha sido emular el antiguo YACAMLQT, pero dotándolo de un diseño más sencillo y ampliable.</p>
<p>YACAMLQT, es un programa que convierte una sintaxis tipo SQL en CAML (el lenguaje de consulta de SharePoint).</p>
<p>Es decir esto: 
<p class="style1"><font face="Courier New"><font size="2"><font color="#000080"><strong><span class="style2">WHERE</span> </strong>((Column1 = &#8220;Value1&#8243;) <span class="style2"><strong>AND</strong></span> (Column2 = &#8220;Value2&#8243;)) <span class="style2"><strong>OR</strong></span> ((Column3 = 10) <br /></font></font></font><font face="Courier New"><font size="2"><font color="#000080"><span class="style2"><strong>AND</strong></span> (Column3 &lt;&gt; NULL)) <span class="style2"><strong>GROUPBY</strong></span> Column1 <span class="style2"><strong>ORDERBY</strong></span> Column1, Column2 <span class="style2"><strong>ASC</strong></span>, Column3 <span class="style2"><strong>DESC</strong></span></font></font></font></p>
<p>En esto:</p>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">&lt;</span><span class="html">Query</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">Where</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">Or</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Text"</span><span class="kwrd">&gt;</span>Value1<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column2"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Text"</span><span class="kwrd">&gt;</span>Value2<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">      <span class="kwrd">&lt;/</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">          <span class="kwrd">&lt;</span><span class="html">Value</span> <span class="attr">Type</span><span class="kwrd">="Integer"</span><span class="kwrd">&gt;</span>10<span class="kwrd">&lt;/</span><span class="html">Value</span><span class="kwrd">&gt;</span></pre>
<pre>        <span class="kwrd">&lt;/</span><span class="html">Eq</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;</span><span class="html">IsNotNull</span><span class="kwrd">&gt;</span></pre>
<pre>          <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">        <span class="kwrd">&lt;/</span><span class="html">IsNotNull</span><span class="kwrd">&gt;</span></pre>
<pre>      <span class="kwrd">&lt;/</span><span class="html">And</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;/</span><span class="html">Or</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">Where</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;</span><span class="html">GroupBy</span><span class="kwrd">&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">  <span class="kwrd">&lt;/</span><span class="html">GroupBy</span><span class="kwrd">&gt;</span></pre>
<pre>  <span class="kwrd">&lt;</span><span class="html">OrderBy</span><span class="kwrd">&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column1"</span> <span class="kwrd">/&gt;</span></pre>
<pre>    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column2"</span> <span class="attr">Ascending</span><span class="kwrd">="True"</span> <span class="kwrd">/&gt;</span></pre>
<pre class="alt">    <span class="kwrd">&lt;</span><span class="html">FieldRef</span> <span class="attr">Name</span><span class="kwrd">="Column3"</span> <span class="attr">Ascending</span><span class="kwrd">="False"</span> <span class="kwrd">/&gt;</span></pre>
<pre>  <span class="kwrd">&lt;/</span><span class="html">OrderBy</span><span class="kwrd">&gt;</span></pre>
<pre class="alt"><span class="kwrd">&lt;/</span><span class="html">Query</span><span class="kwrd">&gt;</span></pre>
</div>
<p>El proyecto completo lo subiré a <b>CodePlex</b> en unos días, con su código fuente que poco a poco y con ayuda espero ir ampliando.</p>
<p>Por si alguien quiere echar una mano en el proyecto, voy a contar alguno de los entresijos del diseño de la aplicación.</p>
<p>Lo primero que he diseñado es el analizador morfológico (<i>lexer</i>) que se encarga de identificar dentro de un string, las distintas unidades sintácticas (<i>tokens</i>) con las que construiremos un analizador sintáctico y semántico (<i>parser</i>) con el cual construiremos un árbol sintáctico (<i>AST</i>) que por último recorreremos para transformar el SQL en CAML u otra variante como CAML.Net.</p>
<p>El lexer, está compuesto por una clase base, <b>ScannerBase </b>que contiene las partes más básicas del lexer, he extraído esta clase base una vez que tenía el analizador morfológico completo ya que de esta manera podemos realizar otro tipo de analizadores. </p>
<p><img src="http://oldblog.ideseg.com/content//yacamlqt_lexer.gif" border="0"></p>
<p>Las funciones básicas como comerse los espacios (<b>EatSpaces</b>()), detectar si es el final de línea (<b>EndOfLine</b>()) , saltar caracteres (<b>SkipChar</b>()) son parte de ScannerBase. Lo más importante de esta clase es la propiedad <b>CurrentChar </b>que devuelve el último carácter leído y el método <b>GetCharMoveNext</b>(), que obtiene un carácter y se mueve a la siguiente posición.</p>
<p>Para los que habéis usado el unix <a href="http://es.wikipedia.org/wiki/Herramienta_de_programaci%C3%B3n_lex">flex</a>, <b>GetCharMoveNext</b>() es similar a <b>input</b>().</p>
<p>Esta clase <b>ScannerBase </b>utiliza internamente una clase <b>ScannerState </b>que mantiene el estado para poder releer un token ó unidad sintáctica. </p>
<p>Los tokens en el caso de YACAMLQT, consisten en las palabras reservadas propias de SQL, así como los distintos operadores, los campos y los valores (<i>cadena, fecha, lógico y numérico</i>). </p>
<p>A diferencia del unix <a href="http://es.wikipedia.org/wiki/Herramienta_de_programaci%C3%B3n_lex">flex</a>, esto no se trata de un <b>unput</b>(), ya que mediante este volveríamos al carácter anterior. En este caso, como lo importante del analizador es obtener una unidad sintáctica, o token, lo que he hecho es implementar un método llamado <b>BackToken</b>() que lo que hace es posicionar el lexer justo al comienzo del último token obtenido, de modo que <b>GetToken</b>() volverá a devolvernos el mismo token.</p>
<p>La clase <b>Scanner</b>, hereda como es de suponer de <b>ScannerBase</b>, e implementa <b>GetToken</b>(), el responsable de de devolver un token, y <b>CheckCorrectBracketsAndQuotes</b>() que es el responsable de comprobar que los paréntesis y las comillas están correctamente.</p>
<p>Dentro de la clase <b>Scanner</b>, el método <b>GetToken</b>() es el responsable de identificar cada uno de los tokens, para lo cual he realizado un método para identificar cada uno de los distintos tokens. <b>GetToken</b>() usa los métodos <b>ScanDate</b>(), <b>ScanString</b>(), <b>ScanOperator</b>(), <b>ScanNumber</b>() y <b>ScanReservedWordOrSymbol</b>().</p>
<p><b>ScanOperator</b>() y <b>ScanReservedWordOrSymbol</b>() usan un diccionario para identificar los distintos operadores y palabras reservadas. En el caso de <b>ScanReservedWordOrSymbol</b>(), si el token leído no se encuentra en el diccionario de palabras reservadas estaremos identificando un símbolo ó identificador.</p>
<p>Para terminar con esta primera parte, y siguiendo el principio de responsabilidad única, se ha implementado la clase <b>Token </b>como un contenedor y <b>TokenFactory </b>como una factória encargada de crear los distintos tipos de tokens ó unidades sintácticas. La clase<b> Scanner</b> es la que usa la factória para crear los distintos Tokens.</p>
<p><img src="http://oldblog.ideseg.com/content//yacamlqt_token.gif" border="0"></p>
<p>La clase <b>Token</b>, puede contener los distintos tipos de tokens, en principio todos aunque pueden ser de diferentes tipos, mantendrán su valor como un string. El resto de propiedades para identificar el tipo de token (<b>TType</b>) ó el tipo de valor (<b>ValueType</b>) son una enumeración.</p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2009/yacamlqt-yet-another-caml-query-tool-redux-1/feed</wfw:commentRss>
		<slash:comments>355</slash:comments>
		</item>
		<item>
		<title>Testeo unitario para SharePoint: La importancia de llamarse &#8220;Test&#8221;</title>
		<link>http://oldblog.ideseg.com/2008/testeo-unitario-para-sharepoint-la-importancia-de-llamarse-test</link>
		<comments>http://oldblog.ideseg.com/2008/testeo-unitario-para-sharepoint-la-importancia-de-llamarse-test#comments</comments>
		<pubDate>Mon, 01 Dec 2008 21:34:49 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[net]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Testeo-unitario-para-SharePoint-La-importancia-de-llamarse-Test-.aspx</guid>
		<description><![CDATA[Testing es algo que todos los desarrolladores deberíamos hacer, y muy pocos hacen. Por no decir “Testing intensivo y consecuente”, pues los números se reducen a prácticamente cero&#8230; si le da curiosidad, revise las estadísticas mostradas en: http://www.methodsandtools.com/dynpoll/oldpoll.php?UnitTest2 http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx http://telerikwatch.com/2008/05/survey-says-unit-testing-still-not.html. Especialmente el segundo vinculo es interesante, aunque por experiencia propia me arriesgaría a decir que [...]]]></description>
			<content:encoded><![CDATA[<p><P>Testing es algo que todos los desarrolladores deberíamos hacer, y muy pocos hacen. Por no decir “<STRONG>Testing intensivo y consecuente</STRONG>”, pues los números se reducen a prácticamente cero&#8230; si le da curiosidad, revise las estadísticas mostradas en:</P><br />
<UL><br />
<LI><A href="http://www.methodsandtools.com/dynpoll/oldpoll.php?UnitTest2">http://www.methodsandtools.com/dynpoll/oldpoll.php?UnitTest2</A></LI><br />
<LI><A href="http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx">http://blog.davebouwman.net/2008/06/04/DeveloperSurveyUnitTestingAmpOtherTools.aspx</A> </LI><br />
<LI><A href="http://telerikwatch.com/2008/05/survey-says-unit-testing-still-not.html">http://telerikwatch.com/2008/05/survey-says-unit-testing-still-not.html</A>. </LI></UL><br />
<P>Especialmente el segundo vinculo es interesante, aunque por experiencia propia me arriesgaría a decir que los porcentajes de aplicación de testeo son mucho, mucho mas bajos.</P><br />
<P>Siendo sincero, escribir software es una de las cosas más divertidas para hacer en el mundo (lo digo por deformación profesional, probablemente), pero hacer pruebas para ese mismo software es una de las más aburridas. Y en algunos casos, es simplemente imposible, como lo es hacer pruebas para SharePoint. </P><br />
<P>Pero para comenzar por el principio, hay que hablar algo sobre testing en general.</P><br />
<P>El mundo del testing es amplio y ajeno: hay tantos tipos de testeo como tipos de desarrolladores&#8230; pero mirándolo desde una perspectiva global, podemos decir que hay:</P><br />
<P><STRONG>- “Unit Test” (Prueba unitaria)</STRONG> – verifica que las unidades individuales de código fuente funcionan como se espera. Normalmente la unidad de código más pequeña es una función, método o propiedad.<BR>- <STRONG>“Regression Test” (Pruebas de regresión)</STRONG> – Cuando se modifica algo que ya ha sido probado que funciona (con el Unit Test), es necesario garantizar que sigue funcionando apropiadamente después de algún tiempo: este es el trabajo de Regression Test<BR>- <STRONG>“Integration Test” (Pruebas de Integración)</STRONG> – Cuando todas las unidades (que ya han sido probadas con Unit y Regression Test) se unen para trabajar conjuntamente, es necesario garantizar que todas funcionen como una unidad apropiadamente. Este es el trabajo del Integration Test<BR>- <STRONG>“System Integration Test” (Pruebas de Integración de sistemas) </STRONG>– puede ser visto como una ampliación del anterior: este test garantiza que nuestro sistema (que ya ha sido probado con Unit, Regression e Integration Tests) puede funcionar con otros sistemas externos apropiadamente</P><br />
<P>En cuanto a metodologías, mis dos hermanas sicólogas me enseñaron que hay tres tipos de pruebas: Black Box, White Box y Grey Box testing (el modelo ha sido tomado “prestado” de la psicología).</P><br />
<P>- <STRONG>“Black Box Testing”</STRONG> – la prueba no sabe nada sobre cómo funciona internamente el sistema a probar&#8230; solamente que si se le entregan algunos parámetros de entrada, deben salir algunos resultados. Black Box Testing le entrega parámetros a una función (correctos e incorrectos) y observa los resultados que la función devuelve<BR>- <STRONG>“White Box Testing”</STRONG> – por el contrario, la prueba conoce perfectamente el funcionamiento interno del sistema a probar, y crea las pruebas basado en el.<BR>-<STRONG> “Grey Box Testing”</STRONG> – ya se imaginaran lo que es, una mezcla de los dos.</P><br />
<P>Finalmente, es necesario hablar de algo que está de moda, “Test-driven development” (TDD). Esta es una técnica de programación basada en escenarios de prueba o de funcionamiento (Test o User Cases), bastante ligada a metodologías de desarrollo como Agiles, que indica que primero hay que hacer el diseño del software (sus clases, métodos, propiedades y eventos), luego generar las definiciones (el “esqueleto” del código), luego crear los métodos de prueba ANTES que el código mismo, y finalmente, crear el código para rellenar el esqueleto.</P><br />
<P>Bien, esto es más o menos la parte teórica. Como los desarrolladores de código que somos, ¿Qué es lo importante de todo esto?</P><br />
<OL><br />
<LI>Primero que todo, y antes que nada, Unit Test. Unit Test me permite dormir tranquilo, pues me asegura que mi código funciona correctamente y seguirá funcionando después de que lo he modificado (¿se puede usar Unit Test como Regression Test? Esta es una discusión bizantina a la que nunca nadie llega a una conclusión, algo por el estilo a que es mejor CSharp o Visual Basic, o Windows o Linux. Vea por la ejemplo la discusión que surgió en el ultimo PDC al respecto en <A href="http://channel9.msdn.com/pdc2008/TL61/">http://channel9.msdn.com/pdc2008/TL61/</A>).</LI><br />
<LI>Como segunda medida, si se está usando (o se quiere usar) TDD, la decisión de usar Black o White Test es importante&#8230; o, mejor dicho, si se quiere usar TDD, hay que usar Black Box Testing. Punto. O hay que iniciar una nueva discusión bizantina sobre si es posible iniciar el desarrollo en Black Box y luego continuarlo en White Box, lo que lleva al modelo de Grey Box&#8230;</LI></OL><br />
<P>Noten que hasta ahora he intentado no tomar partido por ninguno de los puntos mencionados. Todo porque mi punto es SharePoint, no discusiones teológicas sobre cómo, cuando y donde hacer testeo de software. Pero llegamos a la parte interesante: <STRONG>SharePoint.</STRONG></P><br />
<P>Cuando se trata de crear Testeo Unitario para software creado por uno mismo, es decir, en donde se tiene el código fuente, construir las clases de prueba es largo y tedioso, pero es posible de hacer con las herramientas estándar para el efecto (como las que tiene Visual Studio mismo, por ejemplo). Cuando lo que se desea es testear código que utiliza el Modelo de Objetos de otro programa, como ocurre cuando se escribe software para SharePoint o cualquier otro servidor (<EM>SQL, Exchange, BizTalk, etc</EM>), es necesario “hacerle creer” a nuestro código que esta interactuando con el servidor, pero sin que lo haga en realidad, porque no se desean tener dependencias con él.</P><br />
<P>Imagínese una situación no tan hipotética: se crea un método que comprueba los derechos de una Librería de SharePoint; si se utiliza una instalación real de SharePoint para hacer las pruebas, es necesario mantener esa configuración por todo el tiempo del desarrollo y mas allá para garantizar que los resultados de las pruebas sean consistentes en el tiempo. Peor aún, todos los desarrolladores del grupo tienen que disponer de la misma instalación para que sus pruebas también sean consistentes entre desarrolladores. Esto es prácticamente imposible de conseguir y, además, muy engorroso. Para solucionar el problema existen diferentes tipos de herramientas que “falsifican” el Modelo de Objetos del servidor (Mockers, Stubbers, etc)</P><br />
<P>Como ya hemos dicho varias veces Carlos y yo, el problema con SharePoint y Unit Test es que el Modelo de Objetos de SharePoint tiene muchas clases selladas o sin constructor público. Este ha sido el gran problema hasta ahora para poder usar Mockers y Stubbers, pues ellos no saben qué hacer con un objeto sellado o sin constructor público. El posting “<A href="http://www.ideseg.com/TesteoUnitarioParaSharePointAcercandoseALaRespuestaDefinitivaParte1.aspx">Testeo Unitario para SharePoint: acercándose a la respuesta definitiva – parte 1</A>”&nbsp;que escribimos anteriormente comenzó a mostrar cómo se puede iniciar el testeo unitario para SharePoint usando la última versión de <A href="http://www.typemock.com">TypeMock</A>. Las próximas partes continuaran con la parte práctica de la creación y codificación de las clases de prueba. Pero en esta segunda parte <STRONG>se trata de discutir la importancia de Unit Test, Regression Test, Black y White Box Testing y TDD</STRONG>.</P><br />
<P>Uno de las características más importantes de <A href="http://www.typemock.com">TypeMock</A> es la relación intrínseca entre el código de trabajo y el código de testeo, es decir, el fabricante ha escogido por un modelo de “White Box Testing”. Veamos un ejemplo el ejemplo de una función que simplemente imprime los elementos de una Lista de SharePoint:</P><br />
<P><STRONG>Código de trabajo:</STRONG><BR><PRE class=csharpcode>        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>void</SPAN> GetCollection01()<br />
        {<br />
            SPSite mySite = <SPAN class=kwrd>new</SPAN> SPSite(<SPAN class=str>&#8220;http://wsses&#8221;</SPAN>);</p>
<p>            <SPAN class=kwrd>using</SPAN> (SPWeb myWeb = mySite.OpenWeb())<br />
            {<br />
                <SPAN class=kwrd>foreach</SPAN> (SPList myList <SPAN class=kwrd>in</SPAN> myWeb.Lists)<br />
                {<br />
                    <SPAN class=kwrd>foreach</SPAN> (SPItem myItem <SPAN class=kwrd>in</SPAN> myList.Items)<br />
                    {<br />
                        Console.WriteLine(mySite.Url + <SPAN class=str>&#8221; &#8211; &#8220;</SPAN> + myWeb.Title + <SPAN class=str>&#8221; &#8211; &#8220;</SPAN> + myList.Title + <SPAN class=str>&#8221; &#8211; &#8220;</SPAN> + myItem.ID.ToString());<br />
                    }<br />
                }<br />
            }<br />
        }<br />
</PRE><STRONG><BR>Código de Prueba:<BR></STRONG><PRE class=csharpcode>        [TestMethod()]<br />
        <SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>void</SPAN> GetCollection01Test()<br />
        {<br />
            SPWeb fakeWeb = Isolate.Fake.Instance&lt;SPWeb&gt;(Members.ReturnRecursiveFakes);<br />
            SPList fakeList = Isolate.Fake.Instance&lt;SPList&gt;(Members.ReturnRecursiveFakes);<br />
            SPItem fakeItem01 = Isolate.Fake.Instance&lt;SPItem&gt;(Members.ReturnRecursiveFakes);</p>
<p>            <SPAN class=kwrd>using</SPAN> (var recorder = RecorderManager.StartRecording())<br />
            {<br />
                SPSite myFakeSite = <SPAN class=kwrd>new</SPAN> SPSite(<SPAN class=str>&#8220;&#8221;</SPAN>);<br />
                recorder.ExpectAndReturn(myFakeSite.Url, <SPAN class=str>&#8220;fakeSiteUrl&#8221;</SPAN>).RepeatAlways();<br />
                recorder.ExpectAndReturn(myFakeSite.OpenWeb(), fakeWeb);<br />
            }</p>
<p>            Isolate.WhenCalled(() =&gt; fakeWeb.Title).WillReturn(<SPAN class=str>&#8220;fakeWeb&#8221;</SPAN>);<br />
            Isolate.WhenCalled(() =&gt; fakeWeb.Lists[2].Title).WillReturn(<SPAN class=str>&#8220;fakeList&#8221;</SPAN>);<br />
            Isolate.WhenCalled(() =&gt; fakeItem01.ID).WillReturn(1);</p>
<p>            Isolate.WhenCalled(() =&gt; fakeWeb.Lists[2].Items).WillReturnCollectionValuesOf(<SPAN class=kwrd>new</SPAN> List&lt;SPItem&gt;<br />
               {<br />
                    fakeItem01<br />
               });</p>
<p>            Class1 target = <SPAN class=kwrd>new</SPAN> Class1();<br />
            target.GetCollection01();</p>
<p>            var fakeItemList = fakeWeb.Lists[2].Items;</p>
<p>            <SPAN class=kwrd>foreach</SPAN> (SPItem item <SPAN class=kwrd>in</SPAN> fakeItemList)<br />
            {<br />
                Isolate.Verify.WasCalledWithAnyArguments(() =&gt; item.ID);<br />
            }<br />
        }<br />
</PRE><br />
<P></P><br />
<P>Para la prueba unitaria se está usando una combinación de “Natural Mocks” y el nuevo “AAA API” de TypeMocks. Observe un par de puntos específicos:</P><br />
<UL><br />
<LI>Cada objeto “real” necesita un objeto “mockeado”: myWeb -&gt; fakeWeb, myList -&gt; fakeList, etc</LI><br />
<LI>Para cinco líneas de código de trabajo se necesitan 17 líneas de código de prueba</LI></UL><br />
<P><STRONG>Esto conlleva las siguientes consecuencias generales:</STRONG></P><br />
<P>Para poder crear un objeto “fantasma” (un mock) que sustituya efectivamente al objeto “real” en la clase de trabajo, es necesario conocer explícitamente su construcción. <STRONG><FONT color=#a52a2a>Esto excluye directamente la utilización de TDD: código de prueba debe ser escrito antes del código de trabajo</FONT></STRONG></P><br />
<UL><br />
<LI>Una consecuencia de esta consecuencia es que el código unitario deberá ser escrito por el desarrollador mismo que está escribiendo el código de trabajo: al final, es él/ella el que sabe que está haciendo. El peligro con esta construcción es que se van a escribir clases de prueba que casi siempre van a pasar el examen&#8230; voluntaria o involuntariamente, el desarrollador va a omitir las pruebas que tienen más posibilidades de fallar</LI><br />
<LI>Una segunda consecuencia de esta consecuencia es que el desarrollador probablemente utilizara más tiempo creando las clases de prueba que las clases de trabajo</LI><br />
<LI>Por la relación tan estrecha entre código de trabajo y de prueba, cuando se modifica algo en el código de trabajo, hay que modificar también el código de prueba. <STRONG>Es decir, Regression Test es imposible de realizar</STRONG></LI></UL><br />
<P>El fabricante de <STRONG>TypeMocks</STRONG> está trabajando intensivamente para darle solución a estos problemas, y los primeros resultados van saliendo: ciertas partes del Framework de TypeMocks es capaz de crear mocks para trabajar con Black Box Testing, es decir, entregando un objeto “mockeado” al método de trabajo y revisando los resultados producidos, sin tener conocimientos de su funcionamiento interno.<BR></P><br />
<P><STRONG>En cualquier caso, la discusión de si testeo blanco o negro es el mejor, o si Test-Driven Development es realmente valido continuaran hasta el fin de los siglos</STRONG>. Lo importante para nosotros, los que estamos metidos en el lio de hacer que código funcione apropiadamente no son las discusiones teóricas, sino los Frameworks que nos permitan trabajar confortablemente. TypeMocks es hasta el momento lo que más se acerca a una solución viable para hacer testeo de código de SharePoint, así que vale más que la pena de darle por lo menos una mirada e intentar hacerlo funcionar.<BR></P></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2008/testeo-unitario-para-sharepoint-la-importancia-de-llamarse-test/feed</wfw:commentRss>
		<slash:comments>251</slash:comments>
		</item>
		<item>
		<title>Drupal and SharePoint. Dos formas de hacer una tortilla (charla en Navarra)</title>
		<link>http://oldblog.ideseg.com/2008/drupal-and-sharepoint-dos-formas-de-hacer-una-tortilla-charla-en-navarra</link>
		<comments>http://oldblog.ideseg.com/2008/drupal-and-sharepoint-dos-formas-de-hacer-una-tortilla-charla-en-navarra#comments</comments>
		<pubDate>Mon, 01 Dec 2008 15:10:30 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[navarradotnet]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Drupal-and-SharePoint-Dos-formas-de-hacer-una-tortilla-(charla-en-Navarra).aspx</guid>
		<description><![CDATA[El próximo día 18 de diciembre tendremos en el Grupo de Usuarios de Navarra la charla (de los huevos y de los CKarlos), Karlos G. Liberal y un servidor hablaremos de algunas de las&#160;bondades&#160;de nuestras herramientas de trabajo (Drupal y SharePoint). El magnifico cartel ha sido realizado por nuestros amigos de Sistema Formación. La Agenda [...]]]></description>
			<content:encoded><![CDATA[<p><P>El próximo día 18 de diciembre tendremos en el Grupo de Usuarios de Navarra la charla (<STRONG>de los huevos y de los CKarlos</STRONG>), Karlos G. Liberal y un servidor hablaremos de algunas de las&nbsp;bondades&nbsp;de nuestras herramientas de trabajo (Drupal y SharePoint).</P><br />
<P>El magnifico cartel ha sido realizado por nuestros amigos de <A href="http://www.sistemaformacion.com/">Sistema Formación</A>. </P><br />
<P><IMG src="http://oldblog.ideseg.com/content//carteldotnet_final.jpg" border=0></P><br />
<P>La Agenda del evento es la siguiente:</P><br />
<P>La jornada será el jueves, 18 de diciembre<BR>Hora de recepción: 18:00</P><br />
<P><A title=ces href="http://www.cesnavarra.net/"><STRONG>Centros de Excelencia Software</STRONG></A><BR>Salón de actos<BR>Plaza Cein, 1, Polígono Mocholi<BR>Noáin Navarra 31110<BR>España </P><br />
<P><STRONG>AGENDA<BR></STRONG>18:30 &#8211; 19:30: <STRONG>Drupal and SharePoint. Dos formas de hacer una tortilla. Los CKarlos</STRONG>.<BR>19:30 &#8211; 20:00: <FONT color=#a52a2a><STRONG>Celebración 2º aniversario de NavarraDotNet: zorionak zuri y tarta de cumpleaños</STRONG></FONT><BR>20:00 &#8211; 21:00: <STRONG>Drupal and SharePoint. Dos formas de hacer una tortilla. Los CKarlos</STRONG><BR><STRONG><U>21:00 &#8211; &#8230; : Cena!</U></STRONG></P><br />
<P>Para apuntarse podéis hacerlos desde este enlace*<BR><A title=http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032393640&amp;Culture=es-ES href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032393640&amp;Culture=es-ES">http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032393640&amp;Culture=es-ES</A></P></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2008/drupal-and-sharepoint-dos-formas-de-hacer-una-tortilla-charla-en-navarra/feed</wfw:commentRss>
		<slash:comments>574</slash:comments>
		</item>
		<item>
		<title>Cenando, Buenas Practicas, Historia de terror</title>
		<link>http://oldblog.ideseg.com/2008/cenando-buenas-practicas-historia-de-terror</link>
		<comments>http://oldblog.ideseg.com/2008/cenando-buenas-practicas-historia-de-terror#comments</comments>
		<pubDate>Fri, 28 Nov 2008 14:36:06 +0000</pubDate>
		<dc:creator>cseg</dc:creator>
				<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">/post/Cenando-Buenas-Practicas-Historia-de-terror.aspx</guid>
		<description><![CDATA[Cenando El otro día paso Unai por Pamplona y estuvimos cenando y departiendo sobre todas esas cosas frikis que nos gustan. Una suerte para los que habéis podido asistir a los cursos que ha impartido de Entity Framework&#160; y WCF.Durante la cena, [[degustábamos unos “Penne Arrabiata” (no seáis mal pensados, que son macarrones con tomate [...]]]></description>
			<content:encoded><![CDATA[<p><P><STRONG>Cenando</STRONG></P><br />
<P>El otro día paso <STRONG><A href="http://geeks.ms/blogs/unai/Default.aspx">Unai</A></STRONG> por Pamplona y estuvimos cenando y departiendo sobre todas esas cosas frikis que nos gustan. Una suerte para los que habéis podido asistir a los cursos que ha impartido de Entity Framework&nbsp; y WCF.<BR><BR>Durante la cena, [[degustábamos unos “Penne Arrabiata” (<EM>no seáis mal pensados, que son macarrones con tomate un poco picante</EM>) y un “Ochoa Tempranillo” (recomendado)]], hablamos de; libros, de código, de más código, de bugs, de depuración, de tecnología, del bien y del mal (lo típico), no sé si ayer hablamos de sexo (no me acuerdo, pero con el frio que hacía es posible que no <img src='http://oldblog.ideseg.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .<BR><BR>Bueno, la cosa es que le comenté algunas de las cositas del Api de SharePoint. <BR><BR><STRONG>¿Buenas Prácticas?<BR></STRONG><BR>Como ya he contado en alguna ocasión, las colecciones de SharePoint, son a la antigua usanza (Net 1.0), es decir que implementan IEnumerable, en una clase contenida, esto lo hacen en una clase abstracta SPBaseCollection del cual heredan el resto de colecciones de SP.<BR><BR>Bien, hasta el momento no hay mucho problema, es un tema de diseño, necesario para implementar las serializaciones de los objetos además de la persistencia que realiza sharepoint via COM.<BR><BR>Si realicemos una consulta usando SPQuery, (SPQuery nos permite recuperar elementos de una lista usando CAML, que es un meta-lenguaje basado en XML que tiene SharePoint para muchas cosas, entre ellas recuperar elementos de las listas)</P><PRE class=csharpcode><SPAN class=kwrd>&lt;</SPAN><SPAN class=html>Where</SPAN><SPAN class=kwrd>&gt;</SPAN><br />
  <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>Geq</SPAN><SPAN class=kwrd>&gt;</SPAN><br />
    <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>FieldRef</SPAN> <SPAN class=attr>Name</SPAN>=”<SPAN class=attr>ID</SPAN>” <SPAN class=kwrd>/&gt;</SPAN><br />
    <SPAN class=kwrd>&lt;</SPAN><SPAN class=html>Value</SPAN> <SPAN class=attr>Type</SPAN>=”<SPAN class=attr>Integer</SPAN>”<SPAN class=kwrd>&gt;</SPAN>10<SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>Value</SPAN><SPAN class=kwrd>&gt;</SPAN><br />
  <SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>Geq</SPAN><SPAN class=kwrd>&gt;</SPAN><br />
<SPAN class=kwrd>&lt;/</SPAN><SPAN class=html>Where</SPAN><SPAN class=kwrd>&gt;</SPAN></PRE>Nos devolverá todos los elementos de una lista donde el ID sea mayor que 10.<BR><BR>Para poder ejecutar una consulta CAML sobre una lista tenemos una clase llamada <STRONG>SPQuery</STRONG> a través de la cual montamos la consulta.<BR><BR><PRE class=csharpcode>SPQuery query = <SPAN class=kwrd>new</SPAN> SPQuery<br />
                {<br />
                   Query = <SPAN class=str>&#8220;CONSULTITA EN CAML&#8221;</SPAN><br />
                };</PRE><BR>Para recuperar una colección de Items que cumplen esta consulta basta con indicar a la lista los items que queremos pasandole un SPQuery:<BR><PRE class=csharpcode>SPListItemCollection ítems = lista.GetItems(query);</PRE>Bien, como muchos ya sabéis que no es muy buena práctica devolver null, para no tener que comprobar si ítems es null antes de acceder, de modo que lo correcto es devolver una colección vacía (en este caso, como veremos luego tiene otro fundamento).<BR><BR>GetItems internamente nos devuelve una nueva colección <BR><PRE class=csharpcode><SPAN class=kwrd>public</SPAN> SPListItemCollection GetItems(SPQuery query)<br />
{<br />
    <SPAN class=kwrd>return</SPAN> <SPAN class=kwrd>new</SPAN> SPListItemCollection(<SPAN class=kwrd>this</SPAN>, query);<br />
}<br />
</PRE><BR><br />
<P>Pero qué pasa si la consulta está mal formada ó es incompleta.&nbsp; Lo que cabe de esperar es:<BR><BR>1.-&nbsp;Que nos devuelva una excepción en el momento de crear SPQuery (<STRONG>cosa que no hace</STRONG>)<BR>2.-&nbsp;Que nos ofrezca una propiedad o algo para comprobar si la consulta es correcta (<STRONG>cosa que no hace</STRONG>)<BR>3.- Que nos devuelva una colección vacía (<STRONG>cosa que hace peligrosamente a medias</STRONG>)<BR><BR>¿Por qué lo hace a medias? Porque aparentemente nos devuelve una colección vacía, es decir si la consulta está mal, ítems no es null. <STRONG>Pero OJO no es una colección valida</STRONG>.<BR><PRE class=csharpcode>SPQuery query = <SPAN class=kwrd>new</SPAN> SPQuery<br />
                {<br />
                        Query = <SPAN class=str>&#8220;MI mala CAML Query&#8221;</SPAN><br />
                };</p>
<p>SPListItemCollection items = list.GetItems(query);</p>
<p><SPAN class=kwrd>if</SPAN> (items!= <SPAN class=kwrd>null</SPAN>)<br />
{<br />
    Debug.WriteLine(<SPAN class=str>&#8220;Soy una colección no nula. Parece que valgo&#8230;&#8221;</SPAN>);</p>
<p>    <SPAN class=rem>// Ahora reviento</SPAN><br />
    <SPAN class=kwrd>foreach</SPAN> (SPListItem item <SPAN class=kwrd>in</SPAN> items)<br />
    {<br />
    }<br />
}<br />
</PRE><br />
<P>Las colecciones de este tipo en SharePoint, son de carga retardada de modo que la colección se carga cuando realmente vamos a usarla (Lazy-Load / Proxy), en ese momento se hace una petición SPRequest que es al que se encarga de recuperar el contenido y obtener la colección de elementos. (fundamento)<BR><BR>En ese momento se usa la consulta <STRONG>SPQuery</STRONG> que le hemos pasado para recuperar los datos, y al tratar de cargarla, como la consulta está mal formada,&nbsp;da una excepción (<STRONG>no advertida ni documentada</STRONG>), y la colección sigue siendo una colección hasta que usemos alguna de sus propiedades o tratemos de recorrerla. Es decir no es una colección vacia, si no una colección donde todo se ha quedado mal inicializado si intentas un items.Count antes de recorrer la colección tambien dará una excepción ya esta va a producirse de igual manera al cargar los datos.<BR><BR>De <STRONG>modo que la buena práctica se convierte en mala práctica</STRONG> ya que se pasa de hacer una comprobación de null antes, a tener que hacer un Try/Catch en el momento de recorrer la colección (como decimos por aquí, cojonudo).<BR><BR>Como alternativa, se puede implementar un método por ejemplo, vía extensión; &nbsp;para comprobar que la consulta es valida y en caso de no serla que nos devuelva una colección bien formada cuando menos. Otra alternativa podría ser otro método como <EM>EnsureCollection</EM>, a través del cual podamos recuperar la excepción si nos interesa comunicar que la consulta esta mál formada.<BR><BR>La cosa sería algo así: </P><br />
<P><PRE class=csharpcode><SPAN class=kwrd>public</SPAN> <SPAN class=kwrd>static</SPAN> SPListItemCollection TryGetItems(<SPAN class=kwrd>this</SPAN> SPList list, SPQuery query)<br />
{<br />
    SPListItemCollection items; </p>
<p>    <SPAN class=kwrd>try</SPAN><br />
    {<br />
        items = list.GetItems(query);<br />
        <SPAN class=kwrd>int</SPAN> count = items.Count;<br />
    }<br />
    <SPAN class=kwrd>catch</SPAN>(SPException ex)<br />
    {<br />
        query.Query = <SPAN class=kwrd>string</SPAN>.Empty;<br />
        items = list.GetItems(query);<br />
    }</p>
<p>    <SPAN class=kwrd>return</SPAN> items;<br />
}</PRE><br />
<P></P><br />
<P>JA, pero ahí no termina la cosa …&nbsp; los señores de SharePoint son unos fenómenos optimizando y lo que hacen SPQuery internamente es generar una Vista (propiedad ViewXml de SPQuery), para optimizar el rendimiento, esta vista en Xml, se genera reuniendo&nbsp;todas las propiedades de SPQuery, y se genera siempre y cuando no se ha generado antes (optimización)<BR><BR>De modo, que si cambiamos la propiedad Query de SPQuery, la consulta interna ViewXml no cambia (ya se genero antes), manteniendo la última consulta generada,&nbsp;para lo cual debemos limpiar ViewXml. <BR></P><br />
<P><PRE class=csharpcode>query.Query = <SPAN class=kwrd>string</SPAN>.Empty;<br />
query.ViewXml = <SPAN class=kwrd>string</SPAN>.Empty;<br />
items = list.GetItems(query); </PRE><br />
<P></P><br />
<P>¿Por qué que les habría costado implementar un flag de suciedad y reconstruir la ViewXml cada vez que el objeto este sucio? ¿por qué no documentarlo?<BR><BR>En fin,&nbsp;la cena estuvo genial.</P></p>
]]></content:encoded>
			<wfw:commentRss>http://oldblog.ideseg.com/2008/cenando-buenas-practicas-historia-de-terror/feed</wfw:commentRss>
		<slash:comments>450</slash:comments>
		</item>
	</channel>
</rss>

