Introducci�n

data/gvsig-orreili2.png

Note

La documentacion correspondiente a la version 2.1.0 de gvSIG esta empezando a ser actualizada. Puede encontrarse aun muchas referencias a la version 2.0.0, en general estas seran adecuadas.

La guía de desarrolladores para gvSIG pretende proporcionar a un desarrollador que va a trabajar con gvSIG toda la información necesaria para poder compilar, modificar y realizar nuevos desarrollos sobre gvSIG.

Los temas principales que se tratan en la guía son:


Maven

Introducci�n

Maven is a tool for the management and construction of software projects, especially for those based on Java. Maven has similar goals to make and ant, but with greater emphasis on the configuration by convention.

Maven is hosted by the Apache Software Foundation, and can be found at: http://maven.apache.org.

The main goals of Maven are:

Setting up a Maven project is done through the pom.xml file, which describes the main properties of the project and its dependencies with other modules and external components, as well as the Maven configuration to be applied. On the Maven website there is a reference guide on the pom.xml file format

Following the philosophy of configuration by convention, Maven defines a standard project structure:

project
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   `-- resources
    |                   
    `-- test
        |-- java
        `-- resources

If we follow this structure (but if it is different, it can be configured) with a basic configuration, we can perform the typical tasks of any Java project, already predefined in Maven:

Each task is determined by a Maven objective, with its name passed as a parameter. Example:

mvn install

There are two main versions of Maven: 1.0 and 2.0. The latter version is used in gvSIG.


Plugins de maven

The functionality provided by Maven consists of a number of plugins that can be registered and configured for each project via the pom.xml.

The most commonly used plugins are registered and configured by default. If we use a different one for our project, or need to adapt the configuration of any existing ones, we can access the Maven plugins page.

For each plugin there is a user guide and documentation on the different parameters that are accepted by the plugin.

The Maven plugin page also provides links to other repositories of available plugins, mainly on codehaus.org and code.google.com.


Repositorios local y remotos

Maven manages two types of dependency repositories:

Local repository

Local disk location where Maven stores downloaded dependencies, so that they do not have to be downloaded every time. The structure corresponds to one folder per groupId (if the groupID contains points, a subfolder will be created for each element), a folder with the name of the artifactId and finally, a folder with the version.

The downloaded dependencies are stored in the folder of the version. For example, see the following dependency in a pom.xml:

<dependency>
    <groupId>org.gvsig</groupId>
        <artifactId>org.gvsig.tools</artifactId>
        <version>2.0-SNAPSHOT</version>
</dependency>

This will be stored in the local Maven repository with the path:

MAVEN_REPO/org/gvsig/org.gvsig.tools/2.0-SNAPSHOT/org.gvsig.tools-2.0-SNAPSHOT.jar

The files stored by Maven in the local repository can be of type:

When specifying a dependency for our project, Maven will by default download only the .jar file with the compiled classes. However, we can specify that the .jar with the source code and / or the javadoc must be downloaded as well.

Remote repositories

Remote repositories are dependency servers where Maven will look when it cannot find a dependency in the local repository.

Common remote repositories that can be accessed via standard protocols are HTTP/S, FTP, SSH, etc.

The Maven project itself has a dependency repository, accessible by HTTP, which is configured by default. In the pom.xml files you can add other external repositories, or repositories of your own project. For example, gvSIG has its own repository, which is registered by default for the gvSIG projects, in addition to the official repositories.

The gvSIG repository is currently accessible through HTTP as read-only, and through SCP in editing mode. This repository contains mainly the files that are generated by the gvSIG projects, as well as any external dependencies that are not available in the official repository.


Objetivos habituales

The Maven Getting Started Guide describes the common tasks, among which:


Lecciones aprendidas

Desactivar la ejecuci�n de los tests unitarios

To launch Maven in a project and generate jars without launching the unit tests, add the following parameter:

-Dmaven.test.skip=true

Desactivar la consulta de nuevos builds SNAPSHOT

When offline, or when you want to disable the updating of SNAPSHOT dependencies, add the -o parameter.


Depurar tests unitarios desde maven

Sometimes we may need to debug the unit tests of a project, launched by Maven.

To do this, there is a parameter that causes Maven to wait for a remote debug connection on port 5005, before launching each test:

mvn -Dmaven.surefire.debug test

More information can be found in the documentation of the Maven debugging tests plugin


Uso de memoria

It is possible that for some of the tasks Maven launches, such as the compilation of Java classes, or the generation of Javadoc, the default memory settings will not be enough.

If this happens, an OutOfMemoryError message will appear in the console. We can increase the maximum memory allocation of the JVM by defining the MAVEN_OPTS variable that allows us to pass parameters to the JVM that launches Maven. For example:

Linux:

export MAVEN_OPTS=-Xmx256M

Windows:

set MAVEN_OPTS=-Xmx256M

When there is not enough space for the loading of classes (PermGenSpace), this will produce an error like:

[INFO] Compilation failure
Failure executing javac, but could not parse the error:

The system is out of resources.
Consult the following stack trace for details.
java.lang.OutOfMemoryError: PermGen space
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:621)

In this case, we will need to increase the PermGen space with the -XX:MaxPermSize parameter. For example:

Linux:

export MAVEN_OPTS=-Xmx256M -XX:MaxPermSize=64m

Windows:

set MAVEN_OPTS=-Xmx256M -XX:MaxPermSize=64m

Usar maven a trav�s de un proxy

If you access the Internet through a proxy, you will need to configure Maven to download dependencies through this proxy, following the Configuring a proxy instructions at the Maven page.

Basically, this consists of including the corresponding configuration in the .m2/settings.xml file:

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

<settings xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/xsd/settings-1.0.0.xsd">

   ...

    <proxies>
        <proxy>
            <active>true</active>
            <protocol>http</protocol>
            <host>proxy.somewhere.com</host>
            <port>8080</port>
            <username>proxyuser</username>
            <password>somepassword</password>
            <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
        </proxy>
    </proxies>
</settings>

Recursos de maven disponibles


Crear un proyecto para gvSIG

Cosas a tener en cuenta antes de desarrollar un plugin.

When developing a project for gvSIG 2.0 we must consider several things if we want it to have the official endorsement of gvSIG and become part of the official gvSIG release.


Estructura de un proyecto en gvSIG

Maven and Eclipse

One of the most interesting features of Maven is its ability to work with multi-module projects and the options for executing pre-defined targets to perform certain clearly defined tasks, such as code compilation and packaging.

Unfortunately, the current version of Eclipse does not include the necessary mechanisms to support multi-module projects, so that integration with the Maven mechanisms are complex and require the use of certain strategies to simulate such behavior.

Maven uses a Project Object Model (POM) to describe the software project to be built, the structure of the project and its sub-modules, their dependencies on other modules and external components, and the build order of the elements. Using these defined characteristics, you can get Eclipse to use the information in the POMs to simulate multi-module behavior.

Working with Maven in Eclipse

When working with Eclipse, as mentioned above, we will have to follow certain guidelines that will allow us to make use of the functionality Maven offers.

The first thing to note is the naming convention of the directories. The names applied to directories are not random, as they indicate the hierarchical structure of the project. Thus, the name of the parent project will be the name of the artifact_id, and its submodules will include the parent name (for example, if the parent project is org.gvsig.example, the submodule Example1 must be kept in the directory org.gvsig.example/org.gvsig.example.example1, and Example2 in org.gvsig.example/org.gvsig.example.example2. If Example1 has a submodule Example1a, it would be stored in org.gvsig.example/org.gvsig.example.example1/org.gvsig.example.example1a and so on). This gives the project a tree structure:

The parent nodes are not recognized as Java projects by Eclipse, because they are simply containers of the submodules. These projects contain the POM file with its definition and description of the submodules. In this way, you can launch commands at the parent module to run on that level and all its child nodes automatically (install, compile, etc.).

On the other hand, the child nodes (or leaves of the tree) are Java projects, with their usual project structure. These nodes can take advantage of the parent configuration (dependencies, properties, attributes, ...) if that parent is specified in the POM, simplifying its configuration.

Developing a gvSIG project

When we develop a gvSIG project there should be a strict separation between the API and the implementation of that API. To accomplish this, a basic template for gvSIG projects has been prepared which takes advantage of the Maven capabilities to manage multi-module projects. This template will guide us on how to organize the project, keeping strictly separated the logic of the extension from the user interface, and the API of the logic from its implementation, and the API of the interface from its implementation, in different Eclipse projects and separate jars.

The basic structure of a project will be:

Compared to gvSIG projects prior to the 2.0 version, this project structure would seem rather complex, but we will look into it with more detail.

The first thing to note is that the project is oriented as a multi-module SVN project compared to what we used to see in the development of gvSIG 1.X. On the one hand we have the development of the library and on the other, the extension(s) for gvSIG. This has been organized like this because normally the changes in the logic of our extension usually have a life cycle that is clearly separated from the integration into gvSIG. After development of the extension has been completed, it is easier to do the modifications from one gvSIG version to the next in the parts of the code that contains the integration with gvSIG, while the logic remains unchanged except for some bug corrections. To achieve this independence, the SVN repository is separated into two main groups:

In the library we will find the following:

And finally we come to the separation of some of these modules into API, SPI and implementation. This separation can be found in org.gvsig.example.lib and org.gvsig.example.swing.

Imagine that we are developing a network analysis extension for gvSIG. What projects would we be working with?

In principle, our project would not require special service providers. It would consist of the logic, the user interface, and the actual plugin for gvSIG. We would have the following projects:

Basically we would have these six projects, and each of them would generate its own jar, corresponding to the name of the project. Each of the projects will be will be located in its corresponding folder, and it is important that they have the correct name. This is because when you import these projects into Eclipse, we find that the folder tree is flattened; but thanks to the naming convention, these projects retain their consistency in our workspace.

Although it seems obvious, it should be pointed out which dependencies between those projects are acceptable. The implementation will depend on the API, but not vice versa. Also, our API should be concise and complete. Complete because the client of this API should not need to know the implementation in order to use it, and concise because the details of the implementation do not need to be exposed; the less details are exposed, the easier and safer the maintenance will be.

On the other hand, there is the user interface. This, whether the implementation or its API, should have no dependencies on the implementation of the library, or the logic. It should only depend on its API.

And finally, the test implementation and the extension can only depend on the API of the library and the user interface API.

It should also be noted that pom.xml files are found in each of the different folder. So there is a pom.xml in org.gvsig.example that allows us to interact with all the submodules of our project, and it contains the general configuration of the project. For example, through the pom.xml we can directly build the Eclipse projects for each of our modules. In turn, org.gvsig.example.swing and org.gvsig.example.lib have their own pom.xml files with their specific configuration. Finally, each of the final projects will have their own pom.xml file. Each of these pom.xml will be configured indicating the pom of the higher level folder as the parent pom to inherit the common configurations.

We have mentioned API several times. But what do we mean by API? How do we define it?

The question is not as obvious as it seems. When you ask several developers how they define an API module we can end up with very different answers. So, in gvSIG, how do we define an API? Normally, the API consists of a set of Java interfaces. There may be an abstract class that provides a default implementation for something that should be extended by the API user, but it never contains a class with its implementation. As usual, there are exceptions to this. By their nature, exceptions that trigger this API will be implemented in the API. This set of interfaces, packaged in a project and its jar, is the only dependency that the API user must depend on.

When using swing there will be differences. Swing lacks interfaces to handle graphic components, and therefore when it comes to defining the API of the swing part of our project, instead of using interfaces, we use abstract classes that extend the different swing components, adding abstract methods from our project domain. Usually there are abstract classes that extend JPanel, and these define the user interfaces associated with components of our project.

What does the implementation consist of?

Well, there we have a set of classes that implement the interfaces defined in the API. Normally there will be a manager which will serve as entry point to the functionality of our project and its configuration.

It is helpful to review the tools that org.gvsig.tools provides to manage the separation between API and implementation using the Library, Locators and Manager, and the tools that are available for the management of service providers, so that new projects will not need to reinvent each time how to implement these tools, and to harmonize their use throughout gvSIG.

We must also consider the recommendations when naming the classes and interfaces. The project structure described here is designed to follow a naming system such as described in the document nomenclature for classes and interfaces. So the API interfaces are named using meaningful names from the extension domain, without using any kind of prefix or suffix, while the classes that are found in the implementation project and which implement the API interfaces, are named by adding Default as a prefix to the name of the interface that they implement.

Before moving on to the creation of a gvSIG project according to the structure described above, it is recommended to review the documentation about org.gvsig.tools.service that describes in more detail the classes and interfaces to create, and how they are stored in a Maven subproject.


Creando nuestro proyecto

To work with our project need a gvSIG 2.0 installed. You must also install the Development project wizard addon, available through the addons manager (Tools > Addons manager).

What is going to offer this extension?

Mainly this extension will give us the option Create plugin. Using this utility, will allow the creation of maven projects, following the project structure described above, according to the custom options you choose to work with this installation of gvSIG.

This utility can be found in the menu Tools the option Development:

images/es/menu_gvsig_wizard-es.png

After accessing Create plugin option, the extension will show a wizard. This wizard will guide you to create a template from our maven project associated with this instance of gvSIG. As the most interesting points, note that the wizard will require that you enter the name of our project, group_id (default org.gvsig) and the location to generate the plugin.

You will have also to select the template to use, being able to select between a basic project with spatial support or a project to show fortune cookies. The first one is the recommended one.

If you select the second template, in addition we need indicate the type of plugin to be developed (for details see section FortuneCookie a _ plugin gvSIG). Finally, we will tell to wizard if we want to generate the extension for gvSIG or not.

images/es/create_maven_project-es.png

As a last step in the generation of our plugin, the tool will perform a prepare_workspace to leave our project ready. Perform maven tasks 'configure-eclipse-workspace','maven install' and 'maven eclipse:eclipse'.

images/es/configure_eclipse_workspace-es.png

Once created the project, closing gvSIG, start Eclipse and import the folder we created the project. To work with it, we import the parent project (org.gvsig.<project_name>) as all sub-modules (org.gvsig.<project_name>.lib.api, org.gvsig.<project_name>.lib.impl, org.gvsig.<project_name>.main and others according to the variant chosen).

images/es/eclipse_import-es.png

Once the project has been imported into Eclipse, we'll just create our plugin and boot normally, using the project build.xml file, and using the mvn-install target.

Finally, once developed our plugin, use the Pack plugin option of gvSIG installation. A utility to generate binaries from our plugin and will allow us to distribute it as a separate plugin or included in an existing gvSIG installable.


FortuneCookie, un plugin para gvSIG.

The FortuneCookie project is a very simple example plugin that aims to serve as a template to be followed by the developer when implementing their own plugins.

But, what advantages gives us the use of the diferents FortuneCookies projects? In principle, the most direct benefit is pretty obvious, since the fact of working on fully implemented a complete project that compiles and runs, can focus more on developing the code than in configuration tasks. And is that all FortuneCookies projects have declared their POM files with all the minimum dependences to run, and to establish relationships between them.

Therefore, to say that we have a project that will provide a number of basic, complete, compilable and run structures from which begin our development.

It presents several implementations that allow the developer show the highlights to be covered by your plugin depending on which option best suits the nature of the project. The variants presented are:

Should you require more information on any of the alternatives mentioned are advised to consult the document org.gvsig.tools.service

Moreover there is the option of GUI providers. This will be the option if, in addition to the above, support is required for the acquisition of user interfaces provided by vendors (currently under construction).


Trabajar con un proyecto

Preparar el espacio de trabajo en eclipse

Attention!

Pendiente


Tareas habituales con maven

Attention!

Pendiente


Versionado y publicaci�n


Instalables en gvSIG

Introduccion

Warning

This document is under construction.

Note

The utilities described in this document are designed and tested on a linux system. It is very likely to work on other systems, but it is easy to require some adjustments.

Installing gvSIG is a hybrid mechanism between a native installer, dependent on the platform we are running, and a java installer. The native installer, will install the gvSIG framework, preparing everything necessary in order to start a minimalist installation. The second, the java installer, is responsible for presenting the user the different packages available for installation, and installed.

The whole system is based on plugins installation packages, bundles and how they are installed.

We find:

A distribution of gvSIG is formed by the native installer, and a package set, gvspks, which added to the minimal installation a set of features we want to be in distribution.

They are available to those who need it, the mechanisms for creating gvSIG distributions with a custom packages sets, so that packages can be included as considered appropriate, thus creating distributions gvSIG specific or customized for different sectors.


Paquetes y conjuntos de paquetes

Note

The utilities described in this document are designed and tested on a linux system. It is very likely to work on other systems, but it is easy to require some adjustments.

gvSIG supports several types of packages. These packages can install different types of accessories.

Currently there is only one type of package available, the container of plugins. From now on, herein, when referring to packet will always be talking about a package that installs a plugin.

gvSIG has a plugin that allows us to generate a package of a plug installed in that instance of gvSIG. This is a simple way that a developer can generate plugins packages from the same gvSIG on which it is developing.

The packet generation tool will include all information in the folder where live the plugin and also allow us to select other files inside the gvSIG installation, and include an ant script to be executed as post-installation script.

In addition to their own files that make up the plugin, we provide some basic metadata to identify the package. These are:

package required to operate.

In the plugin directory, there will be a * file * package.info with all this information, as well as a folder * install * the script ant to the post-installation called * install.xml *, and all this is packaged in a zip file with relative paths to the folder where you live in the plugin.

System Message: WARNING/2 (<string>, line 76); backlink

Inline emphasis start-string without end-string.

Keep in mind that this zip file should never contain folder entries, only files. So if you create a package by hand without using the tool provided by gvSIG we tell the command * zip * the appropriate option to not include them.

To create our own packages of our plugins, simply will be compressed in a zip file the folder where the plugin, making sure they exist, the file * package.info *, the * install folder * and the file * install / install.xml * if we need it.

System Message: WARNING/2 (<string>, line 86); backlink

Inline emphasis start-string without end-string.

Once we created our package we can install it using the installer is completed, or we can serve for inclusion in a gvSIG custom installation.

Here is an example of what would contain an install package. Let specifically see the plugin install support for ECW in gvSIG:

$ unzip -l gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg
Archive:  gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg
  Length     Date   Time    Name
 --------    ----   ----    ----
     4092  07-08-11 09:47   org.gvsig.raster.ermapper.app/lib/org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT.jar
    23391  07-08-11 09:47   org.gvsig.raster.ermapper.app/lib/org.gvsig.raster.ermapper.io-2.0.0-SNAPSHOT.jar
    28206  07-08-11 09:47   org.gvsig.raster.ermapper.app/lib/org.gvsig.jecw-2.0.0-SNAPSHOT.jar
   655809  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/files/native/libNCSUtil.so.0
   430361  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/files/native/libNCSCnet.so.0
    72242  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/files/native/libNCSEcwC.so.0
  6120711  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/files/native/libNCSEcw.so.0
    25851  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/files/native/libjecw2.0.0.so
     1085  07-08-11 09:47   org.gvsig.raster.ermapper.app/install/install.xml
      313  07-08-11 09:47   org.gvsig.raster.ermapper.app/package.info
      363  07-08-11 09:47   org.gvsig.raster.ermapper.app/config.xml
 --------                   -------
  7362929                   12 files
$ 

We observed that we have the file package.info containing the description of the package:

#
#Fri Jul 08 09:47:35 CEST 2011
state=devel
name=Formats: Ecw format support
buildNumber=23
official=true
code=org.gvsig.raster.ermapper.app
operating-system=lin
architecture=x86
java-version=j1_5
gvSIG-version=2.0.0
version=2.0.0-SNAPSHOT
type=plugin
description=Ermapper data provider for gvSIG
model-version=1.0.0

In addition to this there is a folder install with a file Install.xml, which contains the post-installation script of the package and a folder files, a folder with the files that should go elsewhere gvSIG installation of the outside of the folder plugin. The post-install script takes care of copying the files native to where it belongs and in this case set the symlinks to work native libraries correctly installed:

<project name="org.gvsig.plugin1" default="main" basedir=".">
    <target name="main" depends="copy_files, link"/>
    <target name="copy_files">
        <copy todir="${gvsig_dir}">
            <fileset dir="./files" includes="**"/>
        </copy>
    </target>
    <target name="link" depends="checkos" if="linuxos">
        <exec executable="ln" >
            <arg value="-s"/>
            <arg value="${gvsig_dir}/native/libNCSCnet.so.0"/>
            <arg value="${gvsig_dir}/native/libNCSCnet.so"/>
        </exec>
        <exec executable="ln" >
            <arg value="-s"/>
            <arg value="${gvsig_dir}/native/libNCSEcwC.so.0"/>
            <arg value="${gvsig_dir}/native/libNCSEcwC.so"/>
        </exec>
        <exec executable="ln" >
            <arg value="-s"/>
            <arg value="${gvsig_dir}/native/libNCSEcw.so.0"/>
            <arg value="${gvsig_dir}/native/libNCSEcw.so"/>
        </exec>
        <exec executable="ln" >
            <arg value="-s"/>
            <arg value="${gvsig_dir}/native/libNCSUtil.so.0"/>
            <arg value="${gvsig_dir}/native/libNCSUtil.so"/>
        </exec>
    </target>
    <target name="checkos">
      <condition property="linuxos">
           <os family="unix" />
      </condition>
    </target>
</project>

The other files that appear are the plugin files themselves, their jars and resource files that may need such as the config.xml. In this case find:

Each plugin will provide the files needed for their operation.


A�adiendo nuestro paquete al repositorio de gvSIG

Una vez tenemos nuestro paquete, podemos entregarlo a nuestros usuarios o solicitar que sea incluido en el repositorio de paquetes de gvSIG, lo que es altamente recomendable, ya que de esta forma damos acceso a él a cualquier usuario que pueda estar interesado en él.

Para hacerlo tendremos que preparar un fichero índice con la extensión gvspki. Este fichero es en un zip similar al gvspkg pero que solo contendrá el fichero package.info con una ligera modificación. El fichero package.info, además de los datos descritos en el apartado anterior tendrá una entrada download-url, que será la URL desde la que poder descargar el paquete, gvspkg, por lo que antes de crear el fichero gvspki deberemos tener claro dónde vamos a alojar nuestro paquete, y una vez construido el fichero gvspki haremos llegar este a gvSIG para que se incluya en el repositorio.

Estos paquetes que solicitamos que se integren en el repositorio de gvSIG solo tienen que cumplir unas pequeñas reglas, principalmente de nombrado y versionado del paquete, no siendo preciso que sean desarrollos oficiales, siendo así una forma fácil de distribuir nuestros desarrollos entre los usuarios.

Puede encontrar más información sobre cómo puede solicitar incluir su paquete en el repositorio de gvSIG en Añadir un paquete al repositorio de paquetes de gvSIG.

Tal como vimos en el apartado Paquetes y conjuntos de paquetes vamos a ver ahora que es lo que contiene el fichero indice del paquete que añade el soporte para el formato ECW:

$ unzip -l gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspki
Archive:  gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspki
  Length     Date   Time    Name
 --------    ----   ----    ----
      505  07-08-11 09:47   org.gvsig.raster.ermapper.app/package.info
 --------                   -------
      505                   1 file
$

Como podemos obserbar unicamente tiene un archivo, y es el package.info. Este archivo cotendra:

#
#Fri Jul 08 09:47:36 CEST 2011
state=devel
name=Formats: Ecw format support
buildNumber=23
official=true
code=org.gvsig.raster.ermapper.app
download-url=http\://downloads.gvsig.org/download/gvSIG-desktop/pool/org.gvsig.raster.ermapper.app/gvSIG-desktop-2.0.0-org.gvsig.raster.ermapper.app-2.0.0-SNAPSHOT-23-devel-lin-x86-j1_5.gvspkg
operating-system=lin
architecture=x86
java-version=j1_5
gvSIG-version=2.0.0
version=2.0.0-SNAPSHOT
type=plugin
description=Ermapper data provider for gvSIG
model-version=1.0.0

Como vemos contiene la misma informacion que el package.info del fichero gvspkg mas una entrada indicando donde se encuentra este, download-url.


Generando nuestro conjunto de paquetes

Además de generar el paquete para nuestro plugin y solicitar que este sea añadido al repositorio de paquetes de gvSIG, puede resultarnos útil generar un conjunto de paquetes, gvspks con los distintos paquetes que estemos interesados en hacer llegar a nuestros usuarios, de forma que podamos dar un juego de funcionalidades personalizado.

Para eso bastara con crear un fichero zip en el que incluyamos los paquetes, gvspkg, o referencias a paquetes, gvspki que nos interese. Además dentro de este fichero zip podemos incluir información sobre qué paquetes queremos que estén marcados como recomendados o a instalar por defecto, cuando el usuario intente utilizarlo para instalarse nuevas funcionalidades desde él.

Para conseguir esto tendremos que crear un fichero de nombre "defaultPackages" en el que indicaremos, el nombre de los paquetes que queremos que sean marcados como paquetes recomendados o por defecto (uno por línea).

Cada línea tendrá el formato:

code[#versión[#build]]

De forma que presentará como paquete recomendado el que tenga el código de la versión y build que hayan sido indicados.

¿Qué queremos decir con paquete recomendado o marcado por defecto ?

Si durante el proceso de instalación de la aplicación se utiliza un gvspks en el que tenemos una entrada "defaultPackages", los paquetes que ahí se indiquen se marcarán como seleccionados de forma automática para que se instalen. Es una forma de ofrecer al usuario una instalación típica de paquetes en función de los paquetes disponibles.

Si, una vez instalada la aplicación, entramos en el instalador de complementos, este nos presentará en un color distinto los paquetes que se indiquen en el fichero "defaultPackages" del gvspks que se esté usando, de forma que el usuario pueda ser consciente de qué paquetes es recomendado que tenga instalados.

Hay que tener en cuenta que los paquetes que formen nuestro conjunto de paquetes pueden ser tanto paquetes en sí mismos como referencias a paquetes. Esto nos brinda la posibilidad de incluir de base una serie de funcionalidades, y referenciar a otras que se encuentren en la web y que se descargarán bajo demanda si el usuario solicita instalarlas.


Generando nuestra distribuci�n de gvSIG

Una vez hemos sido capaces de crear el paquete para nuestro plugin, así como de crear un conjunto de paquetes que nos permita ofrecer a nuestros usuarios un juego de funcionalidades personalizado, nos sería útil empaquetar todo esto en un solo instalable de gvSIG para facilitar la descarga e instalación de nuestra distribución personalizada.

El mecanismo de instalación de gvSIG permite hacer esto. Para ello disponemos de utilidades para incluir un gvspkgs dentro del instalable nativo de gvSIG, de forma que este lo extraiga y utilice automáticamente durante el proceso de instalación, así como que lo deje preparado para ser usado por el instalador de complementos cuando concluya la instalación.

Además de incluir nuestro conjunto de paquetes, también nos permitirá añadir los instalables del jre a utilizar por la aplicación para que el usuario no precise descargarselo, en caso de que no disponga de la versión adecuada de el.

Tip

En algunas distribuciones del plugin org.gvsig.mkmvnproject no se ha empaquetado la herramienta gvspkg, puede descargarla directamente desde la web de gvSIG en la que se generan las distribuciones oficiales de gvSIG-desktop, dentro de la carpeta gvspkg.bin .

Dentro de la carpeta "scripts" del plugin org.gvsig.mkmvnproject, encontraremos:

Tip

Este script esta probado sobre S:O. Ubuntu, no teniendo claro que funcione sobre otra plataforma.

Antes de utilizar esta utilidad copiaremos la carpeta gvspkg.bin a nuestro home con el nombre ".gvspkg.bin", y nos aseguraremos que el script gvspkg está en el path.

Supongamos que tenemos los archivos:

Ejecutaremos el comando:

gvspkg mkinstall gvSIG-desktop-2.0.0-2030-devel-lin-x86-online.bin packages.gvspks

Esto nos creara el fichero gvSIG-desktop-2.0.0-2030-devel-lin-x86-custom.bin partiendo de nuestro instalador nativo e insertando en el nuestro packages.gvspks.

Si además queremos que se incluya el instalador del jre en el paquete, tendremos que conseguir primero el archivo de instalación correspondiente. Podemos descargarlo desde:

https://downloads.gvsig.org/download/gvsig-desktop/runtimes/java1.6/

Allí encontraremos:

- jre-6u26-linux-i586.bin
- jre-6u26-windows-i586-s.exe

Con los instalables del jre de java para windows y linux.

Así para generar nuestro instalable para linux ejecutariamos:

gvspkg mkinstall --jrelin=./jre-6u26-linux-i586.bin --addjrelin gvSIG-desktop-2.0.0-2030-devel-lin-x86-online.bin packages.gvspks

Y nos crearía gvSIG-desktop-2.0.0-2030-devel-lin-x86-custom-withjre.bin con el instalable del jre incluido y nuestro conjunto de paquetes personalizado.

Si quisiésemos generar los binarios para windows ejecutariamos:

gvspkg mkinstall --jrewin=./jre-6u26-windows-i586-s.exe --addjrewin gvSIG-desktop-2.0.0-2030-devel-win-x86-online.bin packages.gvspks

Generándose el fichero gvSIG-desktop-2.0.0-2030-devel-win-x86-custom-withjre.exe .

Warning

Esta pendiente añadir utilidades para cambiar la imagen del asistente de instalación así como el readme.


El asistente para empaquetar plugins

Para crear un paquete que contenga nuestro plugin la aplicacion gvSIG dispone de un asistente. Este asistente se encuentra en el menu Herramientas opcion Desarrollo, y requiere que el plugin ya se encuentre desplegado sobre su misma instancia de gvSIG. Vamos a ver cuales serian los pasos para generar un paquete de forma simple.

  1. Lo primero deberemos haber desplegado nuestro plugin sobre una instancia de gvSIG. Para la prueba vamos a generar un paquete de instalacion del plugin org.gvsig.centerviewpoint.

  2. Con el plugin desplegado ejecutaremos gvSIG y seleccionaremos la opcion de menu "Herramientas -> Debvelopment -> Crear paquete de instalacion de plugin".

    el-asistente-para-empaquetar-plugins-images/opcion-menu-crear-paquete-instalacion.png
  3. Ahora seleccionaremos el plugin org.gvsig.centerviewpoint de la lista de plugins que nos muestra el asistente.

    el-asistente-para-empaquetar-plugins-images/seleccionar-plugin-a-instalar-centerviewtopoint.png

    Seleccion de plugin

    y pulsaremos en siguiente.

  4. Ahora nos preguntara por los datos del paquete, que son los que describimos en el apartado Paquetes y conjuntos de paquetes.

    el-asistente-para-empaquetar-plugins-images/formulario-informacion-paquete-centerviewtopoint.png

    Datos del paquete

    Una vez rellenados los datos del paquete correctamente, pulsaremos en siguiente.

  5. Se nos preguntara si queremos habilitar el modo avanzado. En general contestaremos que no dejando el check sin marcar.

    Tip

    El modo avanzado no sera necesario siemrpe que todos los archivos que precise nuestro plugin para funcionar se encuentren en la propia carpeta del plugin, y mientras no necesitemos ejecutar codigo especifico mediante el script de post-instalacion.

    el-asistente-para-empaquetar-plugins-images/opciones-avanzadas-sin-marcar.png

    No activamos el modo avanzado.

    Le daremos siguiente para continuar con el asistente.

  6. Ahora se nos preguntara por el archivo de salida. Por defecto nos ofrecera un nombre para el paquete siguiendo las reglas de nombrado usadas en gvSIG y ofreciendonos como carpeta donde dejarlo la carpeta install de la instalacion de gvSIG. Asi mismo nos pregunta si queremos crear tambien el archivo indice gvspki. Si no se lo ponemos nos generara el fichero del paquete con el que podremos probar si se instala correctamente nuestro plugin o pasarselo a nuestros usuarios para que lo instalen.

    el-asistente-para-empaquetar-plugins-images/opciones-de-salida-sin-gvspki.png

    Archivos de salida sin indice

    Si queremos generar el fichero indice, gvspki, deberemos tener clara bajo que URL va a ser accesible el paquete, para introducir esta en nuesto indice. Asi marcariamos la opcion Crear indice, y en URL de descarga introduciriamos la url completa de donde descargar el fichero gvspkg que vamos a generar.

    el-asistente-para-empaquetar-plugins-images/opciones-de-salida-con-gvspki.png

    Archivos de salida con indice

    Una vez completado el formulario, daremos a siguiente para que se inicie la generacion de los ficheros del paquete.

En caso de que necesitemos incorporar en nuestro paquete archivos que estan fuera de la carpeta de nuestro plugin, o precisemos ejecutar codigo en el script de postinstalcion, en el momento que se nos presenta la opcion de si queremos habilitar el modo avanzado lo marcaremos.

Imaginemos que queremos generar un paquete para el plugin de GPE que precisa actualizar la libreria que lleva gvSIG de base kxml de la version 2.2.2 a la version 2.2.3. Para esto hariamos:

  1. Seleccionaremos el plugin de GPE

  2. Rellenaremos los datos relativos a este plugin.

  3. Marcariamos el check de habilitar el modo avanzado

    el-asistente-para-empaquetar-plugins-images/opciones-avanzadas-marcada.png

    Activamos el modo avanzado.

  4. Se nos presentara un arbol con la estructura de archivos de la instalacion de gvSIG para que seleccionemos los que precisemos. Iremos al directorio lib y seleccionaremos kxml2-2.2.2.jar

    Y pulsaremos en siguiente.

  5. Nos aparecera un panel con el script de post-instalacion por defecto, que se encarga de copiar los ficheros seleccionados al sitio adecuado.

Warning

TODO Continuar por aqui.

modificar el script para borrar el jar antiguo.


Librer�as nativas

Attention!

Pendiente


Normas de codificaci�n y desarrollo

Coding conventions

Contents

Forewords

This document describes a list of coding conventions that are required for code submissions to the project. By default, the coding conventions for most Open Source Projects should follow the existing coding conventions in the code that you are working on. For example, if the bracket is on the same line as the if statement, then you should write all your code to have that convention.

If you commit code that does not follow these conventions and you are caught, you are responsible for also fixing your own code.

Below is a list of coding conventions that are specific to gvSIG, everything else not specificially mentioned here should follow the official Sun Java Coding Conventions

Why code conventions

As explained in the Sun Java Coding Conventions:

Code conventions are important to programmers for a number of reasons:

How to apply?

Having coding conventions is nice but having a way to ensure they are applied is even better ... :-)

The gvSIG maven configuration has a checkstyle target which performs coding conventions using the Checkstyle tool.

Please run this target before committing any code.

Also the eclipse configuration needed to format the source code taking into account the code conventions defined in the current document will be available in the org.gvsig.maven.base.build project, from the gvsig-tools OSOR project.

If the project you are working with has a prepare-workspace.xml file which you have used to configure your workspace, you will have those files already downloaded and available into the folder:

WORKSPACE/org.gvsig.maven.base.build/eclipse-configs

Otherwise, you may download all the files through the repository URL:

https://devel.gvsig.org/svn/gvsig-tools/org.gvsig.maven.base/trunk/org.gvsig.maven.base/org.gvsig.maven.base.build/src/main/resources/org.gvsig.maven.base.build/eclipse-configs/

To import those configurations perform the following:

  1. Clean up:
    • Go to Window > Preferences > Java > Code Style > Clean Up and click the button Import.
    • In the file system explorer, select the clean_up.xml file.
images/clean_up_optim.png
  1. Code templates:
    • Go to Window > Preferences > Java > Code Style > Code Templates and click the button Import.
    • In the file system explorer, select the code_templates.xml file.
    • Activate the option Automatically add comments for new methods and types.
images/code_templates_optim.png
  1. Formatter:
    • Go to Window > Preferences > Java > Code Style > Formatter and click the button Import.
    • In the file system explorer, select the formatter.xml file.
images/formatter_optim.png
  1. Organize imports:
    • Go to Window > Preferences > Java > Code Style > Organize Imports and click the button Import.
    • In the file system explorer, select the organize_imports.importorder file.
images/organize_imports_optim.png

gvSIG specific coding conventions

Mandatory conventions

  1. Headers

    Look at the Headers document for more information.

  2. Indentations

    4 spaces. NO tabs.

  3. Javadoc

    All API interfaces and classes must be fully documented through javadocs comments at interface/class, method and package level.

    When you inherit or extend from another interface or class which is already documented, and implement or rewrite one of the parent methods, don't write any javadoc comments, as they are also inherited since java 1.4.

  4. Brackets

    All brackets should begin at the end of the line that begins the statement, and end on a new line indented to the beginning of the statement. Example:

    AVOID:

    public class MyClass 
    {
    
        public void someMethod() 
        {
            if (...) { // Do something }
    }
    }
    

    RIGHT:

    public class MyClass {
    
        public void someMethod() {
            if (...) {
              // Do something
            }
        }
    }
    

    Brackets are mandatory even for single line statements:

    if (expression)       // AVOID!
        // some code
    
    if (expression) {     // RIGHT
        // some code
    }
    
  5. Blank Spaces

    Keywords followed by a parenthesis should be separated by a space. Example:

    while (true) {
        // some code
    }
    

    Blank space should appear after commas in argument lists. Binary operators should be separated from their operands by spaces:

    a += c + d;
    a = (a + b) / (c * d);
    
    while (d++ = s++) {
        n++;
    }
    
    printSize("size is " + foo + "\n");
    
  6. Class variables

    Class variables should not have any prefix or suffix related to its data type or scope. Example:

    String nameString;   // AVOID!
    
    String name;         // RIGHT
    
  7. Parameter names

    Method parameters should be prefixed by "the" for differentiating them from inner variables, when there is an inner variable with the same name or use. For example:

    public void someMethod(String theClassName) {
        String className; // inner variable
    }
    
  8. Line length

    Avoid lines longer than 80 characters for Code, comments, ...

  9. Versioning

    All .java files should have a @version tag like the one below into the class javadoc comment:

    @version $Id$
    
  10. Logging

    Do not use System.out to log. Instead, use the SLF4J logging API. For example:

    private static final Logger LOG = 
        LoggerFactory.getLogger(MyClass.class);
    
    public void someMethod() {
        LOG.debug("some debug text");
    }
    

    For more information on SLF4J usage, you can read the Logging document.

  11. Exception handling

    Managing exceptions correctly requires experience. This is not supposed to be a guide on managing exceptions, simply a few best practices.

    • Rule 1: Try to catch exceptions as much as possible and rethrow higher level exceptions (meaning hiding the low level detailed and putting a message that is more related to the function of your code).
    • Rule 2: It is important not to loose the stack trace which contains important information. Use chained exceptions for that.
    • Rule 3: Always log the exception at the higher level (ie. where it is handled and not rethrown).
    • Rule 4: Try to avoid catching Throwable or Exception and catch specific exceptions instead.
    • Rule 5: Create one parent Exception for each API library, so methods of the API that throw any exception use that parent exception or one of the child ones.
    • Rule 6: If you have an exception or an error which can't be handled or resolved by code, throw or rethrow a BaseRuntimeException subclass.

    An example:

    public void getTestClass() {
        try {
            Class responseClass =
                Class.forName("some.package.MyClass");
        } catch (ClassNotFoundException cnfe) {
            String message = "Cannot instantiate test class";
            LOG.error(message, ex);
            throw new ChainedRuntimeException(message, e);
        }
    }
    
  12. Qualified imports

    All import statements should containing the full class name of classes to import and should not use the "*" notation: An example:

    // AVOID!
    import java.util.*;
    import java.net.*;
    
    // RIGHT
    import java.util.Date;
    import java.net.HttpURLConnection;
    
  13. Use interfaces in the declaration of methods and variables.

    By example, if you need a variable x that is a list, declare it as List instead an ArrayList:

    // AVOID!
    ArrayList x = new ArrayList();
    HashMap y = new HashMap();
    
    public HashMap create(ArrayList keys, ArrarList values) {
        ...
    }
    
    // RIGHT
    List x = new ArrayList();
    Map y = new HashMap();
    
    public Map create(List keys, List values) {
        ...
    }
    
  14. API packages

    Usually, API interfaces and classes will belong to the library's main root package. If you create subpackages, use them to group by functionality, not by type.

  15. How to name packages

    All packages must begin with org.gvsig.

    For more information on this convention, you can read the How to name packages document.

Advised conventions

  1. How to name interfaces and classes

Attention!

TODO

For more information on this convention, you can read the How to name interfaces and classes document.


Nomenclatura para clases e interfaces

Introduction

This document defines rules for naming classes and interfaces that allow a common style for gvSIG components to be maintained.

The importance of consistency in naming is obvious if one considers a complete Javadoc implementation. From the point of view of the reader, using a variety of naming conventions would create confusion and complicate the understanding of the component.

Criteria to follow

Use of prefixes and suffixes in general

The use of prefixes and/or suffixes in the names of classes and interfaces is usually a means of providing information about their nature and/or task. For example they can be used to denote a pattern, or a role within a pattern (eg the suffix Factory). At other times, it is necessary to use them if the appropriate name has already been assigned. This is the case of the prefixes and suffixes that are described below.

As a general rule:

  • Only use a prefix or suffix when you can't use the simple name (usually because it is being used by another class or interface).

Using the prefix "Abstract"

  • Only to be used for classes, not interfaces.
  • The class must be abstract and implement an interface.
  • Only used when the interface being implemented has the same name.

Example:

public interface List {}
public abstract class AbstractList extends AbstractCollection implements List {}

Using the prefix "I"

  • It is recommended that this prefix not be used.

    Typically, the interfaces are the visible part of a component model. They usually represent entities and concepts from the business or domain and therefore it is recommended that the same names be used as in the business.

Using the prefix "Default"

  • Can't be an abstract class.
  • A default implementation of an interface or an abstract class.
  • The implementation should be sufficient, but not necessarily complete.
  • There may be alternative implementations of this class.

Example:

public interface ListModel {}
public abstract class AbstractListModel implements ListModel, Serializable {}
public class DefaultListModel extends AbstractListModel {}

Using the prefix "Base"

  • Not an abstract class.
  • Provides a "base" implementation of an interface or an abstract class.
  • The class can be instantiated and not used any more, but is designed for the user of the extended component.
  • Do not use this prefix if no interface or parent abstract class exists.

Example:

public abstract class StreamRequestHandler {}
public class BaseHTTPRequestHandler extends StreamRequestHandler {}

Using the suffix "Impl"

  • It is a class instance and therefore can't be abstract
  • It is a complete implementation of an interface or abstract class, generally referred to as the class without the "impl".
  • Other classes should not be extended from it.
  • Do not use this suffix unless the class name conflicts with the name of the interface or abstract class being implemented.
  • If this is the default implementation of part of the API and does not conflict with other parts of the project, the prefix Default is preferred.

Example:

public interface Plane {}
public abstract class AbstractPlane implements Plane {}
 
// Both are correct (but not equal)
public class PlaneImpl implements Plane {} 
public class PlaneImpl extends AbstractPlane {}

Application Conditions

This criterion is applicable to new developments undertaken for gvSIG 2.0 and will be part of the official gvSIG distribution as well as for all developments financed in whole or in part by the CIT.


Nombres de paquetes a usar en gvSIG

Preliminary considerations

Due to the variability and lack of unity in the names of packages used in gvSIG 1.X, it has been decided to standardize these, thereby giving the project an identity that over-rides that of the company doing the development.

Criteria to follow

When creating java packages that will be part of an official gvSIG release, or that will carry the official endorsement of the gvSIG project, the following package is appended:

org.gvsig

No mention is made in the package of the company doing the development.

Normally, the package name org.gvsig is followed by a package name identifying the logical or functional block that it contains.

Application Conditions

These criteria will be applied to new developments to be made to gvSIG 2.0, and will be part of the official gvSIG distribution as well as for all developments financed in whole or in part by the CIT.


Logging

In gvSIG the SLF4J library is used as a logging API.

The Simple Logging Facade SLF4J is a framework that is designed to abstract the underlying logging system. As Log4j is the most popular logging system in use, the framework's API is very similar to simply removing the direct dependence of this system. This framework is therefore an abstraction layer of the logging system and will allow us to change the underlying components without having to undertake major recoding of the application.

Features of SLF4J

// Those lines produce the same results. The second one has parameters that reduce the overhead when debugging is disabled
LOG.debug("The new entry is "+entry+"."); 
LOG.debug("The new entry is {}.", entry);

Using SLF4J in gvSIG

gvSIG 2.0 is ready to work with SLF4J, using LOG4J as implementation, and can be used directly from any gvSIG extension.

To use SLF4J from a Java class just include the following statements:

1.- Import the necessary classes:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

2.- Declare and initialize the Logger:

public class MyClass
{
    private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
    ...

3.- We use the Logger within the code of the class when we want to display a log message, depending on the type: error, warning, information, debug or trace:

LOG.warn(String message);
LOG.warn(String message,Object arg1);
LOG.warn(String message,Object[] arg1);
LOG.warn(String message, Throwable arg1);
LOG.info(String message);
LOG.info(String message,Object arg1);
LOG.info(String message,Object[] arg1);
LOG.info(String message, Throwable arg1);
LOG.error(String message);
LOG.error(String message,Object arg1);
LOG.error(String message,Object[] arg1);
LOG.error(String message, Throwable arg1);
LOG.debug(String message);
LOG.debug(String message,Object arg1);
LOG.debug(String message,Object[] arg1);
LOG.debug(String message, Throwable arg1);
LOG.trace(String message);
LOG.trace(String message,Object arg1);
LOG.trace(String message,Object[] arg1);
LOG.trace(String message, Throwable arg1);

The following methods are provided to check the activation of messages for each level:

LOG.isErrorEnabled();
LOG.isWarnEnabled();
LOG.isInfoEnabled();
LOG.isDebugEnabled();
LOG.isTraceEnabled();

In addition, the messages can also be customized in SLF4J by inserting variables into the String of the log message, as in the following example:

private Integer temperature;

public void setTemperature(Integer temperature) {

    LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);

    this.temperature = temperature;

    if(temperature.intValue() > 50) {
      LOG.info("Temperature has risen above 50 degrees.");
    }
}

This stops us from having to concatenate Strings, which reduces the cost of using the instructions for logging. This is because, although the log level that we are using is disabled (for example, debug), the method call will be made anyway, including the concatenation of strings to build the message, if any.

However, if the obtaining of any of the parameters to be passed to the message log proves costly, it is convenient to use the consultation methods to avoid such implementation. For example:

private Integer temperature;

public void setTemperature(Integer temperature) {

    LOG.debug("Setting temperature to {}. Old temperature was {}.", temperature, this.temperature);

    this.temperature = temperature;
    addToTemperatureLog(temperature);

    if (LOG.isDebugEnabled()) {
        LOG.debug("The current average temperature is {} Celsius", calculateAverageTemperature());
    }
}

Cabeceras

All project java source files will contain the following header:

/**
 * gvSIG. Desktop Geographic Information System.
 *
 * Copyright © 2007-2012 gvSIG Association
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *  
 * For any additional information, do not hesitate to contact us 
 * at info AT gvsig.com, or visit our website www.gvsig.com.
 */

In other languages source code (C, C++, etc.), as well other configuration or definition files (XML, properties, txt, etc.) the previous header must be included also, using the related comment format.

This header has been defined into the eclipse Code Templates configuration, so it gets included by default when a new java file is created.

To update existing files without header or with an old one, the maven-license-plugin maven plugin has been configured. That configuration is available into the pom.xml file of the org.gvsig.maven.base.pom project.

To update or include the previous header automatically, just call:

mvn license:format

Take into account the previous order will modify the headers of all the maven plugin supported files. If anyone is not correcto or it is not mapped, it might be easily added to the configuration.

Yo may also validate if a project files headers are correct by calling:

mvn license:check

Migración de proyectos de gvSIG 2.0.0 a gvSIG 2.1.0

Version: 1.0

Contents

Introduction

In parallel to the release of version 2.0 of gvSIG we have been doing some refactoring work on the projects that are part of the core of gvSIG 2. They have been designed to provide to the maven structure to all projects that form the main gvSIG workspace, and also to provide a maven multimodule that encompasses all these ones, wherein the projects and folders structure were coindicent. It has also been removed the need to generate multiple maven project artifacts, it's also been removed dependencies between API and implementation of some projects, included the ones that had dependencies with other projects.

The changes that have taken place affect mainly poms and, to a lesser degree, the source code.

We have tried to keep compatibility at the APIs level, not changing any in order to avoid incompatibility with the version 2.0. This way the gvSIG plugins compiled for version 2.0 still work with the new version of gvSIG.

The most relevant changes to be found are:

We will describe the changes and how they affect the developer who needs to migrate from version 2.0 to version 2.1.

Changes on poms: artifactsId y classifiers

Changes on maven artifactId are mainly because the restriction that a project should not produce more of an artifact. When this happened in the past, a parent project was created with a subproject by artifact generated. For example, before we had a project called "libFMap_dal/org.gvsig.fmap.dal" that generated the jars:

Now this project has been splited into the following projects:

The code source that were formerly in a single project had been splited into three projects, each generating its corresponding jar.

Besides these changes in the artifactId, which are mainly in the libraries of the project, we have also changed some artifactId of the projects' type plugin. The name and structure of the gvSIG plugins that were in the SVN gvsig-desktop had been normalized.

We can see the artifactId that have changed in the following table:

Changes on the artifactId
artifactId (2.0) classifier (2.0) artifactId (2.1)
org.gvsig.projection   org.gvsig.projection.api
org.gvsig.projection cresques-impl org.gvsig.projection.cresques.impl
org.gvsig.projection cresques-ui org.gvsig.projection.cresques.ui
org.gvsig.fmap.mapcontext   org.gvsig.fmap.mapcontext.api
org.gvsig.fmap.mapcontext impl org.gvsig.fmap.mapcontext.impl
org.gvsig.fmap.mapcontext operation org.gvsig.fmap.mapcontext.operation
org.gvsig.fmap.dal   org.gvsig.fmap.dal.api
org.gvsig.fmap.dal spi org.gvsig.fmap.dal.spi
org.gvsig.fmap.dal impl org.gvsig.fmap.dal.impl
org.gvsig.fmap.dal.db   org.gvsig.fmap.dal.db.lib
org.gvsig.fmap.dal.db jdbc org.gvsig.fmap.dal.db.jdbc
org.gvsig.fmap.dal.index.spatial gt2 org.gvsig.fmap.dal.index.spatial.gt2
org.gvsig.fmap.dal.index.spatial jts org.gvsig.fmap.dal.index.spatial.jts
org.gvsig.fmap.dal.index.spatial jsi org.gvsig.fmap.dal.index.spatial.jsi
org.gvsig.fmap.dal.file   org.gvsig.fmap.dal.file.lib
org.gvsig.fmap.dal.file store.dbf org.gvsig.fmap.dal.file.dbf
org.gvsig.fmap.dal.file store.shp org.gvsig.fmap.dal.file.shp
org.gvsig.fmap.geometry   org.gvsig.fmap.geometry.api
org.gvsig.fmap.geometry impl org.gvsig.fmap.geometry.impl
org.gvsig.fmap.geometry operation org.gvsig.fmap.geometry.operation
org.gvsig:org.gvsig.compat   org.gvsig.compat.api
org.gvsig:org.gvsig.compat se org.gvsig.compat.se
org.gvsig.app   org.gvsig.app.mainplugin
org.gvsig.coreplugin   org.gvsig.coreplugin.app.mainplugin
org.gvsig.geodb   org.gvsig.geodb.app.mainplugin
org.gvsig.editing   org.gvsig.editing.app.mainplugin
org.gvsig.exportto.app.extension   org.gvsig.exportto.app.mainplugin
org.gvsig.help   org.gvsig.help.app.mainplugin
org.gvsig.i18n.extension   org.gvsig.i18n.app.mainplugin
org.gvsig.annotation.app.extension   org.gvsig.annotation.app.mainplugin
org.gvsig.newlayer.app.extension   org.gvsig.newlayer.app.mainplugin

Changes on poms: the project's hierarchy

The hierarchy of projects in version 2.0 was little intuitive. We had a number of projects such as:

Among them it was difficult to navigate or control the hierarchy that existed between them and from which we had to extend to create the new project, contributing that hierarchy's folder do not correspond with the one of the project.

What has been done was to redistribute the functionality that was in those projects in six new projects, aligning its structure with the one of the folders. The projects are:

└── org.gvsig.desktop
    ├── org.gvsig.desktop.compat.cdc
    │
    ├── org.gvsig.desktop.framework
    │
    ├── org.gvsig.desktop.installer
    │
    ├── org.gvsig.desktop.library
    │
    └── org.gvsig.desktop.plugin

These projects represent the different types of project that we will find in gvSIG. In each of them we can find:

A small comment for those who will compile fully gvSIG desktop. In the version 2.0 to compile gvSIG we downloaded the build folder and from there we began to work. With version 2.1 this changes. Now the build folder does not exist any more. To compile gvSIG desktop we will download the org.gvsig.desktop, and simply execute one "mvn install" from there. If we are working with Eclipse, we will need to have installed the eclipse plugin m2e plugin.

Well, with "mvn install" the entire gvSIG will be compiled.... And where are the binaries of gvSIG?

Well, it depends. If this is the first time you compile gvSIG, these remain in the target/product folder. When you compile gvSIG it is checked whether it exists in the "home" of the user the file called ".gvsig-devel.properties" in which it is indicated where to deploy gvSIG. If it does not exist it will be created indicating it will be deployed on the folder called "org.gvsig.desktop/target/product" from which we launched the compilation.

Changes on poms: profiles and properties

In the gvSIG poms there were defined a number of properties with several uses. In the current configuration, the only relevant properties are:

Properties used in the poms
Name Description Value Defined in
gvsig.product.folder.path Folder were gvSIG and its plugins compiled will be deployed. ${basedir}/target/product org.gvsig.desktop
gvsig.desktop.children.version Version of the project org.gvsig.desktop and of all their children that are on the gvsig-desktop SVN. 2.0.10-SNAPSHOT org.gvsig.desktop
gvsig.package.info.state   Devel org.gvsig.desktop.plugin
gvsig.package.info.official   false org.gvsig.desktop.plugin
gvsig.package.info.operatingSystem   All org.gvsig.desktop.plugin
gvsig.package.info.architecture   All org.gvsig.desktop.plugin
gvsig.package.info.javaVM   j1_5 org.gvsig.desktop.plugin
gvsig.package.info.gvSIGVersion   2.0.0 org.gvsig.desktop.plugin
gvsig.package.info.poolURL   http://downloads.gvsig.org/download/gvsig-desktop/pool org.gvsig.desktop.plugin
gvsig.package.info.dependencies   required: org.gvsig.app.mainplugin -ge 2.1.0 org.gvsig.desktop.plugin
gvsig.package.info.owner   gvSIG Association org.gvsig.desktop.plugin
gvsig.package.info.sourcesURL   ${project.scm.url} org.gvsig.desktop.plugin
gvsig.package.info.webURL   http://www.gvsig.com org.gvsig.desktop.plugin
gvsig.package.info.categories     org.gvsig.desktop.plugin

Basically, on the table above, we'll see that it is only used the gvsig.product.folder.path variable, which indicates where our gvSIG plugins and the variables gvsig.package.info are deployed, which are used to configure the package associated with the plugin. Need to comment, that although in the project org.gvsig.desktop.plugin those variables are initialized by default, in each plugin they must be overwritten with the appropriate values ​​to that plugin, and noted that these properties already existed in the 2.0 version, but have been renamed. Previously they were called something like "package.info ..." and now they have the prefix "gvsig ...." but still have the same meaning they had in version 2.0.

In relation to the use of "profiles" in the maven projects, the general rule is that these have disappeared. The main use of these within gvSIG was in order to:

The use of profiles for these tasks has been removed from the gvSIG projects, so it should not be necessary to use them. However, before deleting the profiles from your project, check that properties are not declared on them that will be used from somewhere else, such as the properties "package.info" used to the configuration of the "package.info".

Se ha introducido el uso de perfiles para identificar de forma correcta a los proyectos que despliegan plugins de gvSIG. De forma que los plugins de maven especificos de procesar plugins de gvSIG solo se activan cuando se encuntra en fichero "buildNumber.properties" en la carpeta del proyecto.

Changes on poms: package e install of a gvSIG's plugin

With the new configuration on the basis projects, when we have a gvSIG project of the type plugin, it should be extended from org.gvsig.desktop.plugin. With that we'll inherit all the settings required to package and install the plugin.

A "mvn package" will let the resulting package in the target folder of our project.

In order to deploy the plugin against the gvSIG installation we'll need to do something else. We'll have to go to our user folder in linux $HOME and see that we have a ".gvsig-devel.properties" file which has a declared variable "gvsig.product.folder.path". Its value should be at the gvSIG installation where the plugin must be deployed. If this occurs, an "mvm install" will deploy the plugin in that folder.

The distribution.xml file and plugin's resources

When compiling a library project, all the resources will often go to the jar associated to this library. However when compiling a gvSIG plugin project the resources can get into the jar or into the folder in which the plugin is installed. In the 2.1 version of gvSIG, resources are separated. Resources that are going to be left in the jar will be on the folder src/main/resources, in order to be included on the natural cycle of Maven including them on the jar. And the resources that go to the plugin folder will be left in the folder src/main/plugin-resources, keeping on that folder the structure that will have on the plugin folder once installed, thus making easier the package and deployment of the plugin.

Along with the change of location of some resources, the file "distribution.xml" has also been changed, which has been moved to src/main/assembly/gvsig-plugin-package.xml eliminating the distribution file. It has changed the way in which it is packaged, before it was used as "format", "dir" and now it is used "zip". The package is no longer made directly on the folder where the plugin is deployed, but on a zip file in the target folder of the plugin, maintaining the structure that has the package of the plugin. It will be in the install phase when the plugin will be deployed on gvSIG installation.

Previously the file package.info was generated in the root of your project, but now this will be generated in the target folder.

If we want to continue packing as in version 2.0, we should overwrite the configuration of the plugin maven-assembly-plugin to continue invoking the distribution.xml file.

Changes on the plugin's names

The next table shows the changes applied to plugin's name.

Changes to plugin's names.
gvSIG 2.0 gvSIG 2.1
org.gvsig.app org.gvsig.app.mainplugin
org.gvsig.coreplugin org.gvsig.coreplugin.app.mainplugin
org.gvsig.geodb org.gvsig.geodb.app.mainplugin
org.gvsig.editing org.gvsig.editing.app.mainplugin
org.gvsig.exportto.app.extension org.gvsig.exportto.app.mainplugin
org.gvsig.help org.gvsig.help.app.mainplugin
org.gvsig.i18n.extension org.gvsig.i18n.app.mainplugin
org.gvsig.annotation.app.extension org.gvsig.annotation.app.mainplugin
org.gvsig.newlayer.app.extension org.gvsig.newlayer.app.mainplugin

To keep the impact of this change as low as possible, in addition to the changes responsible for the management and implementation of the plugins, it has been created a new property in the "config.xml" file of the plugins that allow us to declare alternative names for the plugin. Thus, the plugins that have been renamed declared as an alternate name or alias the old name. This allows that plugins that had declared dependencies to plugins that have been renamed, can continue working out correctly. Likewise, the management functions of PluginsManager and PluginService plugings are able to deal adequately with the plugin name on version 2.0. Also when those functions are asked for a plugin using the name relatred to the 2.0 version, they correctly return the folder associated with that plugin, or its instance even if the plugin was renamed.

The way in which a plugin specifies an alternative name or alias shpould be using the "alternativeNames" tag in "config.xml" file:

<plugin-config>
  ...
  <alternativeNames name="org.gvsig.app"/>
  <icon src="gvsig-logo-icon" text="gvSIG"/>
  <libraries library-dir="lib"/>
  ...
</plugin-config>

Despite the changes in the source to reduce the impact, this change will affect plugins that interact directly with other plugins' folder, without going through the API in order to get the associated file to the plugin's folder.

Projects that are not any more on the main gvSIG workspace

In addition to changes in the structure of the main SVN gvSIG projects, there are some projects coming out in order to have its own project on the gvSIG infrastructure with its own SVN. Some of them were already separated projects in the gvSIG SVN, and others were part of one or more projects. In general these projects are composed by data providers for some formats along with its supporting libraries and plugin that installs them. Projects that are new to the gvSIG development infrastructure are:

Changes applied to source code

In addition to the changes inherent to error corrections, changes were made because of the refactoring itself. On the following lines you'll find a short review of these modifications:

Changes on the gvSIG license

We have been reviewing the licenses of individual libraries used by gvSIG, and we detected some incompatibilities with some of them regarding the gvSIG license (til now the GPL 2). Many of these incompatibilities are solved in the next version of the GPL, so it was decided to upgrade the gvSIG license version to the GPL 3. For developers, this change may involve not only the upgrade of version, but the modification of all the gvSIG sources to upgrade headers to GPLv3.

Setting all together

Well ... and all that I have told ...

How does it affect developers who want to migrate their gvSIG plugin to version 2.1?

If you have it compiled for the 2.0 version and want to distribute it, it should be able to do it without extra effort.

If you want to compile for the 2.1 version to take advantage of some of the features that are added, you would have to:

Replacing the line:

<include>...</include>

For the "distribution.xml" corresponding lines in which we should identify the dependencies that must be carry on by the gvSIG plugin into its "lib" file. This list will not include the jar from our plugin as this is copied in another section of the assembly. In case you do not have to move dependencies we can eliminate the entire section "dependencySet" from the assembly and once updated the file "gvsig-plugin-package.xml" remove the folder "distribution".

And after that, with a little of luck, we run a "mvn clean" of the project to verify that you can resolve all dependencies, and "mvn install" to compile and deploy it.

Registro de cambios
versión Descripción
2.0 En introduccion, el punto que dice "Los proyectos de tipo plugin de gvSIG" se ha eliminado.
2.0 En introduccion, el punto que que habla de la eliminacion de perfiles ha sifo modificado.
2.0 En Cambios en los poms: perfiles y propiedades, donde hacia referencia a la propiedad "gvsig.package.info.baseDownloadURL" ahora hace referencia a "gvsig.package.info.poolURL" cambiando tambien su valor.
2.0 En Cambios en los poms: perfiles y propiedades, Se ha añadido al final un parrafo comentando la introduccion de perfiles para la comilacion de los plugins de gvSIG.
2.0 La seccion Cambios en los poms: package e install de un plugin de gvSIG, Ha sido simplificada.
2.0 En Poniendolo todo junto, el punto "En los poms de los proyectos que sean plugins de gvSIG añadiremos" se elimina.

Cached time 11/21/13 16:34:14 Clear cache and reload