miércoles, 29 de septiembre de 2010

ICEfaces - Partial Submit - Procesamiento Inteligente de Formularios

Partial Submit - Intelligent Form Processing


(Submit Parcial - Procesamiento Inteligente de Formularios)


Voy a dedicar este post a recordar el funcionamiento del "Partial Submit" (o procesamiento inteligente de formularios) a partir de la propia documentación oficial de ICEfaces (Partial Submit).

ICEfaces nos proporciona un modelo de interacción con el usuario muy depurado y de alto nivel para el procesamiento inteligente de formularios durante el desarrollo de aplicaciones ICEfaces. Con JSF, el mecanismo de submit normal inicia el ciclo de vida de una aplicación JSF, y como tal, determinadas funcionalidades no se permiten, como por ejemplo, la validación del formulario en el cliente.

El "Partial Submit" (o submit parcial) resuelve estas limitaciones incluyendo el mecanismo de eventos de JavaScript dentro del ciclo de vida de la apilcación JSF mediante el submit automático. Este submit automático es parcial en el sentido de que sólo se realiza una
validación parcial del formulario. El módulo "Ajax bridge" lleva a cabo una monitorización inteligente para identificar el control asociado al submit parcial, deshabilitando la propiedad "required" del resto de controles del formulario. A partir de aquí, el ciclo de vida JSF se desencadena de una forma normal, tras el cual se reestablece las
propiedades "required" a su estado previo.

El efecto global del submit parcial permite ejecutar el proceso de validación completamente, sin embargo aquellos campos del formulario que se encuentren vacíos no provocarán ningún error de validación. La figura 9 ilustra el submit parcial basado en el evento JavaScript "onBlur" que se genera cuando el usuario se desplaza entre los campos del formulario. En el cliente, Ajax nos proporciona un mecanismo apropiado para enlazar los eventos JavaScript con el procesamiento del submit parcial. Los detalles de la API se pueden consultar en la API de referencia de JavaScript, sin embargo el mecanismo descrito sólo se apoya en una pequeña parte de JavaScript que está definida en un determinado atributo JavaScript de la instancia del
componente JSF implicado y causante del submit parcial. La granularidad en la que tiene lugar el submit parcial se encuentra bajo el control del desarrollador totalmente. En ciertos casos, podría ser apropiado evaluar y reaccionar ante la entrada del usuario a partir de pulsaciones de
teclas, y en otros casos, cuando el foco se desplace entre los controles del formulario. En otras ocasiones, sólo determinados controles del formulario deberían iniciar un submit parcial.

Figura 9 Partial Submit Basado en el evento OnBlur

La lógica de la aplicación asociada al partial submit también se encuentra bajo el control total del desarrollador. El mecanismo de validación estándar de JSF puede mejorarse, o puede aplicarse cualquier lógica de evaluación simple o compleja. Si se utilizan las validaciones estándares de JSF, es importante diseñarlas de forma que faciliten los submits parciales. La demo "Address Form", incluida en los ejemplos proporcionados por ICEfaces, ilustra dos mecanismos diferentes que pueden ser desarrollados bajo el partial submit. Se añaden
validaciones estándares a los ampos City, State, y ZIP, para capturar entradas no válidas, sin embargo también se lleva a cabo una evaluación sobre la tupla de campos {City:State:ZIP}. Utilizando los eventos "valueChangedEvents" asociados a los controles de entrada, es posible realizar un análisis entre campos y transformar el formulario basándonos en la entrada actual. Por ejemplo, al introducir una Ciudad válida hará que el control de la entrada Estado cambie a partir del valor introducido añadiendo a al control select-one-of-many asociado sólo los valores de los estados que estén relacionados con el valor previamente introducido en el campo anterior.

miércoles, 4 de agosto de 2010

Facelets Essentials: Guide To JavaServer Faces View Definition Framework


1. Definition.
2. Facelets Vs JSP.
3. Features.
4. Creating an application with facelets.
    4.1. Downloading Facelets.
    4.2. Adding Dependency.
    4.3. Creating a Project Structure.
    4.4. Configuring the Web descriptor (web.xml)
    4.5. Configuring the Faces descriptor (faces-config.xml)
    4.6. Creating JSF Views
    4.7. Unified Expression Language
    4.8. Tag Libraries
    4.9. Facelets Templating and Template Clients
    4.10. Facelets Tags

1. Definition

Facelets is a templating language that provides a highly performant, JSF-centric view technology.

2. Facelets Vs JSP
  • JSP and JSF don't naturally complement each other.
  • JSP is used to create static and dynamic web content but not to create component trees.
  • Its elements are processed in a page from top to bottom with the basic objective of creating a response to a request. JSF has a more complex life cycle, component generation and rendering happen in clearly separated phases.
  • When use together, JSP and JSF both write output to the response, but they do so differently: the JSP container creates output as soon as it finds JSP content, whereas JSF component dictate its own rendering. This difference can cause some problems.
  • Problems found between JSP and JSF can frustate developers using JSF for the first time who does not know the implementation details of both JSP and JSF.
  • Facelets fills the gap between JSP and JSF.
  • Facelets is a view technology focused on building component trees and interweaving content with the complex JSF life cycle.
  • Facelets replace JSP with a very simple API that is a reflection of its simple principles, and it incorporate numerous developer-friendly features.

3. Features
  • Facelets does not depend on a web container. We can use JSF 1.2 without having to use JEE5 or a container that already has JSP 2.1.
  • Facelets can work with any implementation and version of JSF.
  • As mentioned previously, interweaving JSP and JSF can cause difficulties.
  • JSTL cannot be used with JSF. Facelets provides a solution to this incompatibility.
  • Facelets provides a compilation process that is much faster than JSP's, because no Java bytecode is actually generated and compiled behind the scenes when you first visit your page.
  • Facelets provides templating, so you can reuse your code extensively to simplify the development and maintenance of large-scale applications.
  • Facelets allows the creation of lightweight components.
  • Facelets has Unified Expression Language (EL) support.
  • Facelets does not require any special render kits.

4. Creating an application with facelets

