Un viaje sobre lenguajes, APIs y otras cosas raras en el mundo del desarrollo de sistemas.

Introducción

Esto pretende ser una guía de buenas prácticas que deben seguirse para poder tener una programación segura, entendiendo por esto una programación que evite que nuestros programas sean propensos a ataques o errores que puedan generar fuga de información o puedan convertirse en punto de partida para explotar fallas en otros programas o sistemas.

Se divide primero en las reglas generales de programación  aplicables a todos los lenguajes, próximas entradas hablaremos sobre lenguajes específicos y plataformas.

En caso de ser necesario se darán algunas muestras de código para ejemplificar.

Nos dirigido a programadores, arquitectos y líderes de proyectos interesados en realizar sistemas que puedan responder a las necesidades de seguridad actuales.

La seguridad reside en guardar los siguientes aspectos de un sistema:

  1. Confidencialidad : Se refiere a la necesidad de que los datos solamente sean accedidos por aquellos que realmente deban tener acceso a ellos
  2. Integridad: Ningún dato debe ser alterado
  3. Disponibilidad: Cuando se necesite un dato este deberá poderse obtener si es que se ha cumplido los principios anteriores
  4. Autenticación : Es el mecanismo mediante el cual nos aseguramos de la identidad de quien quiere interactuar con el sistema
  5. Autorización: Es el mecanismo por el cual se da acceso a los recursos (programas, archivos, datos, servicios, etc.) a las identidades adecuadas, por ello siempre es necesaria una autenticación correcta
  6. Auditoría (No repudiación): Es el mecanismo por el cual se debe poder rastrear los accesos, autorizaciones del sistema, un buen servicio de auditoría nos debe poder llevar a resolver las preguntas ¿Quién hizo qué? Y ¿Cómo lo hizo?

CIA

Para poder cumplir con estas metas es necesario la implementación de:

  • Políticas: Se refiere a lo que la seguridad significa para un proyecto, organización u otra entidad
  • Normas: Son aquellas observaciones técnicas que deben seguirse para poder cumplir con los requerimientos de seguridad establecidos (estándares)
  • Guías: Una guía es una serie de recomendaciones que determinan como actuar. Las guías no son obligatorias y comúnmente son definidas para apoyar las normas establecidas. Comúnmente son conocidas como recomendaciones y son una referencia cuando no existe una norma establecida.
  • Procedimientos: Un procedimiento es aquel diseño o documento que explica quien, cuando, donde y por qué sobre la implementación de una política establecida.

psgp

Dentro de este conjunto de implementaciones este documento forma parte de las guías para el establecimiento de una buena implementación de la seguridad.

La meta de la seguridad de un sistema es garantizar la confidencialidad, integridad y disponibilidad de los recursos de información para proveer el buen funcionamiento de las operaciones de negocio. Estas metas se logran gracias a la implementación de controles de seguridad. Esta guía tiene como objetivo ayudar a mitigar la ocurrencia de las vulnerabilidades de software en la medida de lo posible.

Buenas Prácticas

Validar las entradas

Algunas publicaciones conocen esta práctica como Input Validation and Data Sanitization (IDS), dejando en claro que la idea de esta práctica es ver que los datos sean válidos y que no contengan “basura” que pueda poner en riesgo los sistemas.

La idea de validar las entradas se debe dar en ambos puntos, el cliente y el servidor para evitar que se trate de brincar la validación del cliente por cualquier otro método.

La sanitación (o depuración) de los datos se da cuando se verifican los caracteres de estas entradas contra una “lista blanca” a fin de no permitir ningún carácter no válido.

inputValidation

Hacer caso de las advertencias de compilación

Las advertencias de compilación “no están de adorno”, hay que atenderlas y verificar que no existan o que las existentes sean “manejables” en el código y no posibles puntos de ruptura del mismo, por ejemplo en C o C++ es posible poner if (variable = otraVariable) sin que esto sea un error en la compilación, el compilador marcará una advertencia pero es muy probable que sea un código realmente erróneo.

fixWarnings

