Incluyendo Simile Timeline en una aplicación ADF Faces.

septiembre 22, 2009 at 12:37 pm Deja un comentario

Escenario

El MIT (Instituto Tecnológico de Massachussetts) ofrece herramientas de manejo y visualización de datos fáciles de usar y, en principio integrables en aplicaciones web cliente, a través del proyecto SIMILE.  Concretamente, para cubrir la necesidad de visualizar eventos en una línea temporal, dispone del widget timeline.  Se trata de una librería javascript que permite justamente eso, visualizar cronológicamente información.  El software se ofrece bajo una licencia BSD.  Se proporciona documentación de cómo se puede incluir una línea temporal en una página HTML.  Aquí lo que vamos a ver es cómo hacerlo en una página ADF Faces.  Nuestra página ADF dispone de un campo lista desplegable. El usuario seleccionará un valor determinado de dicha lista y pulsará un botón de consulta. En ese momento, deberá mostrarse la linea temporal con el calendario correspondiente a la opción elegida.

La estructura

Para usar la linea temporal es necesario incluir los scripts de Simile en nuestro proyecto, en un subdirectorio dentro de public_html. Una vez hecho esto, crearemos tres servlets, a saber:

  • Un primer servlet que extraerá la información que va a aparecer en la línea temporal y generará un XML con la estructura que espera Simile. El parámetro que necesita para extraer la información lo tomará de la sesión.  No obstante, se le pasará un parámetro con los milisegundos de la hora actual para evitar que algunos navegadores (I.E., de hecho) no invoquen al servlet por segunda vez en una sesión al asumir erróneamente que, siendo la misma URL, los datos devueltos deben ser los mismos (incorrecto, ya que los parámetros se están pasando a través de la sesión).
  • Otro servlet que creará la parte jscript que va en el head de la página HTML final.
out.println("<script src=\"simile-timeline-api/timeline-api.js\" type=\"text/javascript\"></script>");
 out.println ("<script>");
 out.println ("var tl1, tl2;");
 out.println ("function onLoad() {");
 out.println ("var ejercicio=new Date().getFullYear();");
 out.println ("var eventSource = new Timeline.DefaultEventSource();");
 out.println ("");
 out.println ("            var theme = Timeline.ClassicTheme.create();");
 out.println ("");
 out.println ("            var date = \"" + getFechaActual() + "\"");
 out.println ("            var bandInfos = [");
 out.println ("                Timeline.createBandInfo({");
 out.println ("                    eventSource:    eventSource,");
 out.println ("                    date:           date,");
 out.println ("                    width:          \"70%\",");
 out.println ("                    intervalUnit:   Timeline.DateTime.MONTH,");
 out.println ("                    intervalPixels: 200");
 out.println ("                }),");
 out.println ("                Timeline.createBandInfo({");
 out.println ("                    eventSource:    eventSource,");
 out.println ("                    date:           date,");
 out.println ("                    width:          \"30%\",");
 out.println ("                    intervalUnit:   Timeline.DateTime.YEAR,");
 out.println ("                    intervalPixels: 200,");
 out.println ("                    overview: true,");
 out.println ("                    trackHeight:    10,");
 out.println ("                    trackGap:       5");
 out.println ("                })");
 out.println ("            ];");
 out.println ("            bandInfos[1].syncWith = 0;");
 out.println ("            bandInfos[1].highlight = true;");
 out.println ("");
 out.println ("            for (var i = 0; i < bandInfos.length; i++) {");
 out.println ("                bandInfos[i].decorators = [");
 out.println ("                    new Timeline.SpanHighlightDecorator({");
 out.println ("                        startDate:  \"" + getFechaInicioMesActual() + "\",");
 out.println ("                        endDate:    \"" + getFechaInicioMesSiguiente() + "\",");
 out.println ("                        color:      \"#AAAACD\", // set color explicitly");
 out.println ("                        opacity:    50,");
 out.println ("                        theme:      theme");
 out.println ("                    })");
 out.println ("                ];");
 out.println ("            }");
 out.println ("tl1 = Timeline.create(document.getElementById(\"tl1\"), bandInfos, Timeline.HORIZONTAL);");
 out.println ("Timeline.loadXML(\"servlet1?time=" + new Date().getTime() + "\", function(xml, url) { eventSource.loadXML(xml, url); });");
 out.println ("}");
 out.println ("</script>");
  • Un tercer servlet que creará la parte HTML que va en el body de la página y que pinta la línea de tiempo.
out.print("<div id=\"body\">");
 out.print("<div style=\"float: rigth; margin-left: 1em; margin-bottom: 1em;\">");
 out.print("<table>");
 out.print("<tr>");
 out.print("<td>");
 out.print("<div id=\"tl1\" class=\"timeline-default\" style=\"width: 600px; height: 200px;\"></div>");
 out.print("</td>");
 out.print("</tr>");
 out.print("</table>");
 out.print("</div>");
 out.print("</div>");
 out.close();

Tendremos que escribir también código en el botón para que al pulsarse, se grabe en la sesión el valor seleccionado en la lista de parámetros, para que pueda ser recogido por el primer servlet.

En la página jspx se incluirá en la cabecera una llamada al servlet2:

 <f:view>
   <afh:html>
     <afh:head title="Mi pagina">
       <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
       <f:subview id="timelinehead">
         <jsp:include page="/servlet2"/>
       </f:subview>
     </afh:head>
     <afh:body onload="onLoad();">

En el cuerpo de la página se incluirá una llamada al servlet3:

 <f:verbatim>
   <f:subview id="timelinebody">
     <jsp:include page="/servlet3"/>
   </f:subview>
 </f:verbatim>

La cáscara de plátano

Lo último que hay que hacer es incluir en el mismo directorio que nuestra página JSPX un fichero con el nombre __history__.html que contenga lo siguiente:

<html><body></body></html>

Al parecer, la librería javascript busca en un momento dado este fichero y si no lo encuentra, provoca una exepción como la siguiente:

com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
oracle.adfinternal.view.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:157)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._invokeDoFilter(AdfFacesFilterImpl.java:228)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._doFilterImpl(AdfFacesFilterImpl.java:197)
oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl.doFilter(AdfFacesFilterImpl.java:123)
...
Anuncios

Entry filed under: ADF. Tags: , , , , .

Generando un PKCS#7 desde un dispositivo Android

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Trackback this post  |  Subscribe to the comments via RSS Feed


Autores


A %d blogueros les gusta esto: