OCP7 10 – E/S de archivos Java – Parte 3 – FileStore y WatchService

Clase FileStore

La  clase FileStore es útil para proporcionar información de uso sobre el sistema de archivos como el total de disco utilizable y asignado.
Filesystem kbytes used available
System (C:) 209748988 72247420 137501568
Data (D:) 81847292 429488 81417804
 
En este enlace oficial de Oracle puede estudiarse la implementación de FileStore.

Interfaz WatchService

La implementación de la interfaz de WatchService representa un servicio de vigilancia que observa los cambios producidos en los objetos Path registrados.
Por ejemplo, una instancia de WatchService puede usarse para identificar cuándo fueron añadidos, borrados o modificados archivos en un directorio.
ENTRY_CREATE: D:testNew Text Document.txt
ENTRY_CREATE: D:testFoo.txt
ENTRY_MODIFY: D:testFoo.txt
ENTRY_MODIFY: D:testFoo.txt
ENTRY_DELETE: D:testFoo.txt


NOTA:
La implementación del mecanismo de observación del sistema de ficheros es dependiente de la plataforma de ejecución.

Por defecto, se intentan mapear los eventos que se observan a través del WatchService con los eventos nativos que el Sistema Operativo genera ante los cambios de ficheros. Esto hace que sea posible encontrarse diferentes tipos de eventos resultados de una misma acción.

En caso que no sea posible consumir los eventos nativos, la implementación en caso de error se encargará de polling consultar el estado de los elementos del sistema de ficheros indicado.

La contra partida de este mecanismo de fallback es que ante eventos muy seguidos, es posible que no se reciban todos los eventos generados si el tiempo entre muestra y muestra es superior al tiempo transcurrido entre los eventos.

En todo caso, la utilización de este servicio ha de tener en cuenta esta particularidad para no obtener resultados inesperados.

En este enlace oficial de Oracle puede estudiarse con más detalle el funcionamiento de la interfaz WatchService.

 

OCP7 10 – E/S de archivos Java – Parte 2 – Interfaz FileVisitor

Operaciones recursivas

La classe Files ofrece un método para recorrer el árbol de archivos en busca de operaciones recursivas, como de copia y de supresión.

Interfaz FileVisitor<T>

La interfaz FileVisitor<T> permite realizar el recorrido de un nodo raíz de forma recursiva. Puede encontrarse la implementación en la API del JDK 7 en el siguiente enlace.

Para poder llevar a cabo el recorrido recursivo mencionado con anterioridad se detallan los siguientes métodos, representando puntos clave del recorrido recursivo. Son métodos a los que se vaya llamando cada vez que se visita uno de los nodos del árbol:
  1. FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs).  Se invoca en un directorio antes de que se visiten las entradas del directorio.
  2. FileVisitResult visitFile(T file, BasicFileAttributes attrs). Se invoca cuándo se visita un archivo.
  3. FileVisitResult postVisitDirectory(T dir, IOException exc). Se invoca después que se hayan visitado todas las entradas un directorio y sus descendientes.
  4. FileVisitResult visitFileFailed(T dir, IOException exc). Se invoca cuándo un archivo no ha podido ser visitado.
El objeto FileVisitResult es el tipo de retorno para la interfaz FileVisitor. Contiene  cuatro constantes  que permiten procesar el archivo visitado e indicar que debe ocurrir en el próximo archivo (Enum FileVisitResult – para un mayor detalle se puede consultar directamente la API de JDK 7 en este enlace). Estas constantes representan  las acciones que tomar tras alcanzar un nodo (antes o después):
  • CONTINUE: Se debe continuar la visita del siguiente nodo en el árbol de directorios.
  • SKIP_SIBLINGS: Señala que se debe continuar el recorrido sin visitar a los hermanos del archivo o directorio.
  • SKIP_SUBTREE: Señala que se debe continuar el recorrido de los nodos sin visitar las entradas de este directorio.
  • TERMINATE: Indica la finalización del proceso de visita.
A continuación se muestra un código Java que ilustra la utilización de los cuatro métodos definidos con anterioridad:

package recursiveoperations;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import static java.nio.file.FileVisitResult.CONTINUE;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;