Otras advertencias que se deben eliminar en la medida de lo posible son aquellas que tengan que ver con conversión de tipo o de no  manejo de posibles excepciones de código, sin embargo este listado no es limitativo y un código limpio de advertencias siempre deberá ser nuestro  objetivo.

Hacer caso de los diseños de seguridad y de la arquitectura establecida

Toda corporación ha pasado años tratando de refinar sus arquitecturas de software e infraestructura a fin de garantizar el correcto uso de los componentes ya existentes y de la seguridad de los mismos. En caso de cualquier duda sobre el funcionamiento de la Arquitectura (en general o la específica ligada a seguridad) acércate con el equipo de Arquitectura Técnica.

Hacer tu código sencillo

Mientras más complejo sea el esquema del código más puntos de error existen y más probabilidades de tener vulnerabilidades en él, un buen código siempre debe de ser limpio, compacto, simple y dedicado a resolver el problema para el que es hecho. Recuerda el concepto es KISS (Keep It Simple, Stupid).

El generar menos líneas de código no es hacer un código sencillo, tampoco lo es escribir más, lo que se debe buscar es un código que sea legible y que permita un buen mantenimiento, cuya lógica sea clara y apegada a la resolución de problemas.

Ante la duda de si un código es sencillo o no las opciones son reescribir el código de una manera más clara y el apoyarse de comentarios en el código.

Por omisión: restringe.

En seguridad solo hay dos opciones: O se permite o se restringe (rechaza), si se toma la decisión de permitir sobre la de restringir siempre entonces existirá el riesgo de que alguien se aproveche de ello.

restrict

Principio del menor privilegio

Si tu programa corre en una computadora con usuario de privilegios de administrador, una base de datos con un esquema sin restricciones de espacio, sin restricciones de acceso a los sistemas de archivos o un espacio sin restricción de conexiones de puertos entonces es muy probable que no funcione correctamente en un ambiente real. El desarrollador debe  poder generar su código en las mismas condiciones de restricción en que este se ejecutará para poder llegar a validarlo.

Lo ideal es suponer que ningún privilegio (informático) será otorgado salvo aquel que se especifique  claramente en los requerimientos.

privilegeAbuse

Verifica, codifica y depura los datos que se enviarán a otros sistemas

Ya hemos hablado de la validación de datos, estos datos se validan en el punto de recolección de los mismos (p.e. navegador) y deben ser verificados en los puntos de recepción (p.e. servidor de aplicaciones), al momento de enviarse estos deben ser codificados de manera correcta para poder ser interpretados sin problema alguno (URLEncode en nuestro ejemplo) y decodificados de una manera correcta, de igual manera se debe buscar evitar todos los caracteres que puedan causar conflictos, ya sea generando caracteres de escape, aplicando una codificación o simplemente no aceptándolos (un ejemplo de depuración de caracteres puede ser el envío o recepción de campos que contengan un apóstrofe  hacia una consulta de base de datos o un signo de < o de > hacia una página HTML)

CRS

Defensa a fondo

La idea de defensa a fondo es similar a la de manejar a la defensiva cuando se conduce un automóvil: No sabemos qué es lo que van a hacer los conductores de los otros carros, por lo tanto hay que prevenir y adelantarnos a los posibles movimientos de ellos.

watchout

El tema de la programación defensiva es muy amplio y se tratará en la medida de lo posible en las especificaciones de cada lenguaje, pero la idea general de realizar una programación defensiva debe ser común y de alerta independientemente de la plataforma de programación que se use.

Utilizar técnicas de aseguramiento de calidad

QALas técnicas de calidad no empiezan con el área de QA, muy al contrario ellos son un punto de apoyo para poder asegurar que todos los controles funcionen. Todas las prácticas de QA deben de tomar en cuenta los requerimientos y buenas prácticas de seguridad a fin de poder tener un sistema lo más seguro posible, entre estas prácticas no deben faltar la integración continua, las revisiones entre pares, el manejo de requerimientos, la generación de pruebas unitarias y las discusiones en los grupos ágiles sobre la seguridad requerida en cada una de las historias de usuario.

 

Adoptar normas de codificación segura

Se debe desarrollar y/o adoptar las normas que se tengan de programación para el lenguaje usado y la plataforma en la que se desarrolla o ejecutarán los programas, cada de ellas es única y pueden variar entre cada proyecto inclusive.

Una programación basada en normas y uso de librerías (frameworks) de uso común permitirá siempre el poder hacer frente a las posibles vulnerabilidades que se puedan descubrir.

Adicional al manejo propio del código siempre existirán normas y regulaciones internacionales, corporativas o informáticas que debemos observar a fin de cumplir con los requerimientos internos, estos pueden ir desde normas documentales para soportar a las áreas de servicio técnicos, normas de manejo de bitácoras o leyes nacionales o internacionales.

normasPS

Verificar y exigir requerimientos de seguridad

Como se ha mencionado anteriormente la seguridad debe ser parte integral de los requerimientos de manera que cuando estos lleguen al programador este pueda tener claridad en aquellos puntos específicos que debe verificar.

Una planeación de requerimientos que no contempla seguridad puede convertir un proyecto en un verdadero dolor de cabeza.

Manejo de la autenticación

authenticationEl manejo de la autenticación siempre es un dolor de cabeza, sin embargo la arquitectura corporativa ofrece varias soluciones para resolverlo, es precisamente esta otra de las razones por las cuales es importante seguir las guías de arquitectura y los diseños de arquitectura técnica para cada proyecto. Hacer caso omiso de ella o tratar de deshabilitar los módulos de seguridad ya establecidos trae como consecuencia generar vulnerabilidades que ya han sido resueltas durante el tiempo que esta arquitectura y soluciones se han venido desarrollando.

En aquellas plataformas donde no existan librerías corporativas las soluciones de autenticación deben ser  validadas ante Arquitectura técnica a fin de determinar los componentes a usar.

Manejo de Sesiones

En el caso de México el manejo de sesiones es muy estricto para aquellos programas bancarios e instituciones financieras,  pero en general hay que verificar siempre el cumplimiento de normas que  permitan el uso adecuado de estas. Si estás en una institución bancaria mexicana lee la Circular Única para bancos.

Un manejo equivocado de la sesión puede generar que los esfuerzos de autenticación de un sistema sean inútiles pues puede quedar comprometida la seguridad si esta sesión es interceptada o suplantada.

  • Las sesiones nunca deben ser un parámetro GET
  • Las sesiones deben tener una vigencia (deben caducar)
  • Usuarios y contraseña no deben ser parte del identificador de sesión
  • Al utilizar tokens de sesión que contengan este tipo de datos sensibles deberán usar algún tipo de criptografía.
  • Siempre se debe utilizar un protocolo seguro (https, es decir SSL o TLS)
  • Idealmente se debería cambiar un identificador de sesión después de que el usuario se ha identificado con éxito.
  • Las cookies que se usen siempre deben ser seguras

En la siguiente entrada hablaremos de:

  • Control de acceso
  • Prácticas criptográficas
  • Manejo de errores y bitácoras
  • Protección de Datos
  • Seguridad en las comunicaciones
  • Configuración en los sistemas
  • Seguridad en las bases de datos
  • Manejo de archivos
  • Manejo de memoria
  • Manejo de la concurrencia

Gluon Rulez

After my last BLOG entry (long time ago) lot of things have happened, JavaFX performance has improved a lot and the quantity of things that it provides and you can find for this framework has grown in quantity and quality. There are more components and definitely one of the missing parts on the equation has appear and it’s called GLUON.

¿What’s GLUON?

Well… Gluon is a company that took “the responsability” to lead a copule of very important projects: Scene Builder and  JavaFXPorts, improving the wy to use both of them, that’s what we are going to talk about.

Scene Builder

Scene Builder is a  JavaFX WYSIWYG for GUIs.

Yeah, i know that “we” prefer to use our old Eclipse or Netbeans and edit our FXML files handly, but it is always a good idea to have an auxiliar tool to help us to create the first prototype and let us make an approach on what we need in order to polish things after (using this tool or aour beloved notepad editor).

The tool is a good one and we are going to put a couple of screenshots about examples that we alrady talked before in this blog.

This way we can move some properties on our GUI quickly.

Improvements we have seen: a better way to manage image resources and CSS files (it does not have a CSS editor and it could be a valuable improvement on the future).

JavaFX Ports

This is what we wait for long long  time, a tool to let us use all the JavaX beauty to develop mobile devices applications.

Once again our life has been made easier. Gluon has generated some plugins that let us focus on coding and forget on the instalations needed, so to make a mobile development we only need to install the required SDKs (Android, iOS -XCode- and Gluon). To have the complete set of instructions on how to do it i will drop the link to see it:

http://docs.gluonhq.com/charm/1.0.0/#_ide_plugins

I have to point out that once you have your gluon project and the gradle files generated by the tool you must update the build.gradle file to point to the last javafx ports version as dependency:

dependencies {
classpath ‘org.javafxports:jfxmobile-plugin:1.0.6’
classpath ‘com.android.tools.build:gradle:0.5.+’
classpath ‘com.google.code.ksoap2-android:ksoap2-android:3.4.0’
}

 

If you left the default version (the one that the plugin generates the day of this post) you may have some trouble with the displaying position for the item list box for ChoiceBox and DatePicker … and you are not going to like it.

I must recomend an aditional reading of the documentation provided on the site in order to generate notification or some mobiles platform specific features for your programs.

So the good news are on, cause beside these and the modularization that will be in java 9 (jigsaw) we can be sure that the WORE concept is not just back but in the best position ever. Hopefully and Gluon can contribute to create a PPAPI plugin for browsers in order  to run again our applets, that could be “the icing on the cake”.

Greetings and i promise that my blog is back for good.

Después de la última entrada en este BLOG (ya hace bastante) muchas cosas han pasado, JavaFX mejoró bastante en su desempeño y en la cantidad de cosas que provee y poco a poco cada vez hay más soporte para los componentes necesarios para este lenguaje, definitivamente uno de los componentes que estaba perdido era GLUON.

¿Que es GLUON?

Bueno… gluon es una empresa que se ha dado a la labor de “hacerse responsable” de un par de proyectos muy específicos:  Scene Builder y JavaFXPorts, mejorando la forma de utilizar ambos, que es de lo que hablaremos a continuación.

Scene Builder

Scene Builder es un constructor de interfaces JavaFX WYSIWYG.

Si, ya se que preferimos (muchos) manejar nuestro viejo Eclipse o NetBeans y estar editando los XML (FXML) a mano, pero siempre es bueno una herramienta auxiliar que nos permita hacer la primera aproximación de una manera rápida y segura para que nosotros podamos refinarla posteriormente (ya sea con ayuda de esta herramienta o “a patín del diablo” -a mano- )

La herramienta es buena y les dejamos aqui algunos ejemplos con lo que ya alguna vez escribimos dentro de este blog.

Así pues podemos mover las características de nuestra aplicación de una forma más rápida.

Una de las mejoras que hemos observado es un mejor manejo de las iágenes y recursos CSS dentro del editor. (No tiene editor de CSS y probablemente eso pudiese ser un extra muy valioso a futuro).

JavaFX Ports

Esto es lo que durante muchos e interminables meses estuvimos buscando, una herramienta (justo de la que hablé en mi último post) que nos permitiera llevar toda la belleza de JavaFX hacia los dispositivos móviles.

Una vez más nos han facilitado la vida. Han generado plugins que nos permiten olvidarnos un podo sobre las instalaciones necesarias y nos ayudan a enfocarnos en la codificación, así que ahora para hacer un desarrollo en móviles sólo hay que instalar los SDK adecuados (Android, iOS -Xccode- y Gluon). Para las instrucciones de como instalar los plugins les dejo la liga correspondiente:

http://docs.gluonhq.com/charm/1.0.0/#_ide_plugins

Es bueno hacer notar que una vez que el proyecto e gradle se encuentre generado para nuestra aplicación es recomendable actualizar el archivo build.gradle para que las dependencias vayan a la última versión de javafx ports:

dependencies {
classpath ‘org.javafxports:jfxmobile-plugin:1.0.6’
classpath ‘com.android.tools.build:gradle:0.5.+’
classpath ‘com.google.code.ksoap2-android:ksoap2-android:3.4.0’
}

 