4.1 Downloading Facelets
  • You can download a release binary from
    http://facelets.dev.java.net/servlets/ProjectDocumentList
  • The Facelets artifact can be found in the Maven Central Repository

    (http://www.ibiblio.org/maven2/) and in the Java.net Maven Repository (https://maven- repository.dev.java.net/repository/). You can include the artifact in your project by adding the following dependency to your Project Object Model (POM):

    <dependency>

      <groupId>com.sun.facelets</groupId>

      <artifactId>jsf-facelets</artifactId>

      <version>1.1.13</version>

    </dependency>


    Version 1.1.13 is the current one at the time of this writing. You should use a newer version if possible.

4.2. Adding Dependency

PROJECT

BUILD

INCLUDED

DESCRIPTION

Apache MyFaces

No

No

Implements JSF 1.1 and JSF 1.2.

JavaServer Faces RI

No

No

The reference implementations of JSF 1.1 and JSF 1.2 are available for use with your application.

JavaServer Faces API

Yes

Yes

JSF 1.2 API that works with the new EL specification. (Optionally, MyFaces Core API could be used.)

EL API

Yes

Yes

The stand-alone EL utilized by both JSP and JSF.

EL RI

No

Yes

The reference implementation that is used by Facelets for handling EL.

Servlet API

Yes

Yes

Servlet API

XML SAX

Yes

No

This dependency should not be an issue for most deployments, as it's astandard part of web containers and JREs.


4.3. Creating a Project Structure

Including the correct list of libraries can be one of the trickiest parts when starting a project. Missing libraries or incompatibilities between its versions can lead to obscure exceptions and increase developer frustration. Moreover, the diversity of web containers, each of them with its own libraries and particularities, makes this task even more complex.

In a project that uses Facelets and MyFaces, a common directory structure would look like this:

$PROJECT
+- /WEB-INF
+- /lib
+- /commons-beanutils.jar
+- /commons-collections.jar
+- /commons-digester.jar
+- /commons-logging.jar
+- /el-api
+- /el-impl
+- /jsf-facelets.jar
+- /myfaces-api.jar
+- /myfaces-impl.jar
+- /web.xml
+- /faces-config.xml
+- /[xhtml documents]

The EL libraries (el-api and el-impl) need to be excluded if the container is JSP 2.1 compliant. JSP 2.1 already contains an EL implementation, and you would have a conflict when starting the application.
If you are using the Reference Implementation (RI), replace myfaces-api.jar and myfaces-impl.jar with jsf-ri.jar and jsf-api.jar.
Note: if you’re using Maven, you do not need to worry about the dependencies, as Maven will get them for you. You need to declare the JSF implementation in your POM file, though.
4.4. Configuring the Web descriptor (web.xml)

We need to include the context parameter javax.faces.DEFAULT_SUFFIX, which defines the suffix of the documents for your views. By convention, the default extension for pages built using Facelets is *.xhtml.

<web-app>
..............
<!-- Use Documents Saved as *.xhtml -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
</web-app>

4.5. Configuring the Faces descriptor (faces-config.xml)

Facelets replaces the default JavaServer Faces ViewHandler with its own implementation represented by the class com.sun.facelets.FaceletViewHandler.

<faces-config>
<application>
<view-handler>
com.sun.facelets.FaceletViewHandler
<!-- Icefaces => com.icesoft.faces.facelets.D2DFaceletViewHandler-->
</view-handler>
</application>
</faces-config>

4.6. Creating JSF Views
  • Create a template and define the different areas
  • Create a project structure like the following

    $PROJECT
    +- /WEB-INF
    +- /lib [with dependencies]
    +- web.xml
    +- faces-config.xml
    +- template.xhtml
    +- index.xhtml
    +- parrot.xhtml
    +- eagle.xhtml
    +- menu.xhtml
  • Create documents with the extension *.xhtml
  • One of them is the template.xhtml used by the other pages
  • menu.xhtml will be used to navigate through the application.
  • With the Facelets UI tag “ui:insert” we define areas in the page (template) that can be overwritten
  • We need to use the http://java.sun.com/jsf/facelets namespace to use the Facelets tags. By convention, we define “ui” as the prefix for the UI Facelets library tags.
  • We can define default content for the areas just by nesting this content in the “ui:insert” tag.
  • We are using three new Facelets tags: “ui:composition”, “ui:define”, and “ui:include”.
    • We use the “ui:composition” tag’s template attribute to reference the template we want to use for the page. Everything inside the “ui:composition” tag will be evaluated by Facelets when compiling the document. All elements outside the “ui:composition” tag will be ignored.
    • Use the “ui:define” tag to define the content that will go in the areas declared in the template. The name attribute of the ui:define tag must match the one of the ui:insert tag in the template.
    • “ui:include” tag allows us to include the content from another document.
  • We use “h:commandLink” with action attributes defined to trigger the navigation in our application . It builds a link that will take the user to the page indicated in the navigation rule. We define this rule in the faces-contig.xml with the following tag,

    <navigation-rule>
    <navigation-case>
    <from-outcome>action_name</from-outcome>
    <to-view-id>/view_page.xhtml</to-view-id>
    </navigation-case>
    </navigation-rule>

4.7. Unified Expression Language
  • The Unified Expression Language was successfully created in an attempt to align the Expression Languages (ELs) used in JSP 2.0 and JSF 1.1.
    • JSP EL uses ${. . .}
    • JSF EL uses #{. . .}
  • Thanks to the Unified EL, JSTL tags, such as the iteration tags, can now be used intuitively with JSF components .
  • Facelets uses the new Unified EL. It supports the use of ${. . .} and #{. . .} syntax , so you can use either one, depending on the developer’s particular tast e.
  • With Facelets, you can insert an EL expression anywhere in the page

    <p>The Happy Birds Directory
    contains #{directoryBean.totalCount} birds.
    </p>

4.8. Tag Libraries
  • To use a tag library in our page, we must declare it by using its namespace. We can do that by mapping the library’s URI (or URL) to a prefix.
  • Facelets uses a couple of strategies to load tag libraries.
    • It searches the classpath trying to find libraries in the /META-INF folder of the JAR files. It will try to load any file that has the extension *.taglib.xml.
    • Facelets will check the libraries defined in the web.xml file with the initialization parameter facelets.LIBRARIES.
  • Tag libraries included in the Facelets binaries
    • Templating library: This contains the tags using for templating.
    • JSF libraries: The two tag libraries for the JavaServer Faces specification are supported by default by Facelets.
    • JSTL: Facelets provides partial support for JavaServer Pages Standard Tag Library (JSTL) tags. While the Function library is fully supported, the Core tags are only partially so. The Core tags supported by Facelets are: c:if, c:forEach, c:catch, and c:set.
  • If you want to use other libraries that do not have a Facelets tag library, you will need to create the tag library file yourself and register it in your web.xml file, if the tag library was not already included in a JAR . Add the library under the parameter facelets.LIBRARIES, and separate multiple libraries with semicolons.

4.9. Facelets Templating and Template Clients
  • Facelets templates can be created from both JSF components and HTML tags. Templates can be interwoven thanks to the fact that they are compiled during the render phase.
  • We distinguish in Facelets between templates and template clients. The latter use the templates to create variations of the same pattern.
  • A template defines spots where the content can be replaced. Which content is used in those spots is defined by the clients. The template defines the different areas using the ui:insert tag, and the clients use the templates with ui:component, ui:composition, ui:fragment, or ui:decorate tags.
  • Templating in Facelets is not just limited to one level. It is possible to have multilevel templating, as a client for one template can be a template for other client templates. Hence, Facelets powerful templating support allows you to create complex composite applications.
  • Facelets will interpret the EL expressions within the HTML comments (<!-- -->) unless the context parameter facelets.SKIP_COMMENTS is set to true in the web.xml file.

4.10. Facelets Tags
  • <ui:component/>: inserts a new UIComponent instance as the root of JavaServer Faces tree.
  • <ui:composition/>: it is used to encapsulate content that can be included in other Facelets pages.
  • <ui:debug/>: When launched using the combination Ctrl + Shift + (D, by default), it will display a pop-up window that shows the component tree and the scoped variables.
  • <ui:decorate/>: is similar to the ui:composition tag, the only difference being that the decorate tag does not remove everything outside of it. You can use this tag to add some content around the decorated section by using a template.
  • <ui:define/>: can be used to insert named content into a template. It can be used within tags that allow templating, such as the ui:composition and ui:decorate tags. The names used in the define tag must match the names used in the ui:insert tags in the target template.
    : is similar to the ui:component tag, but the fragment tag does not trim the content outside itself.
  • <ui:include/>: can be used to include another Facelets file into your document. It simply includes whatever source file you specify.
  • <ui:insert/>: is used to specify in a template those parts that can be replaced by ui:define tags declared in the client template.
  • <ui:param/>: This tag is used to pass objects as named variables between Facelets.
  • <ui:remove/>: The ui:remove tag is used to remove blocks of code at compilation time. It has no attributes, though you can use this tag in conjunction with the jsfc attribute.
  • <ui:repeat/>: The ui:repeat tag is used to iterate over a list of objects, and we always recommend its use instead c:forEach from the JSTL Code tag library.
  • Note: ui:repeat and c:forEach are different. ui:repeat is a render-time evaluation, whereas c:forEach is a build-time evaluation. c:forEach does not represent a component in Facelets (it is a TagHandler) and will never become part of the component tree. It is used to create the tree when the page is first referenced (when the request is not a postback), but after that, c:forEach will not do anything else. On the other hand, ui:repeat is implemented as a component in Facelets and is part of the component tree. As an example, you could develop a list of elements with a button to add more elements. If you used forEach for the iteration, the new elements would never be added when the button is clicked (which is a postback).

miércoles, 14 de julio de 2010

La Mascota Oficial de Sun, Duke, está con la roja

Duke, la Mascota Oficial de Sun, está con la roja.
Tras la épica victoria ante Holanda de la selección española de fútbol por 1 gol a 0, el pasado domingo 11 de julio de 2010 , la mascota de Sun Microsystems, Duke, se viste con los colores de nuestra selección como sincero homenaje y para compartir con todos los españoles la emoción y la enorme felicidad de ser campeones del mundo de fútbol.

11 de julio de 2010, 20:30 - Estadio Soccer City, Johannesburgo


La selección española de fútbol, de la mano de Iker Casillas, levantando la copa del mundo de fútbol

Noticias de interés:
Enlaces de interés:

jueves, 8 de julio de 2010

ICEfaces 1.8: Next Generation Enterprise Web Development

Hello all people interested in ICEfaces world. I've just read "ICEfaces 1.8: Next Generation Enterprise Web Development" and now I present in this post the most important notes that I have written about it. I hope this is useful for you.



Index

Chapter 1: Next Generation Java Development.
Chapter 2: Development Environment.
Chapter 3: User Interface Design.
Chapter 4: Components For Navigation and Layout.
Chapter 5: Components For Feedback and Behaviour.
Chapter 6: Components For Data Presentation and Multimedia.
Chapter 7: Components For Data Creation and Selection.
Chapter 8: User Interfaces Customization.
Chapter 9: Reusable Facelets Components.
Chapter 10: Push Technology.

Chapter 1: Next Generation Java Development
  • ICEfaces
    • Icesoft defines ICEfaces as an AJAX extension of JavaServer Faces.

Chapter 2: Development Environment
  • Spring Framework
    • Dependency Injection
      • Spring beans instead of JSF beans → implements Backing Bean Concept
    • Used in all layers
    • Transaction Management & persistence
      • Hibernate → Object Relational Mapping → through annotations
    • Spring Security
      • Protect Web Access → login, remember me, logout...
  • Hibernate
    • POJOs → managing persistence
    • AppFuse framework → automated generation of hibernate artifacts during build process.
  • Apache tomahawk
    • JSF components that extend JSF specification.
    • 100% compatible with the Sun JSF 1.1 Reference Implementation (RI / mojarra) or any other JSF 1.1 compatible implementation
    • For further information on compatibility between Tomahawk and other frameworks/libraries, please see the relevant wiki page

Chapter 3: User Interface Design.
  • User Interfaces Design
    • An important part of the user interface design is the page layout.
    • web applications that mimic desktop behavior
    • desktop metaphor in the Web context mixed with user habits based on the first decade of the Web
    • shift your mind to components and events
    • Software ergonomics
      • ISO standard 9241, Ergonomics of Human System Interaction (http://en.wikipedia.org/wiki/ISO_9241)? This standard describes how a system has to be designed to be human-engineered. The most important part of ISO 9241 for software developers is part 110, dialog principles,
        • Suitability for the task
        • Suitability for learning
        • Suitability for individualization
        • Conformity with user expectations
        • Self-descriptiveness
        • Controllability
        • Error tolerance
    • The technical limitations that derive from your framework decisions can be additionally frustrating.
    • Occam's razor: “everything should be made as simple as possible, but not simpler”.
    • User interface design principles
      • Suitability for the task: the functionality of a web application seldom delivers what the user requires to fulfill his needs.
      • Self-descriptiveness: what is the context I am working in at the moment?, what is the next possible step?
      • Controllability: the user must be able to stop his/her work at any time. For example, for a lunch break or telephone call, without any disadvantages.
      • Conformity with user expectations: cultural background, similar socialization, use of words of the target language, standardization, single implementation for each context that is reused in different web pages.
      • Error tolerance: allow mishandling of the application. dialog boxes presenting corresponding error information.
      • Suitability for individualization: If you add more flexibility to the user interface, keep in mind that it becomes more complex. Finding the right balance is a process. So, do not stop with the first iteration.
      • Suitability for learning: the user chooses the trial and error process to learn a new application. For this, the application has to be intuitive in its usage.
  • Interface Layout
    • The layout design: Defines the logical output sections of a web application.
    • The navigation design: Defines how to use the web application.
    • The skin design: Defines how a web application looks.
  • Create drafts with a mockup tool
  • The web page is separated into:
    • Header: a graphic that covers the complete section that is an integral part of brand recognition.
    • Main navigation: saving space.
    • Content: use dialogs with a caption. Content is used for everything that has to be presented to the use,
      • Forms to manipulate data of the backend; for example, for administration purposes.
      • Informational pages that show, for example, tables of data records for certain system objects.
      • More complex and interactive components that may allow a prompt result, such as a GoogleMap presentation.
    • Footer: status information, copyright, privacy policy, the terms of use, or a link to an about page.
  • Facelets templating
    • Facelets templating is used to implement the layout design. It is officially a part of the JSF specification since release 2.0.
    • The page template
      • File | New | Other | Web | HTML Page → page-template.xhtml for File name → choose New ICEfaces Facelets.xhtml File (.xhtml).
      • Eclipse → Select File → Open with → Web Page Editor.
      • Tags introduced: <ui:insert name=””>, <ui:include src=””>
      • We need a reference to one of the ICEfaces default skins in the <head> tag to get a correct menu presentation.
    • Using the template
      • Including CSS, Javascript or FavIcon.
      • We need a reference to the page template so that the templating knows that it has to manage the page. As the page template defines the page structure, we no longer need a <head> tag definition.
      • Facelets has a look at the complete code base and matches pairs of corresponding name attribute definitions between <ui:insert name="..."> and <ui:define name="..."> tags.
      • <ui:insert name="..."> tag allows us to set defaults that are used if we do not definesomething for replacement.
      • <ui:composition template=””>, <ui:define>
  • The templating in ICEfusion
    • Delivers a standardized templating based on experiences from productive development.
    • Maven 2 conventions
    • folder names follow the AppFuse conventions
    • The new tags are managed via a Facelets tag library. We use the icefusion namespace to reference the tags
    • <ui:component> tag describes where the code for a Facelets tag starts and stops. Everything outside this tag is ignored
    • With ICEfusion, we get a production-ready templating implementation that can be used for the creation of ICEcube. ICEcube can then be extended with the code examples from the chapters that follow.

viernes, 2 de julio de 2010

Java - Estándares de programación

Índice

1. Estándares de programación
    1.1. Introducción
    1.2. Organización de ficheros
           1.2.1. Fichero fuente Java (.java)
                     1.2.1.1. Comentarios de inicio
                     1.2.1.2. Sentencias de paquete
                     1.2.1.3. Sentencias de importación
                     1.2.1.4. Declaraciones de clases e interfaces
    1.3. Sangría
           1.3.1. Longitud de línea
           1.3.2. División de líneas
    1.4. Comentarios
           1.4.1. Comentarios de implementación
           1.4.2. Comentarios de documentación
   1.5. Declaraciones
           1.5.1. Una declaración por línea
           1.5.2. Inicialización
           1.5.3. Localización
           1.5.4. Declaración de clases / interfaces
    1.6. Sentencias
    1.7. Espacios en blanco
    1.8. Nomenclatura de identificadores
           1.8.1. Paquetes
           1.8.2. Clases e interfaces
           1.8.3. Métodos
           1.8.4. Variables
           1.8.5. Constantes
    1.9. Prácticas de programación
           1.9.1. Visibilidad de atributos de instancia y de clase
           1.9.2. Referencias a miembros de una clase
           1.9.3. Constantes
           1.9.4. Asignación sobre variables
           1.9.5. Otras prácticas
2. Documentación: javadoc

1. Estándares de programación

1.1. Introducción

El objeto del presente documento es el establecimiento de los estándares o convenciones de programación empleados en el desarrollo de software sobre la plataforma Java. Este modelo de programación está basado en los estándares recomendados por Sun Microsystems, que han sido difundidos y aceptados ampliamente por toda la comunidad Java, y que han terminado por consolidarse como un modelo estándar de programación de facto.

Estas normas son muy útiles por muchas razones, entre las que destacan:

  • Facilitan el mantenimiento de una aplicación. Dicho mantenimiento constituye el 80% del coste del ciclo de vida de la aplicación.

  • Permite que cualquier programador entienda y pueda mantener la aplicación. En muy raras ocasiones una misma aplicación es mantenida por su autor original.

  • Los estándares de programación mejoran la legibilidad del código, al mismo tiempo que permiten su compresión rápida.



1.2. Organización de ficheros

Las clases en Java se agrupan en paquetes. Estos paquetes se deben organizar de manera jerárquica, de forma que todo código desarrollado para el Ayuntamiento de Málaga tendrá que estar incluido dentro del paquete "eu.malaga".
Dentro del paquete principal las clases se organizarán en subpaquetes en función del área, organismo o sección del Ayuntamiento al que pertenezca el código desarrollado. Por ejemplo, si estamos desarrollando un servicio web de inscripción a un curso de programación Java del IMFE las clases de dicho servicio se incluirían en el paquete "eu.malaga.imfe.webservices.cursojava" o similar.

Un fichero consta de secciones que deben estar separadas por líneas en blanco y comentarios opcionales que identifiquen cada sección.

Deben evitarse los ficheros de gran tamaño que contengan más de 1000 líneas. En ocasiones, este tamaño excesivo provoca que la clase no encapsule un comportamiento claramente definido, albergando una gran cantidad de métodos que realizan tareas funcional o conceptualmente heterogéneas.

1.2.1. Fichero fuente Java (.java)

Cada fichero fuente Java debe contener una única clase o interfaz pública. El nombre del fichero tiene que coincidir con el nombre de la clase. Cuando existan varias clases privadas asociadas funcionalmente a una clase pública, podrán colocarse en el mismo fichero fuente que la clase pública. La clase pública debe estar situada en primer lugar dentro del fichero fuente.
En todo fichero fuente Java distinguimos las siguientes secciones:

  • Comentarios de inicio.

  • Sentencia de paquete.

  • Sentencias de importación.

  • Declaraciones de clases e interfaces.



1.2.1.1. Comentarios de inicio

Todo fichero fuente debe comenzar con un comentario que incluya el nombre de la clase, información sobre la versión del código, la fecha y el copyright. El copyright indica la propiedad legal del código, el ámbito de distribución, el uso para el que fue desarrollado y su modificación.

Dentro de estos comentarios iniciales podrían incluirse adicionalmente comentarios sobre los cambios efectuados sobre dicho fichero (mejora, incidencia, error, etc.). Estos comentarios son opcionales si los ficheros están bajo un sistema de control de versiones bien documentado, en caso contrario se recomienda su uso. Estos comentarios constituyen el historial de cambios del fichero. Este historial es único para cada fichero y permitirá conocer rápidamente el estado y la evolución que ha tenido el fichero desde su origen.

A continuación se muestra un comentario de inicio para la clase "JceSecurity.java".

/*
* @(#)JceSecurity.java 1.50 04/04/14
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

/**
* This class instantiates implementations of JCE engine classes from
* providers registered with the java.security.Security object.
*
* @author Jan Luehe
* @author Sharon Liu
* @version 1.50, 04/14/04
* @since 1.4
*/


1.2.1.2. Sentencias de paquete

La primera línea no comentada de un fichero fuente debe ser la sentencia de paquete, que indica el paquete al que pertenece(n) la(s) clase(s) incluída(s) en el fichero fuente. Por ejemplo,


package javax.crypto;


1.2.1.3. Sentencias de importación

Tras la declaración del paquete se incluirán las sentencias de importación de los paquetes necesarios. Esta importación de paquetes obligatorios seguirá el siguiente orden:


  • Paquetes del JDK de java.

  • Paquetes de utilidades no pertenecientes al JDK de Java, de frameworks de desarrollo o de proyectos opensource tales como apache, hibernate, springframework, etc.

  • Paquetes desarrollados para el Ayuntamiento de Málaga.

  • Paquetes de la aplicación.



Se recomienda minimizar en la medida de lo posible el uso de importaciones del tipo "package.*", pues dificultan la comprensión de las dependencias existentes entre las clases utilizadas por la aplicación. En caso contrario, se recomienda utilizar comentarios de línea tras la importación.


import java.io.*; // BufferedReader, PrintWriter, FileInputStream, File
import java.util.ArrayList;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import es.provincia.organismo.corporativas.atlas.vo.AgendaVO;
import es.provincia.organismo.atlas.vo.AnuncioVO;
import es.provincia.organismo.atlas.vo.OrganigramaVO;


1.2.1.4. Declaraciones de clases e interfaces

La siguiente tabla describe los elementos que componen la declaración de una clase o interfaz, así como el orden en el que deben estar situados.

Elementos de declaración de una clase / interfazDescripción
Comentario de documentación de la clase/interfaz /** ... */Permite describir la clase/interfaz desarrollada. Necesario para generar la documentación de la api mediante javadoc.
Sentencia class / interface
Comentario de implementación de la clase/interfaz, si es necesario /* ... */Este comentario incluye cualquier información que no pueda incluirse en el comentario de documentación de la clase/interfaz.
Variables de clase (estáticas)En primer lugar las variables de clase públicas (public), después las protegidas (protected), posteriormente las de nivel de paquete (sin modificador), y por último las privadas (private).
Variables de instanciaPrimero las públicas (public), después las protegidas (protected), luego las de nivel de paquete (sin modificador), y finalmente las privadas (private).
Constructores
MétodosDeben agruparse por funcionalidad en lugar de agruparse por ámbito o accesibilidad. Por ejemplo, un método privado puede estar situado entre dos métodos públicos. El objetivo es desarrollar código fácil de leer y comprender.


1.3. Sangría

Como norma general se establecen 4 caracteres como unidad de sangría. Los entornos de desarrollo integrado (IDE) más populares, tales como Eclipse o NetBeans, incluyen facilidades para formatear código Java.

1.3.1. Longitud de línea

La longitud de línea no debe superar los 80 caracteres por motivos de visualización e impresión.

1.3.2. División de líneas

Cuando una expresión ocupe más de una línea, esta se podrá romper o dividir en función de los siguientes criterios,


  • Tras una coma.

  • Antes de un operador.

  • Se recomienda las rupturas de nivel superior a las de nivel inferior.

  • Alinear la nueva línea con el inicio de la expresión al mismo nivel que la línea anterior.

  • Si las reglas anteriores generan código poco comprensible, entonces estableceremos tabulaciones de 8 espacios.



Ejemplos:

unMetodo(expresionLarga1, expresionLarga 2, expresionLarga 3,
expresionLarga 4, expresionLarga 5);

if ((condicion1 && condicion2)
|| (condicion3 && condicion4)
||!(condicion5 && condicion6)) {
unMetodo();
}


1.4. Comentarios

Distinguimos dos tipos de comentarios: los comentarios de implementación y los de documentación.

1.4.1. Comentarios de implementación

Estos comentarios se utilizan para describir el código ("el cómo"), y en ellos se incluye información relacionada con la implementación, tales como descripción de la función de variables locales, fases lógicas de ejecución de un método, captura de excepciones, etc.

Distinguimos tres tipos de comentarios de implementación:

  • Comentarios de bloque:

    Permiten la descripción de ficheros, clases, bloques, estructuras de datos y algoritmos.


    /*
    * Esto es un comentario
    * de bloque
    */


  • Comentarios de línea:

    Son comentarios cortos localizados en una sola línea y tabulados al mismo nivel que el código que describen. Si ocupa más de una línea se utilizará un comentario de bloque. Deben estar precedidos por una línea en blanco.


    /* Esto es un comentario de línea */

    // Esto es otro comentario de línea


  • Comentario a final de línea

    Comentario situado al final de una sentencia de código y en la misma línea.


    int contador = 4 + 10; // Inicialización del contador
    contador++; /* Incrementamos el contador */




1.4.2. Comentarios de documentación

Los comentarios de documentación, también denominados "comentarios javadoc", se utilizan para describir la especificación del código, desde un punto de vista independiente de la implementación, de forma que pueda ser consultada por desarrolladores que probablemente no tengan acceso al código fuente.

El apartado 2 de este documento describe el uso de comentarios de documentación.


1.5. Declaraciones

1.5.1. Una declaración por línea

Se recomienda el uso de una declaración por línea, promoviendo así el uso de comentarios. Ejemplo,


int idUnidad; // Identificador de la unidad organizativa
String[] funciones; // Funciones de la unidad


1.5.2. Inicialización

Toda variable local tendrá que ser inicializada en el momento de su declaración, salvo que su valor inicial dependa de algún valor que tenga que ser calculado previamente.


int idUnidad = 1;
String[] funciones = { "Administración", "Intervención", "Gestión" };


1.5.3. Localización

Las declaraciones deben situarse al principio de cada bloque principal en el que se utilicen, y nunca en el momento de su uso.


public void unMetodo() {
int contador = 0; // inicio del método

...
}


La única excepción a esta regla son los índices de los bucles "for", ya que, en Java, pueden incluirse dentro de la propia sentencia "for".


for (int i=0; contador<10; i++) {
...
}

Se debe evitar el uso de declaraciones que oculten a otras declaraciones de ámbito superior.


int contador = 0; // Inicio del método

public void unMetodo() {

if (condicion) {
int contador = 2; // ¡¡ EVITAR !!
...
}
...
}


1.5.4. Declaración de clases / interfaces

Durante el desarrollo de clases / interfaces se deben seguir las siguientes reglas de formateo:

  • No incluir ningún espacio entre el nombre del método y el paréntesis inicial del listado de parámetros.

  • El carácter inicio de bloque ("{") debe aparecer al final de la línea que contiene la sentencia de declaración.

  • El carácter fin de bloque ("}") se sitúa en una nueva línea tabulada al mismo nivel que su correspondiente sentencia de inicio de bloque, excepto cuando la sentencia sea nula, en tal caso se situará detrás de "{".

  • Los métodos se separarán entre sí mediante una línea en blanco.




public classe ClaseEjemplo extends Object {

int variable1;
int variable2;

public ClaseEjemplo() {
variable1 = 0;
variable2 = 1;
}
...
}


1.6. Sentencias

Cada línea debe contener como máximo una sentencia. Ejemplo,


int contador++;
int variable--;


Las sentencias pertenecientes a un bloque de código estarán tabuladas un nivel más a la derecha con respecto a la sentencia que las contiene.

El carácter inicio de bloque "{" debe situarse al final de la línea que inicia el bloque. El carácter final de bloque "}" debe situarse en una nueva línea tras la última línea del bloque y alineada con respecto al primer carácter de dicho bloque.

Todas la sentencias de un bloque deben encerrarse entre llaves "{ ... }", aunque el bloque conste de una única sentencia. Esta práctica permite añadir código sin cometer errores accidentalmente al olvidar añadir las llaves. Ejemplo,


if (condicion) {
variable++;
}


La sentencia "try/catch" siempre debe tener el formato siguiente,


try {
sentencias;
} catch (ClaseException e) {
sentencias;
}


En el bloque "catch" siempre se imprimirá una traza de error indicando el tipo de excepción generada y posteriormente se elevará dicha excepción al código invocante, salvo que la lógica de ejecución de la aplicación no lo requiera.

Siempre se utilizará el bloque "finally" para liberar recursos y para imprimir trazas de monitorización de fin de ejecución.


try {
sentencias;
} catch (ClaseException e) {
sentencias;
} finally {
sentencias;
}



1.7. Espacios en blanco

Las líneas y espacios en blanco mejoran la legibilidad del código permitiendo identificar las secciones de código relacionadas lógicamente.

Se utilizarán espacios en blanco en los siguientes casos:

Entre una palabra clave y un paréntesis. Esto permite que se distingan las llamadas a métodos de las palabras clave. Por ejemplo:


while (true) {
...
}


Tras cada coma en un listado de argumentos. Por ejemplo:


objeto.unMetodo(a, b, c);


Para separar un operador binario de sus operandos, excepto en el caso del operador ("."). Nunca se utilizarán espacios entre los operadores unarios (p.e., "++" o "--") y sus operandos. Por ejemplo:


a += b + c;

a = (a + b) / (c + d);

contador++;


Para separar las expresiones incluidas en la sentencia "for". Por ejemplo:


for (expresion1; expresion2; expresion3)



Al realizar el moldeo o "casting" de clases. Ejemplo:


Unidad unidad = (Unidad) objeto;


1.8. Nomenclatura de identificadores

Las convenciones de nombres de identificadores permiten que los programas sean más fáciles de leer y por tanto más comprensibles. También proporcionan información sobre la función que desempeña el identificador dentro del código, es decir, si es una constante, una variable, una clase o un paquete, entre otros.

1.8.1. Paquetes

Se escribirán siempre en letras minúsculas para evitar que entren en conflicto con los nombres de clases o interfaces. El prefijo del paquete siempre corresponderá a un nombre de dominio de primer nivel, tal como: es, eu, org, com, net, etc.

El resto de componentes del paquete se nombrarán de acuerdo a las normas internas de organización de la empresa: departamento, proyecto, máquina, sección, organismo, área, etc.

Generalmente se suele utilizar el nombre de dominio de Internet en orden inverso. Cuando dicho nombre contenga un carácter "-", este se sustituirá por el carácter "_".

Ejemplos:


es.provincia.organismo1.festivaldecine
es.provincia.organismo2.vivienda
es.provincia.organismo3.juventud
es.provincia.organismo3.formacion
es.provincia.organismo3.gestionturistica

java.util.ArrayList
java.util.Date
java.util.Properties

javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpServletResponse


1.8.2. Clases e interfaces

Los nombres de clases deben ser sustantivos y deben tener la primera letra en mayúsculas. Si el nombre es compuesto, cada palabra componente deberá comenzar con maýusculas.
Los nombres serán simples y descriptivos. Debe evitarse el uso de acrónimos o abreviaturas, salvo en aquellos casos en los que dicha abreviatura sea más utilizada que la palabra que representa (URL, HTTP, etc.).

Las interfaces se nombrarán siguiendo los mismos criterios que los indicados para las clases. Como norma general toda interfaz se nombrará con el prefijo "I" para diferenciarla de la clase que la implementa (que tendrá el mismo nombre sin el prefijo "I").


class Ciudadano
class OrganigramaDAO
class AgendaService
class IAgendaService


1.8.3. Métodos

Los métodos deben ser verbos escritos en minúsculas. Cuando el método esté compuesto por varias palabras cada una de ellas tendrá la primera letra en mayúsculas.


public void insertaUnidad(Unidad unidad);
public void eliminaAgenda(Agenda agenda);
public void actualizaTramite(Tramite tramite)


1.8.4. Variables

Las variables se escribirán siempre en minúsculas. Las variables compuestas tendrán la primera letra de cada palabra componente en mayúsculas.

Las variables nunca podrán comenzar con el carácter "_" o "$". Los nombres de variables deben ser cortos y sus significados tienen que expresar con suficiente claridad la función que desempeñan en el código. Debe evitarse el uso de nombres de variables con un sólo carácter, excepto para variables temporales.


Unidad unidad;
Agenda agenda;
Tramite tramite;


1.8.5. Constantes

Todos los nombres de constantes tendrán que escribirse en mayúsculas. Cuando los nombres de constantes sean compuestos las palabras se separarán entre sí mediante el carácter de subrayado "_".


int LONGITUD_MAXIMA;
int LONGITUD_MINIMA;


1.9. Prácticas de programación

1.9.1. Visibilidad de atributos de instancia y de clase

Los atributos de instancia y de clase serán siempre privados, excepto cuando tengan que ser visibles en subclases herederas, en tales casos serán declarados como protegidos.

El acceso a los atributos de una clase se realizará por medio de los métodos "get" y "set" correspondientes, incluso cuando el acceso a dichos atributos se realice en los métodos miembros de la clase.


public class Unidad {

private int id;
private String nombre;
...

public void actualizaUnidad(Unidad unidad) {
this.setId(unidad.getId());
this.setNombre(unidad.getNombre());
}

...
}


1.9.2. Referencias a miembros de una clase

Evitar el uso de objetos para acceder a los miembros de una clase (atributos y métodos estáticos). Utilizaremos en su lugar el nombre de la clase. Por ejemplo:


metodoUtilidad(); // Acceso desde la propia clase estática
ClaseUtilidad.metodoUtilidad(); // Acceso común desde cualquier clase


1.9.3. Constantes

Los valores constantes (literales) nunca aparecerán directamente en el código. Para designar dichos valores se utilizarán constantes escritas en mayúsculas y se declararán, según su ámbito de uso, o bien en una Clase de constantes creada para tal efecto, o bien en la clase donde sean utilizadas.


// Uso incorrecto
codigoErrorUsuarioNoEncontrado = 1;
...
switch (error) {
case codigoErrorUsuarioNoEncontrado:
...
}

// Uso correcto
public final int CODIGOERROR_USUARIONOENCONTRADO = 1;
...
switch (error) {
case CODIDOGERROR_USUARIONOENCONTRADO:
...
}


1.9.4. Asignación sobre variables

Se deben evitar las asignaciones de un mismo valor sobre múltiples variables en una misma sentencia, ya que dichas sentencias suelen ser difíciles de leer.


int a = b = c = 2; // Evitar


No utilizar el operador de asignación en aquellos lugares donde sea susceptible de confusión con el operador de igualdad. Por ejemplo:


// INCORRECTO
if ((c = d++) == 0) { }

// CORRECTO
c = d++;
if (c == 0) { }


No utilizar asignaciones embebidas o anidadas. Ejemplo:


c = (c = 3) + 4 + d; // Evitar


debería escribirse


c = 3;
c = c + 4 + d;



1.9.5. Otras prácticas


  • Paréntesis

    Es una buena práctica el uso de paréntesis en expresiones que incluyan distintos tipos de operadores para evitar problemas de precedencia de operadores. Aunque la precedencia de operadores nos pueda parecer clara, debemos asumir que otros programadores no tengan un conocimiento exhaustivo sobre las reglas de precedencia.


    if (w == x && y == z) // INCORRECTO
    if ((w == x) && (y == z)) // CORRECTO



  • Valores de retorno

    Los valores de retorno tendrán que ser simples y comprensibles, de acuerdo al propósito y comportamiento del objeto en el que se utilicen.


    // INCORRECTO
    public boolean esProgramador(Empleado emp) {

    if (emp.getRol().equals(ROL_PROGRAMADOR)) {
    return true;
    } else {
    return false;
    }

    }

    // CORRECTO
    public boolean esProgramador(Empleado emp) {

    boolean esUnProgramador = false;

    if (emp.getRol().equals(ROL_PROGRAMADOR)) {
    esUnProgramador = true;
    }

    return esUnProgramador;
    }



  • Expresiones en el operador condicional ternario

    Toda expresión compuesta, por uno o más operadores binarios, situada en la parte condicional del operador ternario deberá ir entre paréntesis. Ejemplo:


    (x >= y) ? x : y;



  • Comentarios especiales (TODO, FIXME, XXX)

    Utilizaremos XXX para comentar aquella porción de código que, aunque no tenga mal funcionamiento, requiera modificaciones. Usaremos FIXME para señalar un bloque de código erróneo que no funciona. Emplearemos TODO para comentar posibles mejoras de código, como puedan ser las debidas a optimizaciones, actualizaciones o refactorizaciones.




2. Documentación: javadoc

Se aconseja, como buena práctica de programación, incluir en la entrega de la aplicación la documentación de los ficheros fuente de todas las clases. Dicha documentación será generada por la herramienta "javadoc".

La herramienta "javadoc" construirá la documentación a partir de los comentarios (incluidos en las clases) encerrados entre los caracteres "/**" y "*/". Distinguimos tres tipos de comentarios javadoc, en función del elemento al que preceden: de clase, de variable y de método.

Dentro de los comentarios "javadoc" podremos incluir código html y etiquetas especiales de documentación. Estas etiquetas de documentación comienzan con el símbolo "@", se sitúan al inicio de línea del comentario y nos permiten incluir información específica de nuestra aplicación de una forma estándar.

Como norma general utilizaremos las siguientes etiquetas:

  • @author Nombre

    Añade información sobre el autor o autores del código.


  • @version InformacionVersion

    Permite incluir información sobre la versión y fecha del código.


  • @param NombreParametro Descripción

    Inserta el parámetro especificado y su descripción en la sección "Parameters:" de la documentación del método en el que se incluya. Estas etiquetas deben aparecer en el mismo orden en el que aparezcan los parámetros especificados del método. Este tag no puede utilizarse en comentarios de clase, interfaz o campo. Las descripciones deben ser breves.


  • @return Descripción

    Inserta la descripción indicada en la sección "Returns:" de la documentación del método. Este tag debe aparecer en los comentarios de documentación de todos los métodos, salvo en los constructores y en aquellos que no devuelvan ningún valor (void).


  • @throws NombreClase Descripción

    Añade el bloque de comentario "Throws:" incluyendo el nombre y la descripción de la excepción especificada. Todo comentario de documentación de un método debe contener un tag "@throws" por cada una de las excepciones que pueda elevar. La descripción de la excepción puede ser tan corta o larga como sea necesario y debe explicar el motivo o motivos que la originan.


  • @see Referencia

    Permite incluir en la documentación la sección de comentario "See also:", conteniendo la referencia indicada. Puede aparecer en cualquier tipo de comentario "javadoc". Nos permite hacer referencias a la documentación de otras clases o métodos.


  • @deprecated Explicación

    Esta etiqueta indica que la clase, interfaz, método o campo está obsoleto y que no debe utilizarse, y que dicho elemento posiblemente desaparecerá en futuras versiones. "javadoc" añade el comentario "Deprecated" en la documentación e incluye el texto explicativo indicado tras la etiqueta. Dicho texto debería incluir una sugerencia o referencia sobre la clase o método sustituto del elemento "deprecado".


  • @since Version

    Se utiliza para especificar cuando se ha añadido a la API la clase, interfaz, método o campo. Debería incluirse el número de versión u otro tipo de información.


El siguiente ejemplo muestra los tres tipos de comentarios "javadoc",


/**
* UnidadOrganizativa.java:
*
* Clase que muestra ejemplos de comentarios de documentación de código.
*
* @author jlflorido
* @version 1.0, 05/08/2008
* @see documento "Normas de programación v1.0"
* @since jdk 5.0
*/
public class UnidadOrganizativa extends PoolDAO {

/** Trazas de la aplicación */
private Logger log = Logger.getLogger(UnidadOrganizativa.class);

/** Identificador de la unidad organizativa */
private int id;

/** Nombre de la unidad organizativa */
private String nombre;

/** Obtiene el identificador de esta unidad organizativa */
public int getId() {
return id;
}

/** Establece el identificador de esta unidad organizativa */
public void setId(int id) {
this.id = id;
}

/** Obtiene el nombre de esta unidad organizativa */
public String getNombre() {
return nombre;
}

/** Establece el nombre de esta unidad organizativa */
public void setNombre(String nombre) {
this.nombre = nombre;
}

/**
* Inserta la unidad organizativa en el sistema.
*
* @param unidad Unidad organizativa a insertar
* @throws Exception Excepción elevada durante el proceso de inserción
*/
public void insertarUnidad(UnidadOrganizativa unidad) throws Exception{

log.debug("-> insertarUnidad(UnidadOrganizativa unidad)");

Connection conn = null;
PreparedStatement pstmt = null;
StringBuffer sqlSb = null;

try {
conn = this.dameConexion();

sqlSb = new StringBuffer("")
.append("INSERT INTO ORG.UNIDAD_ORGANIZATIVA ")
.append("(ID, NOMBRE) VALUES (?, ?)");

pstmt = conn.prepareStatement(sqlSb.toString());
pstmt.setInt(1, unidad.getId());
pstmt.setString(2, unidad.getNombre());
pstmt.executeUpdate();

} catch (Exception e) {

log.error("Error: error al insertar la unidad. " +
"Descripción:" + e.getMessage(), e);

throw e;

} finally {

log.debug("<- insertarUnidad(UnidadOrganizativa unidad)");

}
}
}


La documentación generada por "javadoc" será la siguiente:

a) Página índice de toda la documentación generada:



b) Documentación de la clase "UnidadOrganizativa.java":