NiHao 0.8 (C) XWolf 2012
NiHao es un framework de aplicaciones autocontenido, por lo que NO esta basado en ningún otro framework ni librería más que lo que corresponde a J2EE.
Esta diseñado para ser amable con la memoria mientras se busca la mayor rapidez de ejecución posible. Equilibrandolo finalmente con la sencillez de configuración y mantenimiento. Haciendolo perfecto tanto para grándes como pequeñas aplicaciones.

El diseño interno de QCore está basado en técnicas vistas en multitud de frameworks actuales, pero tiene su propia implementación, mejornado la integración y eliminando código e instancias innecesiarias.

Una de esas técnicas es la capacidad de configurar el framework usando un archivo de contexto, como hace Srping pero en vez de usar una estructura en XML, usa un lenguaje propio, facilitando enormemente la lectura y modificación de dicho archivo.

O Ibatis, para el acceso a base de datos. Plasmando en este mismo fichero de confugración la configuración de acceso a datos, y las queries que atacan a esta.
Una peculiaridad de QCore es la posibilidad de definir el engine de base de datos usado, y poder realizar multiples queris para los distintos engines.
De esa manera QCore es capaz de decidir la query a usar dependiendo del engine del acceso a datos, y por lo tanto facilitar el cambio de engine de una base de datos a otra sin penalización en el desarroyo.

Instalación:
Ejecutar en una Base de datos el script correspondiente a su engine, este generará la estructura, y datos básicos para el uso de QCore.
QCore busca por defecto el archivo de contexto qcore.ctx dentro de META-INF. Se publican unos archivos .ctx de ejemplo para la configuración inicial.
Añadir QCore.jar como libreria de aplicación, y añadir al META-INF de la aplicación web los archivos de ejeplo situados en doc/META-INF.
Editar el web.xml, añadiendo el correspondiente filtro, es recomendable usar este filtro como primer filtro
<filter>
  <filter-name>SessionFilter</filter-name>
  <filter-class>qcore.WebFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>*.html</url-pattern>
</filter-mapping>
Lenguaje de contexto:
QCore utiliza un formato propio para definir una persistencia de objetos que son instanciados como objetos para definir distintas configuraciones y estructuras complejas. QCore leera por defecto el archivo localizado en NETA-INF/qcore.ctx el cual ha de definirse en el proyecto de aplicación
Definición de Proveedores
 Estructura:
  provider <name> default <defaultname>{
   <implname>
   <implname>
  }
 