public class PrintTree implements FileVisitor<Path> {

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attr) {
        System.out.print("preVisitDirectory: ");
        System.out.println("Directory : " + dir);
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
        System.out.print("visitFile: ");
        System.out.print("File : " + file);
        System.out.println("(" + attr.size() + " bytes)");
        return CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        System.out.print("postVisitDirectory: ");
        System.out.println("Directory : " + dir);
        return CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        System.out.print("vistiFileFailed: ");
        System.err.println(exc);
        return CONTINUE;
    }
}

A continuación se muestra un código de ejemplo utilizando la clase PrintTree:

Path path = Paths.get("D:/Test");
try{
    Files.walkFileTree(path, new PrintTree())
} catch (IOException e) {
    System.out.println("Exception: "+e);
}

En este ejemplo la clase PrintTree implanta cada uno de los métodos en FileVisitor e imprime el tipo, nombre y el tamaño del directorio y el archivo de cada nodo.

Búsqueda de Archivos

Clase PathMatcher
En java.nio.file se incluye la interfaz PathMatcher la cuál define el método matches(Parth path).  Éste método  permite determinar si un objeto Path coincide con una cadena de búsqueda especificada.Cada implantación de sistema de archivos proporciona un objeto PathMatcher recuperable mediante FileSystems:

PathMatcher matcher = FileSystems.getDefault().getPathMatcher(String syntaxPattern);
La cadena syntaxPattern presenta la siguiente forma sintaxis:patrón dónde sintaxis puede ser «glob» o  «regex».Y cúando la sintaxis es «regex«, el componente patrón es una expresión regular definida por la clase Pattern.
Se incluye el siguiente código Java. Esta clase se utiliza para recorrer el árbol en busca de coincidencias entre el archivo y el archivo alcanzado por el método VisitFile.

package findingfiles;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import static java.nio.file.FileVisitResult.CONTINUE;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.attribute.BasicFileAttributes;

public class Finder implements FileVisitor<Path> {
    
    private Path root;
    private PathMatcher matcher;
    
    Finder(Path root, PathMatcher matcher) {
        this.root = root;
        this.matcher = matcher;
        
    }
    
    private void find(Path file) {
        Path name = file.getFileName();
        if (name != null && matcher.matches(name)) {            
            System.out.println(file);
        }
    }
    
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        find(file);
        return CONTINUE;
    }
    
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        return CONTINUE;
    }
    
    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
        return CONTINUE;
    }
    
    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
       return CONTINUE;
    }
}
Una vez definido el tipo, se instancia en una clase MyClass y se ejecuta.

package findingfiles;

import java.io.IOException;
import java.nio.file.*;

public class MyClass {

    public static void main(String[] args) {

        Path root = Paths.get("C:\JavaTest");

        PathMatcher matcher = FileSystems.getDefault().getPathMatcher
                                                              ("glob:*.{java,class}");
        
        Finder finder = new Finder(root, matcher);
        try {
            Files.walkFileTree(root, finder);
        } catch (IOException e) {
            System.out.println("Exception: " + e);
        }
       
    }
}
El primer argumento se prueba para ver si es un directorio. El segundo argumento se usa para crear una instancia PatchMatcher con una expresión regular mediante la fábrica FileSystems.Finder es un clase que implanta la interfaz FileVisitor, de modo que se puede transferir a un método walkFileTree. Esta clase se usa para llamar al método de coincidencia en todos los archivos visitados en el árbol.

 

OCP7 10 – E/S de archivos Java – Parte 1 – NIO.2 (New Input Output 2)

NIO

Es el acrónimo de New Input Output.

NIO.2  del Jdk 1.7 implementa un nuevo paquete java.nio.file con dos subpaquetes:

java.nio.file.attribute:  Que permite un acceso masivo a los atributos  de los archivos.
java.nio.file.spi: Dónde SPI significa Service Provider Interface. Es una interfície que permite establecer la conexión de la implementación de varios sistemas de archivos, permitiendo al desarrollador crear  su propia versión del proveedor de sistema de archivos si así lo requiere.

 

La clase FileSystem

Proporciona un método de intercomunicación con un sistema de archivos y un mecanismo para la creación de objetos usados para la manipulación de archivos y directorios.