Por ejemplo, si usted deja la versión (que hasta hoy viene en el plugin por omisión) es probable que haya problemas con la posición en que se desplieguen las listas del Datepickeer o del ChoiceBox… lo cual no nos gustará.

Yo recomendaría, adicionalmente darle una buena leida al sitio por si creen que generar notificaciones o hacer algo específico de alguna plataforma movil debe ser parte de su aplicación.

Así pues siguen las buenas noticias, pues entre esto y la modularización que tendremos en Java 9 podemos estar seguros de que el concepto WORE está no sólo de vuelta si no en un mejor posicionamiento que muchas otras herramientas, ojalá y Gluon decidiera contribuir para que se genere un plugin PPAPI para JavaFX, sería “la cereza en el pastel”.

Saludos y les aseguro que volveré pronto con más posts.

JavaFX en mi android

El día de hoy vamos a hacer que una aplicación ya hecha en Java FX la podamos pasar a nuestro dispositivo Android.

Los pasos son a grandes rasgos:

Bajar el sdk de android y el adt para tener emuladores. http://developer.android.com/sdk/installing/index.html?pkg=tools

Bajar el runtime de JFX https://bitbucket.org/javafxports/android/downloads

Gradle viene con el dalvik sdk

Generar para gradle las siguientes variables:

NAME El nombre escogido para el proyecto.

ANDROID_SDK el path donde se ha bajado el SDK Android, Si se ha bajado todo el ADT hay que apuntar al directorio interno del adt.

DIR el directorio donde el apk será guardado. Un directorio llamado NAME será generado en este directorio de salida

PACKAGE El nombre del paquete requerido por Android. No tiene relación con el de la aplicación JavaFX pero se puede usar el mismo.

JFX_SDK Donde el JavaFX-Android Runtime ha sido compilado o descargado

JFX_APP Lugar donde está el .jar de la aplicación JavaFX

debe utilizar el API de Android al nivel 19 o posterior, si alguno de los archivos han sido compilados con Java 7 o mayor. De otra forma los archivos deben ser compilados para Java 6.

JFX_MAIN el nombre de la clase que inicia la aplicación Java (completa con el nombre de los paquetes)

DEBUG Si se quiere hacer l depuración del producto portado.

Crear el proyecto de Gradle:

gradle -PDEBUG -PDIR=/home/user/work -PNAME=HelloAndroidWorld -PPACKAGE=com.helloworld \

-PJFX_SDK=/home/user/android/android-sdk -PJFX_APP=/home/user/NetBeansProjects/HelloAndroidWorld/dist \

-PJFX_MAIN=com.helloworld.HelloAndroidWorld createProject

correr en el directorio de la aplicación: ant debug

Instale la aplicación en su dispositivo

La aplicación no correrá en dispositivos virtuales debido a que estos no tienen las extensiones de opengl requeridas por JFX. Se debe utilizar un dispositivo real.

El bundle Android ADT tiene una herramienta llamada adb que le permitirá comunicarse con el dispositivo real (o incluso con los emuladores). Instale el paquete via:

adb install -r path/to/package-debug.apk

Si quiere debugearlo hágalo usando:

adb logcat

En las entradas posteriores les iremos diciendo que es lo que hemos encontrado sobre este procedimiento, por lo pronto queda saber que el runtime que manejamos aqui es referente a JavaFX2 (Java 7), sin embargo en el mismo repositorio de bitbucket podemos encontrar el JFX rt para JFX 8… seguiremos informando

After a very heavy workload here we are to finish (or start) what we begun.

If you remember we made a user interface that had a VBox named as  “vbScores” in that VBox  we’ll put our baseball results. but what we will show?