El nombre <name> ha de coincidir con el de la clase del proveedor (sin el paquete) El nombre <defaultname> ha de estar en la lista de <implname> Los proveedores adicionales han de estar listados en <implname>
Definición de Objeto
 Estructura:
  object [<name>] class <class>{[(<parameter>[,<parameter>,...])
   [<property>=<value>]
   [<property>=<value>]
   [...]
  }
 
El nombre <name> ha de ser único entre todas las definiciones del contexto, excepto con las definiciones de queries. La clase <class> ha de un nombre completo de una clase instanciable. El parametro <parameter> son los parametros del constructor. Tanto <property> como <value> se usan para asignar propiedades de la clase mediante su seter o directamente en la propiedad privada.
Definición de Array
 Estructura:
  array [<name>] of <class> {
   [<value>]
   [<value>]
   [...]
  }
 
El nombre <name> ha de ser único entre todas las definiciones del contexto, excepto con las definiciones de queries El valor <value> se usa para definir los vlares del array
Definición de Lista
 Estructura:
  list [<name>]{
   [<value>]
   [<value>]
   [...]
  }
 
El nombre <name> ha de ser único entre todas las definiciones del contexto, excepto con las definiciones de queries El valor <value> se usa para definir los vlares del array
Definición de HashMap
 Estructura:
  map [<name>] {
   [{<key>,<value>}]
   [{<key>,<value>}]
   [...]
  }
 
El nombre <name> ha de ser único entre todas las definiciones del contexto, excepto con las definiciones de queries La clave <key> es la clave del HashMap El valor <value> es el valor para la clave <key>
Definición de null
 Estructura:
  null
 
Es la definicion del valor null
Definición de literal String
 Estructura:
  "<value>"
 
El valor <value> es el contenido del String sin cambios.
Definición de literal numerica
 Estructura:
  <value>
 
El valor <value> es un número, usando el punto "." para decimales
Definición de literal booleana
 Estructura:
  true|false
 
Literal sin commillas, true para verdadero y false para falso.
Definición de Queries
 Estructura:
  query <name> [engine <enginename>|any] [type <type>] { <querystr> }
 
El engine ha de coincidir con el especificado en el acceso a datos (case sensitive) any para cualquera, si no se especifica engine, se asume any.
Querystr puede contener información adicional usando la almoadilla como caracter de escape:
  • ## Hace referencia a un tipo escalar unico
  • #[<numero indice>]# Hace referencia a un elemento de un array Ex: #1#,#2#,#10#
  • #<nombre miembro># Hace referencia a una propiedad de un objeto, o a una clave en un hashmap Ex: #userName#,#userPwd#
</div> </div>
Conocimientos básicos:
La base de datos por defecto de QCore contiene 2 grupos: Admin y Guest. Y un usuario: admin (contraseña 1234), perteneciente al grupo Admin.

El grupo guest es obigatorio, ya que es el grupo que se le asigna a los usuarios no logados. es recomendable que no tenga permisos, pero que sea un gupo activo.

El fichero de contexto ha de tener de forma obligatoria un objeto llamado QCoreConf. Ejemplo:

object QCoreConf class nihao.QCoreConf{
 loginConf=object class nihao.login.LoginConf{
  modules=array of nihao.login.ILoginModule{
   //object class nihao.login.LoginModuleSSL{}
   object class nihao.login.LoginModuleRequest{}
  };
  pageLogin="login.jsp";
  pageEnd=  "end.jsp";
  pageError="error.jsp";"
  pageForbidden="forbidden.jsp";
  excluded=array of String{
  };
 }
 worksetCacheSize=10;
}
 
Uso en JSP:
 Se usa a través del taglib de QCore, defeinir en cada página:
  <%@ taglib uri="http://www.xwolf.es/qcore" prefix="Q"%>
  para usar el taglib

Id en tags
 Para que el tag coja datos del Workset se vinculan mediante el mismo nombre de campo del workset que el id del tag.
 En este caso el tag es de ida y vuelta (el valor se envia a la página, pero este también se notifica al servidor).
 Existen casos especiales, para obtener valores, pero estos no serán enviados al servidor de manera natural.
 Estos casos son:
  · Nombres que empiezan por "|": Obtienen el valor de los atributos del PageContext, el nombre en el PageContext incluye
  el simbolo "|"
  · Nombres que empiezan por "@": Obtienen el valor del archivo de contexto de aplicación, sin incluir el simbolo inicial. 
  · Nombres que empiezan por "$": Obtienen el valor de la sesión, sin incluir el simbolo inicial. 
  · Nombres que empiezan por "%": Obtienen el valor de el parametro del request, sin incluir el simbolo inicial.
  · Puntos en el nombre: Si los nombres de campo estan separados por ".", se realiza una navegación. por
  los elementos de los objetos, pudiendo emplear cualquier profundidad. Si algún elemento en la ruta de
  navegación, es null, se retorna null.
 Para enviar al servidor hay que especificar el attributo send="<nombre campo>". Dónde
  <nombre campo> es el nombre del campo del workset.
 

Proveedores de acceso a datos:
 Estructura:
  object MainDatabaseConnection class xwolf.qcore.db.DataSourceProviderJNDI{("java:comp/env/jdbc/<name>")
   engine="<engine>" //opcional
  }
  object MainDatabaseConnection class xwolf.qcore.db.DataSourceProviderJDBC{("jdbc:<engine>://<host>:3306/<ddbb>")
   driver="<driver to initialize>" // opcional
   engine="<engine>" //opcional
   user="<user>"
   password="<password>"
  }