Interface Path – java.nio.file.Path

Un objeto Path representa la ubicación relativa o absoluta de un archivo o directorio. A su vez, permite definir métodos para la localización de archivos o directorios dentro de un sistema de archivos.
En Windows nodo raíz   c:
En Unix nodo raíz empieza con /
Puede encontrarse informació más detallada en la API oficial

Métodos principales de la interfaz Path (se pueden encontrar más métodos en la URL oficial):
  • getFileName(): Devuelve el nombre del archivo o del elemento más alejado del nodo raíz en la jerarquía de directorios.
  • getParent(): Devuelve la ruta del directorio padre.
  • getNameCount(): Devuelve el número de elementos que componen la ruta sin contar al elemento raíz.
  • getRoot(): Devuelve el elemento raíz.
  • normalize(): Elimina cualquier elemento redundante en la ruta.
  • toUri(): Convierte una ruta en una cadena que puede ser introducida en la barra dirección web de un navegador.
  • subpath(1, 3): Devuelve un objeto Path que representa una subsecuencia de la ruta origen. (Los números hacen referencia a los identificadores situados entre las / separadoras empezando por el 0).
  • relativize(new Path()): Crea una ruta relativa entre la ruta y una ruta indicada. Caso de ejemplo: en un entorno UNIX, si la ruta  es "/a/b" y la ruta indicada es "/a/b/c/d" entonces la ruta relativa resultante será "c/d".

La clase Filesjava.nio.file.Files

Esta clase contiene métodos estáticos los cuáles podemos utilizar para realizar operaciones en archivos o en directorios. 

Puede encontrarse información más detallada en la API oficial.

La clase Files es sumamente importante para poder realizar operaciones con objetos Path tales como:
  • Verificar un archivo o directorio.
    • exists():
    • notExists():
  • isReadable(Path path)Comprobar si el archivo o directorio dispone de permisos de lectura.
  • isWritable(Path path)Comprobar  si el archivo o directorio dispone de permisos de escritura.
  • isExecutable(Path path): Comprobar si el archivo o directorio dispone de permisos de ejecución.
  • setAttribute(Path path, String attribute, Object value, LinkOption… options). Permite aplicar distintos atributos a ficheros en el sistema DOS.                                                       Ejemplo:  Files.setAttribute(new Path(), «dos:readonly», true).
El siguiente código ejemplifica su utilización.
package filesclass;

import java.io.IOException;
import java.nio.file.*;
import java.util.Set;

public class FilesClass {
  
    public static void main(String[] args) {

        Path p1 = Paths.get("C:\JavaCourse\src\Example.java");

        System.out.println("exists: " + Files.exists(p1));
        System.out.println("isReadable: " + Files.isReadable(p1));
        System.out.println("isWritable: " + Files.isWritable(p1));
        System.out.println("isExecutable: " + Files.isExecutable(p1));

        //Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
        //FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);

        try {
            //Path f1 = Paths.get("C:\JavaCourse\src\Hello.txt");
            //Files.createFile(f1, attr);             
            Files.setAttribute(p1, "dos:readonly", true);
            System.out.println("Example.java isWritable: " + Files.isWritable(p1));
            System.out.println(Files.createTempFile("test", ".temp"));

        } catch (IOException e) {
            System.err.println(e);
        }
    }
}
Adicionalmente se puede comprobar y modificar el nivel de accesibilidad de un archivo o directorio mediante los siguientes métodos
    • createTempFile
      • createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>… attrs)
        Crea un nuevo fichero vacío en el directorio especificado, utilizando los textos de prefixo y sufijo facilitados en la llamada de la función para generar su nombre.
      • static Path     createTempFile(String prefix, String suffix, FileAttribute<?>… attrs) Crea un nombre vacío en el directorio temporal por defecto, utilizando el prefijo y sufijo facilitados para generar su nombre.
    • copy: Permite copiar un archivo de una ruta a otra.
      • copy(InputStream in, Path target, CopyOption… options)
        Copia todos los bytes de un flujo de datos de entrada (Stream) a un fichero.
      • copy(Path source, OutputStream out)
        Copia todos los byters de un fichero a un flujo de datos de salida(Stream).
      • copy(Path source, Path target, CopyOption… options)
        Copia un fichero a otro fichero.
    • delete(Path path): Permite borrar archivos físicos o lógicos.
    • move(): Permite mover un archivo de una ruta a otra.
    • newDirectoryStream(new Path()): Permite obtener una interfaz DirectoryStream que al heredar de Iterable permite iterar sobre todos los archivos o subdirectorios situados en el nodo raíz. Debe utilizarse try-with-resources o lo finalizaremos explícitamente.  Puede lanzar la excepción  DirectoryIteratorException o IOException.