well let’s make our FXML first:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" prefHeight="45.0" prefWidth="169.0" styleClass="mainFxmlClass, rootPane" xmlns:fx="http://javafx.com/fxml" fx:controller="com.beisbolicos.scoreboard.GameResultController">
  <children>
    <GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <Label fx:id="eVisitante" text="Label" textFill="#e0ff66" GridPane.columnIndex="0" GridPane.rowIndex="0">
          <font>
            <Font name="Verdana Bold" size="12.0" fx:id="x1" />
          </font>
        </Label>
        <Label fx:id="eLocal" font="$x1" text="Label" textFill="#52ff00" GridPane.columnIndex="0" GridPane.rowIndex="2" />
        <Label fx:id="cVisitante" text="Label" textFill="WHITE" GridPane.columnIndex="1" GridPane.rowIndex="0" />
        <Label fx:id="cLocal" text="Label" textFill="WHITE" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label id="lInning" fx:id="lInning" text="Label" textFill="#ff3d00" GridPane.columnIndex="2" GridPane.rowIndex="0">
          <font>
            <Font name="System Bold" size="12.0" fx:id="x2" />
          </font>
        </Label>
        <Label fx:id="lStatus" font="$x2" graphicTextGap="0.0" text="Label" textFill="#33ffe7" GridPane.columnIndex="0" GridPane.rowIndex="3">
          <GridPane.margin>
            <Insets fx:id="x3" />
          </GridPane.margin>
        </Label>
        <ImageView fitHeight="30.0" fitWidth="50.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.halignment="LEFT" GridPane.hgrow="NEVER" GridPane.margin="$x3" GridPane.rowIndex="1" GridPane.rowSpan="2" GridPane.valignment="TOP" GridPane.vgrow="NEVER" />
      </children>
      <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
      </columnConstraints>
      <rowConstraints>
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
      </rowConstraints>
    </GridPane>
  </children>
  <stylesheets>
    <URL value="@scoreboard.css" />
  </stylesheets>
</AnchorPane>


As you can see we will put the game’s local team name and runs, visitor’s name and run and one state and one graphic for the on bases runners.

Now it’s time to connect to the WebService that will provide the data, we will make this from out initial FXML controller, that is the ScoreboardController class and we will read something like:

package com.beisbolicos.scoreboard;
import com.delunasaenz.scoreboardWS.Game;
import com.delunasaenz.scoreboardWS.ScoreboardWS;
import com.delunasaenz.scoreboardWS.ScoreboardWSService;
import java.io.IOException;import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javax.annotation.Resource;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class ScoreBoardController implements Initializable {
    public ScoreboardWSService service;
    @FXML
    private ChoiceBox leagueSelection;
    @FXML
    private VBox vbScores;
    @FXML
    private void handleButtonAction(ActionEvent event) {
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        URL wsdlLocation = null;
        try {
            wsdlLocation = new URL("http://localhost:8080/"
                    + "ScoreboardApp/ScoreboardWSService?wsdl");
        } catch (MalformedURLException ex) {
            Logger.getLogger(ScoreBoardController.class.getName()).log(Level.SEVERE, null, ex);
        }
        service = new ScoreboardWSService(wsdlLocation,
                new QName("http://scoreboard.delunasaenz.com/", "ScoreboardWSService"));
        leagueSelection.getSelectionModel().select(0);
        leagueSelection.getSelectionModel().selectedIndexProperty()
                .addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov,
                    Number t, Number t1) {
                actualizaLista(t1);
            }
        });
        actualizaLista(new Integer(0));
    }
    private void actualizaLista(Number t1) {
        ScoreboardWS port = service.getScoreboardWSPort();
        String liga;
        switch (t1.intValue()) { 
           case 0:
                liga = "MEX";
                break;
            case 1:
                liga = "LMP";
                break;
            case 2:
                liga = "MLB";
                break;
            case 3:
                liga = "SC";
                break;
            default:
                liga = "MEX";
                break;
        }
        List<Game> result = port.league(liga);
        vbScores.getChildren().clear();
        for (Game item : result) {
            FXMLLoader fxml = new FXMLLoader(getClass()
                        .getResource("/com/beisbolicos/scoreboard/GameResult.fxml"));
            try {
                fxml.load();
                GameResultController grc = fxml.getController();
                vbScores.getChildren().add((Node) fxml.getRoot());
                grc.setGame(item);
            } catch (IOException ex) {
                Logger.getLogger(ScoreBoardController.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }
    }
}

And now the explanation.

if you have used Web Services from servlets or JSP you will find that  @WebServiceRef(wsdlLocation = “http://localhost:8080/ScoreboardApp/ScoreboardWSService?wsdl&#8221;) is missing, that is because the Service reference for our webservice client (service variable), that is because that annotation only works inside a Webserver container and a JavaFX is not running on the server side, but the client side, then we need to start our WS client using the constructor of the client using the wsdlLocation, new QName(“http://scoreboard.delunasaenz.com/&#8221;, “ScoreboardWSService”) as the parameters to start it.

On the initialize method we add a listener to the leagueSelection ChoiceBox making the VBox to be filled with the current games on the league selected, the leagues are obtained thanks to web service we defined.

I hope this can get you a good brief explanation on how to start and use a WebService from a FXML/JavaFX application.

Stop the press… xD

I’ve been working hard with a project that uses a lot of text data in a TableView, usually the tableviews uses about 8 columns for each row and can be more than 100000 rows on a “bad user search”…

the problem with this is that TableView use to “paint” (outside the screen) all the cells involved (above) the line that has to be presented when you use the scroolTo(int) function, so with tables like the one i described the response can became veeeery slooow…

after making a research i wrote a “work around” for those tables with the same height on all the rows:

package my.good.stuff.package.utils;

import com.sun.javafx.scene.control.skin.TableViewSkin;
import com.sun.javafx.scene.control.skin.VirtualContainerBase;
import com.sun.javafx.scene.control.skin.VirtualFlow;
import javafx.scene.Node;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableView;

/**
* @author charly
*/
public class MyVeryGoodTableView extends TableView
{
protected double rowHeight;
@Override
public void scrollTo(int registro){
TableViewSkin skin = (TableViewSkin)getSkin();
VirtualFlow vf = null;
for(Node node : skin.getChildren()){
if(node instanceof VirtualFlow){
vf = (VirtualFlow)node;
}
}
ScrollBar bar=null;
for(Node node : vf.getChildrenUnmodifiable()){
if(node instanceof ScrollBar){
bar=(ScrollBar)node;
if(Orientation.VERTICAL== bar.getOrientation()){
bar.valueProperty().set((double)(
((double)registro/(double)(getItems().size()-1))
*bar.getMax()));
}
}
}
}

public double getRowHeight() {
return rowHeight;
}

public void setRowHeight(double rowHeight) {
this.rowHeight = rowHeight;
}

}

Hope this works for you… after this we will continue with the JavaFX tutorial…  xD

La reusabilidad viene en varios sabores, el peor de ellos es el copy/paste o el mueve_este_archivo_y_vuelvelo_a_usar, y el mejor de los sabores es el usa_este_modulo. Para obtener este último sabor se debe considerar cuantos proyectos (módulos) debe tener uno. Yo recomiendo por lo menos 2 (aún cuando uno programa algo tan sencillo como un “casi Hola Mundo”), uno para la capa de presentación (Vista y controladores con un “cliente del modelo”) y otro con el Modelo, que incluye la Lógia  de Megocios y los DAOs

Normalmente se necesitará una Façade -Una Façade (o Fachada) es un objeto que recibe peticiones (en este caso para CUALQUIERA de los “métodos” de la Lógica de Negocios) y los redirige al objeto correcto que puede resolver dicha petición (En este caso un Objeto de Lógica de Negocios) y puede ser publicada despues como un Web Service o usado por cualquier otra capa de presentación como JSP/JSF-. Asi pues, si uno quiere “aislar” la Façade en un proyecto nuevo para poder ser reutilizado por otro proyecto similar definitivamente tendría que ser otro módulo o proyecto (piensen en un banco que tiene diferentes políticas de impuestos dependiente del sistema y el país donde se acceda al sistema; cada sistema y país tendrían sus propios objetos de negocio de acuerdo a las especificaciones de la Fachada).

Generalmente cuando uno habla de modularidad encontramos buenas razones para hacer más y más módulos cada vez, les recomiendo leer el refcard   http://refcardz.dzone.com/refcardz/patterns-modular-architecture.

La siguiente entrada será sobre un diseño de UI basado en un escenario complejo de manera que podamos utilizar FXML y sus controlers, debo disculparme por estas dos partes de introducción “teóricas”  que habla principalmente de patrones.

Saludos y hasta la siguiente.