El siguiente código muestra un caso de ejemplo de borrado, copia y pegado de ficheros en Java7.
package filesclass;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;


public class FilesClass2 {

    public static void main(String[] args) {

        Path f1 = Paths.get("C:\JavaCourse\src\Hello.txt");
        Path f2 = Paths.get("C:\student\Hello2.txt");
        
        
        try {
                        
            Files.copy(f1,f2,REPLACE_EXISTING);
            Files.delete(f1);
            Files.move(f2,f1,REPLACE_EXISTING);
            
            System.out.println("Hello.txt exists: " + Files.exists(f1));
            System.out.println("Hello2.txt exists: " + Files.exists(f2));

        } catch (NoSuchFileException n) {
            System.err.println(n);
            
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

Relación y conversión entre  Path y File

Entre la Interface Path y la classe File existen mecanismos para obtener una representación de un tipo a el otro. En el JDK7 no es necesario realizar operaciones de conversión complejas solamente es necesario recurrir al método .toFile de cada uno de ellos:

  • path.toFile():  Retorna un objeto File representando su ruta.
  • file.toPath(): Retorna un objeto de tipo Path construido desde una ruta abstracta. El objeto Path resultante se encuentra asociado con el sistema de archivos por defecto.

Código fuente de ejemplo.

1
2
File file = path.toFile();
Path file = file.toPath();

 

Método Unescape en Javascript

En el proyecto actual en el que estoy trabajando, se ha creado una URL mediante la API de Java y se ha transmitido mediante una petición al navegador web.

Se ha producido un error en la transformación y su interpretación del navegador web de dicha URL dado que la cadena de texto obtenida por el navegador ha sido ésta:

http://www.direccion.es/dominio?param1=valor1&param2=valor2

Para solucionar el problema basta con utilizar el método unescape de Javascript.

Mediante este método se trata la cadena de texto recibida por parámetro de forma literal con lo que se eliminan las codificaciones especiales de la cadena de texto.

Dentro del proyecto, se ha utilizado este método para interpretar los caracteres que conforman la URL literalmente y así poder utilizarla en el método window.open de Javascript correctamente.

El código Javascript queda del  siguiente modo:

window.open(unescape(url), "popup2", "left=5,top=5,scrollbars=yes,resizable=yes,status=yes,width=" + (screen.availWidth - 20).toString() + ",height=" + (screen.availHeight - 100).toString());

Al hacer clic en el botón, se abre correctamente el pop up y se carga el contenido indicado por el enlace correctamente dado que el navegador puede interpretar la dirección web (URL) de forma literal y explícita.

A modo de resumen,  comentar que si desea que una cadena URL recibida por petición se trate correctamente debe emplearse el método unescape para ser tratada la cadena de forma literal.

Enlace:  http://www.w3schools.com/jsref/jsref_unescape.asp

Generar esquema XSD a través de las clases de dominio con JAXB

Una operación muy habitual cuando se trabaja con JAXB para generar XML a partir de clases de dominio mediante anotaciones de JAXB es la de generar el esquema XSD asociado a la estructura de datos de dicho XML. Este esquema puede ser utilizado posteriormente para volver a generar las clases de dominio a través de JAXB. Se trata de una operativa muy común cuando se trabaja con servicios web REST para exponer la estructura de los mensajes de respuesta desde el servidor a los clientes para que estos puedan interpretarla, por ejemplo. 

Una manera muy sencilla de generar esta definición XSD cuando ya se tienen modeladas las clases de dominio a partir de las que se creará el XML mediante JAXB es utilizando el método generateSchema del contexto JAXB al que se han especificado las clases de dominio que forman el mensaje XML.

Seguir leyendo Generar esquema XSD a través de las clases de dominio con JAXB

Creación de un Fat Jar con Apache Maven

Hace un tiempo publiqué un post en este mismo blog en el que se explicaba cómo se construir un Fat Jar con Apache Ant para empaquetar toda una aplicación, dependencias incluidas, dentro de un mismo fichero jar. El procedimiento para ello se basa en extraer los ficheros .class compilados que se encuentran dentro de los jars de las dependencias incluirlo dentro del jar principal de la aplicación. En caso de utilizar Maven cómo herramienta de construcción en lugar de Ant, esta acción se puede realizar utilizando el plugin Shade. Para ello será necesario incluir su definición dentro del fichero pom.xml del proyecto y asociar la ejecución de su único goal "shade" a la ejecución de la fase de empaquetado "package":

Seguir leyendo Creación de un Fat Jar con Apache Maven

«Perlas del código fuente» ^_^

Perlas auténticas encontradas en el código fuente del proyecto actual. Son auténticas maravillas de programación. 

A día de hoy aún me pregunto cómo puede funcionar la aplicación de forma productiva 
: 3

* Caso de misma excepción para distintas casuísticas
Es curioso el detalle que lance la misma excepción en los distintos casos ^^  (en  PL/SQL).

                  IF p_codret != '0' THEN
                        IF p_codret = '5' THEN
                             RAISE ErrorObtDiasDatos;
                        ELSIF p_codret = '6' THEN
                             RAISE ErrorObtDiasDatos;
                        ELSIF
                             RAISE ErrorObtDiasDatos;
                        END IF;
                  END IF;

 

* Caso del bifurcador misterioso
Supuestamente pretende realizar una comprobación en el código fuente pero en realidad sólo está interesado en asignar un valor 0 de tipo cadena  a la variable nia 🙂 

if("".equals(nia) || nia==null);
{
         nia = "0";
}

 



* Caso dónde se realiza la aserción de un dato en una variable de objeto

 

El programador quería confirmar que se le asignaba el valor correcto a la variable del objeto.
Primero se recupera el objeto de un formulario y se asigna mediante el Setter pertinente al campo del objeto. Posteriormente, como aserción vuelve a recuperar el valor del propio objeto y lo vuelve a asignar al mismo objeto mediante el mismo Setter.
Es posible que el programador haya encontrado otro mecanismo para la sostenibilidad del estado de un objeto en memoria…?
                comunicadoNuevo.setCe_cm(fr22.get("CE_CM").toString());
                comunicadoNuevo.setCe_cm(comunicadoNuevo.getCe_cm());
 

* Caso dónde se realiza la aserción de un dato en una variable de objeto

 

 

Comprovación exhaustiva sobre el retorno que se ha producido en una variable de error.
                if (codError == 0){
                    error = 0;
                }

                if (error == 0) {
                // ... Code continues here

 


 


 

Función CONVERT en BBDD Oracle 10g

La función CONVERT permite convertir un carácter de un conjunto específico de caracteres a otro carácter de otro conjunto específico de caracteres.

En el caso concreto de la aplicación en la que se está trabajando se desea realizar una consulta sobre una tabla concreta para recuperar una descripción que contenga la palabra avión, como caso de ejemplo. Las descripciones a recuperar son las siguientes

  • Auxiliares de vuelo y camareros de avión, barco y tren                         
  • Mecánicos y ajustadores de motores de avión

mediante la siguiente consulta

SELECT 
                des.des_dcol
FROM 
               TABLA_DESCRIPCIONES des
WHERE 
               UPPER(des.des_dcol) LIKE UPPER(‘%avión%’));

No encuentra ningún resultado dado que realiza la consulta estrictamente con acento y aunque existe en la tabla no lo retorna correctamente.

Aquí es dónde entra la utilización de la función CONVERT. La siguiente consulta busca las descripciones que contengan el valor %avión% mostrando el resultado correctamente.

SELECT 
                des.des_dcol
FROM 
               TABLA_DESCRIPCIONES des
WHERE 
               UPPER(CONVERT(des.des_dcol, ‘US7ASCII‘)) 
               LIKE UPPER(CONVERT(‘%avión%’, ‘US7ASCII‘));

Las descripciones recuperadas son las esperadas como se ha comentado con anterioridad.

  • Auxiliares de vuelo y camareros de avión, barco y tren                         
  • Mecánicos y ajustadores de motores de avión

La clave se encuentra en el parámetro que se le pasa, US7ASCII, correspondiente una de las codificaciones de caracteres comunes (ASCII US 7-bit) de las que puede gestionar la función..

Hasta aquí la prueba de concepto de esta función de Oracle. Para un mayor detalle de la misma se puede acceder a la siguiente ruta.

 

Adaptación de librería java-json.jar a JAVA 1.4

Una de las limitaciones más comunes a la hora de programar es la versión del jdk que requiere nuestra aplicación. Cuando los requerimientos exigen una versión un tanto antigua (1.4 por ejemplo), encontramos problemas a la hora de usar tecnologías como AJAX, sobretodo si necesitamos utilizar respuestas de tipo JSON. Para ello existe una librería muy simple «java-json.jar» pero nos encontramos de que es incompatible con el jdk 1.4.

Aquí explicaré en pocos pasos como adaptar y recompilar esta librería para hacerla compatible y funcional para una aplicación que use un jdk 1.4. Necesitaremos descargar el código fuente de la librería y modificar unos pequeños detalles de las clases que contiene.

Se puede descargar el código fuente de aquí

PROCEDIMIENTO:

Primero importaremos el código a nuestro IDE (en este caso uso Eclipse Juno) . Crearemos un proyecto Java.

 

Y definimos la versión del jdk que usaremos como jdk_4_2_19

 

Una vez tenemos nuestro proyecto creado, importaremos las clases de la librería que vamos a refactorizar. Para eso vamos a Archivo -> importar -> File System

Y seleccionamos la carpeta donde tenemos las clases descargadas.

Una vez tenemos las clases importadas, abrimos una de estas clases y miramos el «package» donde debería estar incluida la clase.

 

Creamos en nuestro proyecto este package y movemos todas las clases a este package

Ahora comprobaremos que las clases muestran errores, esto es lo que debemos corregir.

1 – Cambiamos la utilización de la clase «StringBuilder» por «StringBuffer»

 

2 – Eliminamos las parametrizaciones de las clases «Iterator», «ArrayList», «Set», «Collection», «Enumeration», «Map» i «HashMap»

 

3 – Al eliminar la parametrización, deberemos añadir unos «casts» ya que al no estar parametrizados, ahora todos seran «Object».

 

4 – Eliminamos las anotaciones.

 

5 – Las operaciones de suma entre objetos se deben modificar para que sean entre tipos primitivos, ya que la suma entre objetos no está soportada.

Imagen 1

 

Imagen 2

6 – Modificamos las asignaciones directas de tipos primitivos a clases por una instanciación de la propia clase.

Una vez nuestro proyecto esta corregido sin errores, encapsulamos de nuevo todas las clases en un nuevo archivo .jar compilado con el jdk 1.4. Para esto, clickamos sobre el package «org.json» con el botón derecho del ratón i selecionamos «export -> Java-> Jar file».

 

Finalmente, clickamos a «Finish» y tenemos nuestra librería compilada y totalmente funcional para Java 1.4.

 

 

Quick Reference: Oracle DML and DDL Statements

Just a quick reference of DML and DDL Oracle Statements and some links to visit.

DML Statements

Main Site: Oracle DML Statements

Insert
INSERT INTO table_name (list_of_columns)
VALUES (list_of_values);

Update
UPDATE table_name
SET column_name = value [, column_name = value]…
[ WHERE condition ];

Delete
DELETE FROM table_name
[ WHERE condition ];

DDL Statements

Main Site:  DDL Oracle Statements

Create
CREATE TABLE table_name
(
column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],

column_n datatype [ NULL | NOT NULL ] );

Alter
ALTER TABLE table_name
ADD column_name column-definition;

Drop
DROP [schema_name].TABLE table_name
[ CASCADE CONSTRAINTS ] [ PURGE ];

Extra

Some sites which contains interesting information about the last topics: 1, 2, 3.