¿Cómo
evitar que se pueda modificar cierto campo en una vista?
Al actualizar en una vista, por defecto todos los campos (excepto la
clave) son modificables.
Pero podemos declarar cualquier propiedad de la vista de solo lectura, de
esta forma:
<vista nombre="UnMiembroSoloLectura">
<vista-propiedad propiedad="nombre" solo-lectura="true"/>
</vista>
O, si estamos usando OX3:
@ReadOnly(forViews="UnMiembroSoloLectura")
private String nombre;
¿Cómo
usar una vista diferente para crear y para actualizar?
Obviamente, tenemos que definir un vista para crear y otra para
actualizar, así:
<componente ... >
...
<vista nombre="Crear">
...
</vista>
<vista nombre="Actualizar">
...
</vista>
</componente>
O, si usamos OX3:
@Views({
@View(name="Crear", members=" .... "),
@View(name="Actualizar", members=" ... ")
})
public class MiEntidad { ...
Ahora hemos de refinar la acción
new para escoger la vista
Crear
y la accion de búsqueda para escoger la vista
Actualizar.
Primero, definamos nuestro propio controlador, en
controladores.xml,
así:
<controlador nombre="MiTipico">
<accion nombre="new"
clase="com.miempresa.miaplicacion.acciones.MiAccionNuevo"
imagen="images/new.gif" on-init="true"
atajo-de-teclado="F2">
<usa-objeto nombre="xava_view"/> <!-- No obligatorio desde v4m2 -->
</accion>
<accion nombre="search"
por-defecto="si-posible" oculta="true"
clase="com.miempresa.miaplicacion.acciones.MiAccionBuscar"
atajo-de-teclado="F8">
<usa-objeto nombre="xava_view"/> <!-- No obligatorio desde v4m2 -->
</accion>
</controlador>
Y ahora asignamos este controlador a nuestro módulo, y definimos la acción
de búsqueda para el módulo. Escribimos nuestro módulo de esta manera en
aplicacion.xml:
<modulo nombre="MiModulo">
<var-entorno nombre="XAVA_SEARCH_ACTION" valor="MiTipico.search"/>
<modelo nombre="MiComponente"/>
<controlador nombre="MiTipico"/>
</modulo>
Y ahora solo queda refinar la lógica de nuestras acciones. Para
MiAccionBuscar
podemos escribir:
public class MiAccionBuscar extends SearchByViewKeyAction {
public void execute() throws Exception {
Map clave = getView().getKeyValuesWithValue(); //1
getView().setViewName("Actualizar"); //2
getView().setValues(clave); //3
super.execute();
}
}
Los valores de la clave se han de capturar (1) para que puedan ser
restaurados (3) después de la inicialización que hace el método
setViewName(...).
Y para
MiAccionNuevo:
public class MiAccionNuevo extends NewAction {
public void execute() throws Exception {
getView().setViewName("Crear");
super.execute();
}
}
¿Cómo
desactivar una propiedad para actualizar pero no para crear?
A partir de v6.2 puedes desactivar una propiedad sólo para crear con
@ReadOnly(onCreate=false) como se explica en StackOverflow. por lo
que las instrucciones de abajo son para las versiones anteriores a la
6.2.
Hemos de refinar la acción
new
y la accion de búsqueda. Primero, definamos nuestro propio controlador, en
controladores.xml, así:
<controlador nombre="MiTipico">
<accion nombre="new"
clase="com.miempresa.miaplicacion.acciones.MiAccionNuevo"
imagen="images/new.gif" on-init="true"
atajo-de-teclado="F2">
<usa-objeto nombre="xava_view"/> <!-- No obligatorio desde v4m2 -->
</accion>
<accion nombre="search"
por-defecto="si-posible" oculta="true"
clase="com.miempresa.miaplicacion.acciones.MiAccionBuscar"
atajo-de-teclado="F8">
<usa-objeto nombre="xava_view"/> <!-- No obligatorio desde v4m2 -->
</accion>
</controlador>
Y ahora asignamos este controlador a nuestro módulo, y definimos la acción
de búsqueda para el módulo. Escribimos nuestro módulo de esta manera en
aplicacion.xml:
<modulo nombre="MiModulo">
<var-entorno nombre="XAVA_SEARCH_ACTION" valor="MiTipico.search"/>
<modelo nombre="MiComponente"/>
<controlador nombre="MiTipico"/>
</modulo>
Y ahora solo queda refinar la lógica de nuestras acciones. Para
MiAccionBuscar podemos escribir:
public class MiAccionBuscar extends SearchByViewKeyAction {
public void execute() throws Exception {
super.execute();
getView().setEditable("mipropiedad", false);
}
}
Y para
MiAccionNuevo:
public class MiAccionNuevo extends NewAction {
public void execute() throws Exception {
super.execute();
getView().setEditable("mipropiedad", true);
}
}
¿Cómo
acceder a una propiedad del modelo que no se muestra en la vista?
Desde la vista solo podemos obtener la información visualizada. Pero es
posible, usando la clase
MapFacade acceder directamente al modelo.
Podemos escribir en nuestra vista un código parecido a este:
public class MiAccion extends ViewBaseAction {
public void execute() throws Exception {
Factura factura = (Factura) MapFacade.findEntity(getModelName(), getView().getKeyValues());
// Descuento especial no se muestra en la vista
BigDecimal descuentoEspecial = factura.getDescuentoEspecial();
...
}
...
De esta manera podemos acceder a la propiedad
descuentoEspecial
aunque no este visualizada en la vista actual.
¿Cómo
mostrar la fecha en un dato tabular cuando usas PostgreSQL?
*Resuelto en OpenXava 3.0.2, este metodo es util solo si usas una
version inferior.
Cuando usas OpenXava en combinación con PostgreSQL suele suceder que al
actualizar esquema y tienes una entidad del tipo DATE se crea un campo del
tipo TIMESTAMP en lugar de DATE, esto provoca un error en los datos
tabulares(listas) y el resultado es que la fecha no se lista y al exportar
a PDF aparece el texto "ERROR" en lugar de la fecha, la solución es pasar
el tipo de dato de Timestamp a DATE, puedes hacerlo usando
pgadmin.
Seleccionas el campo, luego con el botón secundario haces clic y
seleccionas la opción propiedades, aparecerá la siguiente ventana.
...
|
Campo con data type Timestamp |
Luego donde dice Data Type haces clic en el listbox y seleccionas DATE
finalmente presionas OK y ya podrás visualizar en los datos tabulares de
tu aplicación la fecha, en este caso el campo "fecha ingreso"
fue corregido y se ve bien, pero el campo "fecha" esta sin corregir y
todavía no aparece la fecha.
Este procedimiento se debe hacer luego de actualizar esquema.
¿Cómo
almacenar preferencias de usuario (nuevo en v3.0.2)?
Almacenar las preferencias del usuario es un asunto que cada uno tiene que
resolver, pero por comodidad OpenXava nos permite usar su propio sistema
para almacenar las preferencias.
OpenXava usa
Java Preferences API para almacenar y leer las
preferencias de usuario, pero adaptada a un entorno de servidor
multiusuario. Podemos acceder al objeto
Preferences usando la clase
Users de OpenXava. Simplemente así:
// Obtenemos las preferencias para el usuario actual
// y nodo (una categoria arbitraria de nuestra elección)
Preferences preferencias = Users.getCurrentPreferences().node("minodo");
// Leemos el valor de una propiedad
boolean filasOcultas = preferencias.getBoolean(FILAS_OCULTAS, false);
...
// Modificamos y grabamos la propiedad
preferencias.putBoolean(FILAS_OCULTAS, filasOcultas);
preferencias.flush();
Hemos de llamar explícitamente a
flush() para guardar los
cambios.
¿Cómo
trabajar con OX desde la línea de comandos?
Los proyectos nuevos creados mediante la plantilla OX, obtienen un fichero
build.xml que podríamos calificar como un tanto filo-eclipse ;-)
Esto se concreta en que el fichero build carece del target de compilación,
que es necesario cuando se trabaja desde la línea de comandos y no lo es
desde Eclipse, pues este entorno compila automáticamente antes de ejecutar
tareas ant (ver
http://sourceforge.net/forum/message.php?msg_id=4962325).
Para solucionarlo, edita primero el build.xml de tu proyecto creado a
partir de la plantilla y haz depender todas las tareas ant de una tarea de
compilación. Así:
<?xml version="1.0"?>
<project name="miProyecto" basedir=".">
...
<target name="desplegarWar" depends="compilar">
...
</target>
<target name="generarPortlets" depends="compilar">
...
</target>
<target name="actualizarEsquema" depends="compilar">
...
</target>
<!-- Compila llamando al target compile
del build de OpenXava -->
<target name="compilar">
<ant antfile="../OpenXava/build.xml" target="compile"/>
</target>
...
</project>
Hay que modificar también, del modo oportuno, el target compile de
$DIR_INSTALACION_OX/workspace/OpenXava/build.xml para crear unos
directorios destino que precisa el script e incluir en los directorios de
fuentes src, xava, persistence, i18n y properties de cada proyecto (ésto
último está ya corregido en la OX 3.0.2). El target modificado tiene este
aspecto OX 3.0.1:
<?xml version="1.0"?>
<project name="OpenXava" default="deployWar">
...
<target name="compile">
<!-- We create the 'lib' folder for it does not fails at the first time -->
<mkdir dir="web/WEB-INF/lib"/>
<!-- hay que disponer aquí la creación de dos directorios más para que no falle -->
<mkdir dir="web/WEB-INF/classes"/>
<mkdir dir="../${project}/gen-src-xava"/>
<javac destdir="../${project}/web/WEB-INF/classes">
<src path="../${project}/src"/>
<!-- Only needed if you uses XDoclet generated code
<src path="../${project}/gen-src"/>
-->
<src path="../${project}/gen-src-xava"/>
<classpath>
<pathelement path="../OpenXava/bin"/>
<fileset dir="../OpenXava/web/WEB-INF/lib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="web/WEB-INF/lib">
<include name="**/*.jar"/>
</fileset>
<pathelement path="../OpenXava/lib/j2ee.jar;${xava.compiler.path}"/>
</classpath>
</javac>
<copy todir="../${project}/web/WEB-INF/classes">
<fileset dir="../${project}/gen-src-xava" excludes="**/*.java"/>
<!-- Esto es lo que he añadido. Desde aquí -->
<fileset dir="../${project}/xava"/>
<fileset dir="../${project}/persistence"/>
<fileset dir="../${project}/i18n"/>
<fileset dir="../${project}/properties"/>
<!-- Hasta aquí -->
</copy>
</target>
...
</project>
Después de estos cambios, deberíamos poder ejecutar sin problemas los
targets como el de actualizarEsquema, que antes de los cambios producían
error.
¿Cómo
enviar correos electrónicos en OX?
Enviar correos electronicos con OX puede ser trivial, solo que se deben
tomar en cuenta los detalles para lograr que todo salga bien.
En este ejemplo veremos como configurar los datos del servidor SMPT y como
enviar un mail en un
@PostUpdate, es decir luego de actualizar
un registro.
Primero debemos editar el archivo
xava.properties ubicado en la
carpeta
/workspace/MiProyecto/properties/
Ahora que tenemos ambos archivos abiertos debemos agregar las siguientes
lineas:
smtpHost=smtp.miserver.com
smtpPort=25
smtpUserId=pepitoesminombre
smtpUserPassword=estaesmiclavesecreta
guardamos ambos archivos, ahora en cualquiera de nuestras clases agregamos
lo siguiente(puede ser alfinal de los getters and setters):
@PostUpdate void enviar() throws ParseException, MessagingException{
Emails.send("mailorigen@origen.com", "mail@destino.com", "asunto de prueba", "contenido de prueba");
}
Con esto ya seremos capaces de enviar mail desde OX sin tener que
implementar alguna clase por nuestra cuenta, recomiendo mirar el codigo
fuente de el proyecto
QaManager esta hecho en OX y tiene algunas
caracteristicas que seran utiles para aprender a usar OX.
¿Cómo
crear tu propio archivo .properties para configurar tu aplicacion?
En ocasiones es necesario dar la posibilidad que ciertos comportamientos u
opciones de tu aplicacion se puedan configurar desde un archivo
.properties en lugar de volver a realizar un deploy con los cambios, en mi
caso fue necesario para indicar si algunos modulos debian mostrar un
formulario en blanco o seguir trabajando con el mismo registro despues de
guardar los datos, asi tambien necesitaba configurar los correos
electronicos de quien enviaria y recibiria mails desde una accion, el
ejemplo estara basado sobre esto ultimo.
En el primer ejemplo veremos en pocos pasos como manejar desde nuestra
aplicacion OX nuestro propio archivo .properties.
- En la carpeta properties de nuestro proyecto crearemos el archivo proyecto.properties(si
lo deseas puedes cambiar el nombre), y dentro de este archivo
escribiremos lo siguiente:
#Esto es un comentario
#Mail de quien envia, cambiarlo por el que corresponda
MailEnvia=sender@sender.com
#Mail recipiente, cambiarlo por el que corresponda, para varios mails separarlos por coma(,)
MailRecipiente=recipiente1@recipiente.com,recipiente2@recipiente.com
- Guardamos el documento y ahora creamos una nueva clase en
org.ejemplo.com.utils(pueden ponerlo en el package que quieran)
llamada ConcesionesPreferencias (deberan cambiar el nombre
por el de su propia aplicación).
package org.ejemplo.com.utils;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import org.apache.commons.logging.*;
import org.openxava.util.*;
/**
* @author Andres Molina
*/
public class ConcesionesPreferencias {
private final static String FILE_PROPERTIES="proyecto.properties";
private final static String JAVA_LOGGING_LEVEL_DEFAULT_VALUE="INFO";
private static Log log = LogFactory.getLog(**ConcesionesPreferencias**.class);
private static ConcesionesPreferencias instance;
private Properties properties;
private boolean ejb2PersistenceLoaded=false;
private boolean ejb2Persistence=false;
private boolean jpaPersistenceLoaded=false;
private boolean jpaPersistence=false;
private boolean hibernatePersistenceLoaded=false;
private boolean hibernatePersistence=false;
private boolean duplicateComponentWarningsLoaded=false;
private boolean duplicateComponentWarnings=false;
private int maxSizeForTextEditor;
private Level javaLoggingLevel;
private Level hibernateJavaLoggingLevel;
private ConcesionesPreferencias() {
}
public static ConcesionesPreferencias getInstance() {
if (instance == null) {
instance = new **ConcesionesPreferencias**();
}
return instance;
}
private Properties getProperties() {
if (properties == null) {
PropertiesReader reader = new PropertiesReader(**ConcesionesPreferencias**.class, FILE_PROPERTIES);
try {
properties = reader.get();
}
catch (IOException ex) {
log.error(XavaResources.getString("properties_file_error", FILE_PROPERTIES),ex);
properties = new Properties();
}
}
return properties;
}
public String getMailEnvia() {
return getProperties().getProperty("MailEnvia");
}
public String getMailRecipiente() {
return getProperties().getProperty("MailRecipiente");
}
}
- Guardamos el archivo y ahora podemos acceder a los valores de
nuestro archivo properties de la siguiente forma:
ConcesionesPreferencias.getInstance().getMailEnvia();
por ejemplo desde una accioon que envia mail luego de guardar lo tengo asi
if (isResetAfter()) {
MapFacade.create(getModelName(), getValuesToSave());
addMessage("entity_created", getModelName());
Emails.send(ConcesionesPreferencias.getInstance().getMailEnvia(),
ConcesionesPreferencias.getInstance().getMailRecipiente,
"Nueva Concesion en espera de una asignacion",
"Se ha creado una nueva Concesion, usted puede asignar un responsable.");
}
¿Cómo
añadir tu propio servlet, filter, listener o resource-ref a tu
aplicación OpenXava?
A partir de OpenXava 7.0 los archivos
servlets.xml,
filters.xml
y
listeners.xml de los que hablamos abajo ya no se soportan.
Puedes definir tus servlets, filters o listeners directamente en
web.xml,
que desde v7.0 está vacío y listo para tus propias cosas, en
src/main/webapp/WEB-INF.
También puede usar las anotaciones estándar
@WebServlet,
@WebFilter
y
@WebListener.
A partir de OpenXava 6.0 puedes
usar las anotaciones estándar de Servlet @WebServlet, @WebFilter y
@WebLister para definir tus propios servlets, filters o listeners.
Si usas una versión de OpenXava
anterior a 7.0, para añadir tus propios resource-ref a tu
aplicación OX no modifiques el archivo web.xml, en vez de eso
puedes crear un resources.xml con elementos resource-ref
(desde v5.4) en la carpeta WEB-INF.
Si usas una versión de OpenXava
anterior a v6.0 tendrás que usar
servlets.xml,
filters.xml
y
listeners.xml. En este caso, para añadir tus propios servlets a
tu aplicación OX
no modifiques el archivo
web.xml,
en vez de eso puedes crear un
servlets.xml (con elementos
servlet
y
servlet-mapping), un
filters.xml (con elementos
filter
y
filter-mapping), un
listeners.xml (con elementos
listener,
desde v4.0.1) y un
resources.xml (con elementos
resource-ref,
desde v5.4) en la carpeta WEB-INF. Aunque este método es obsoleto
todavía funciona con las últimas versiones de OpenXava.
Por ejemplo, si quieres añadir un servlet llamado
TestServlet,
crea un archivo
servlets.xml en WEB-INF con el siguiente
contenido:
<!-- Con v6.0 o superior es mejor usar @WebServlet -->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>org.openxava.test.servlets.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
Este fragmento será insertado automáticamente en
web.xml cuando
llames a las tareas ant
deplegarWar o
actualizarOX.
¿Cómo
crear un elemento nuevo directamente desde una colección @ManyToMany? (nuevo
en v4m4)
Por defecto en una colección
@ManyToMany el usuario puede añadir
elementos existentes a la colección, sin embargo no puede crear nuevos.
Afortunadamente, puedes añadir esta funcionalidad usando la acción
ManyToMany.new
(incluida en OpenXava) como una acción de lista. Como sigue:
@ManyToMany
@ListAction("ManyToMany.new")
private Collection<Humano> miembros;
¿Cómo
cambiar el esquema, idioma o usuario a través de parametros url? (nuevo
en v4m4)
Usted puede cambiar el esquema, idioma o usuario a través de parámetros
url con sólo incluirle al módulo el controlador
UrlParameters
(1). Por ejemplo, incluiremos en
application.xml el controlador:
<application name="MyApplication">
<module name="MyModule">
<model name="MyModel"/>
<controller name="Typical"/>
<controller name="UrlParameters" /> // 1
</module>
</application>
Ahora el URL para invocar el módulo, basta con incluir el parametro
schema.
http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&schema=companyA
o el idioma:
http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&locale=es
o el usuario actual (el valor se guarda en el atributo de sesión
xava.user):
http://localhost:8080/MyApplication/xava/module?application=MyApplication&module=MyModule&user=theUser
Estos parámetros no son exclusivos, pueden ser utilizados todos al mismo
tiempo o en cualquier combinación.
¿Cómo
modificar los parámetros en los listados por defecto?
Podemos cambiar los parámetros que se incluyen en los listados por defecto
mediante código. En este caso cambiaremos el nombre de la organización:
Por defecto este nombre de organización se recoge del valor de
'xava.organization' desde los ficheros i18n, pero nosotros lo
modificaremos para que recoja un valor variable.
Simplemente hay que crear una clase que implemente a
IReportParametersProvider y añadir el código que necesitemos al método
'getOrganization()':
package org.openxava.test.util
import org.openxava.util.*;
/**
*/
class MyReportParametersProvider implements IReportParametersProvider {
String getOrganization() {
return "report to " + Users.getCurrent()
}
}
Por último tendremos que añadir a nuestro fichero 'xava.properties' una
nueva línea indicando la clase que vamos a usar:
reportParametersProviderClass=org.openxava.test.util.MyReportParametersProvider
¿Cómo generar
informes HTML?
Un opción es redireccionar a un JSP que genere el informe HTML, podemos
hacer esto por medio de
IForwardAction. Otra opción es usar la acción
SimpleHTMLReportAction (
desde v4.3)
que permite trabajar con plantillas de HTML simples.
¿Cómo
generar varios informes desde una única acción?
Extiende tu acción de
JasperMultipleReportBaseAction (nuevo en
v4.3). Tienes un ejemplo en
InvoiceTwoReportsAction de
OpenXavaTest.
¿Cómo
unir varios reportes en un único PDF?
Extiende la acción
JasperConcatReportBaseAction (nuevo en v5.0).
Útil cuando necesitas concatenar varios reportes con diferentes formatos
de página (landscape, portrait). Hay un ejemplo en
MovieReportAction
de
OpenXavaTest.
¿Cómo
añadir tu propio portlet a tu aplicación OpenXava (nuevo en v4.6,
hasta v6.6.3)?
Para añadir tu propio portlet a tu aplicación OX no modifiques el archivo
portlet.xml directamente, en vez de eso crear un archivo
portlet-ext.xml
(con elementos
portlet) y un
liferay-display-ext.xml
(con elementos
portlet) en la carpeta WEB-INF.
Por ejemplo, si quieres crear un portlet llamado
VersionPortlet,
crea un archivo
portlet-ext.xml en WEB-INF con el siguiente
contenido:
<portlet id="Version">
<description>OpenXavaTest - Version</description>
<description xml:lang="ca">OpenXavaTest - Versió</description>
<description xml:lang="es">OpenXavaTest - Versión</description>
<description xml:lang="fr">OpenXavaTest - Version</description>
<portlet-name>Version</portlet-name>
<display-name>OpenXava - Version</display-name>
<display-name xml:lang="ca">OpenXavaTest - Versió</display-name>
<display-name xml:lang="es">OpenXavaTest - Versión</display-name>
<display-name xml:lang="fr">OpenXavaTest - Version</display-name>
<portlet-class>org.openxava.test.portlets.VersionPortlet</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<supported-locale>ca</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>en</supported-locale>
<supported-locale>fr</supported-locale>
<resource-bundle>portlets/Version</resource-bundle>
</portlet>
Si estás usando Liferay puedes crear opcionalmente el archivo
liferay-display-ext.xml
para añadir entradas a
liferay-display.xml. Así, para el portlet
de arriba puedes escribir un
liferay-display-ext.xml con el
siguiente contenido:
<portlet id="Version" />
Este fragmento se insertará automáticamente en
liferay-display.xml
cuando llames a la tarea ant
generatePortlets.
Además, has de escribir el archivo de recursos, en este caso has de
escribir
Version_ca.properties,
Version_es.properties,
Version_en.properties y
Version_fr.properties. Aquí
tenemos un ejemplo para
Version_es.properties:
javax.portlet.short-title=Versión
javax.portlet.title=OpenXavaTest - Versión
category.OpenXavaTest=OpenXavaTest
Y, por supuesto, necesitas escribir el código de tu portlet, en este caso:
package org.openxava.test.portlets;
import java.io.*;
import javax.portlet.*;
import org.openxava.controller.*;
public class VersionPortlet extends GenericPortlet {
public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
response.setContentType("text/html");
response.getWriter().write("<table border=\"0\">");
writeVersion(response.getWriter(), "The version of OpenXava is", ModuleManager.getVersion());
response.getWriter().write("</table>");
}
private void writeVersion(PrintWriter out, String unit, String version) {
out.write("<tr>");
out.write("<td style=\"padding: 2px 5px 2px 5px;\"><b>" + unit + "</b></td>");
out.write("<td style=\"padding: 2px 5px 2px 5px;\">v" + version + "</td>");
out.write("</tr>");
}
}
¿Cómo
definir tu propio contenido para la página de Bienvenida y la página de
Primeros pasos (nuevo en v5.0)?
Para modificar la página de Bienvenida, edita el archivo
src/main/webapp/naviox/welcome.jsp
de tu proyecto. Para modificar la página de Primeros pasos, utiliza la
propiedad
initialModule en
naviox.properties, como se
explica en la
documentación de
navegación entre módulos. Para v6, edita
web/naviox/welcome.jsp
y
web/naviox/firstSteps.jsp en tu proyecto. Si tu proyecto fue
creado con v7.1 o v7.2, primero tienes que copiar
welcome.jsp del
repositorio de GitHub a tu proyecto, sigue las
instrucciones
en la documentación de personalización para hacerlo.
¿Cómo
hacer que @Required permita números positivos, negativos o cero pero no
vacío?
Crear el archivo
Miproyecto/xava/validators.xml y debe contener
:
<?xml version = "1.0" encoding = "ISO-8859-1"?>
<validators>
<required-validator>
<validator-name name="NOT_EMPTY_STRING"/>
<for-type type="java.math.BigDecimal"/>
<for-type type="java.lang.Integer"/>
</required-validator>
<required-validator>
<validator-name name="NOT_NULL"/>
<for-type type="java.math.BigDecimal"/>
<for-type type="java.lang.Integer"/>
</required-validator>
</validators>
Nota: Adecuar los for-type con
los tipos que se utilicen para manejar datos numéricos
¿Cómo
tener acceso al objeto View desde un JSP propio?
En nuestro JSP añadimos las siguientes lineas:
<jsp:useBean id="context" class="org.openxava.controller.ModuleContext" scope="session"/>
<%
String viewObject = request.getParameter("viewObject");
viewObject = (viewObject == null || viewObject.equals(""))?"xava_view":viewObject;
org.openxava.view.View view = (org.openxava.view.View) context.get(request, viewObject);
System.out.println("modelo: " + view.getModelName()); // Aquí usamos view
¿Cómo
generar Excel de verdad en lugar de CSV (nuevo en v5.5)?
Añade esto a tu
aplicacion.xml:
<modulo-defecto>
<controlador nombre="TypicalRealExcel"/>
</modulo-defecto>
Además, en tus propios controladores has de extender
TypicalRealExcel
en vez de
Typical.
¿Cómo
redireccionar a otra página en una ventana nueva sin recargar la página
actual?
Recargar la página actual es el comportamiento correcto porque tu acción
podría cambiar la vista, añadir mensajes, etc. De todas formas, si quieres
redireccionar sin recargar es posible usando JavaScript, de esta forma:
package org.openxava.provaox.actions;
import org.openxava.actions.*;
public class RedireccionarSinCargar extends BaseAction implements IForwardAction {
public void execute() throws Exception {
// Hacer algo aquí, si quieres
}
public boolean inNewWindow() {
return false; // Porque abriremos la ventana nosotros mismos usando JavaScript
}
public String getForwardURI() {
return "javascript:void(window.open('/MiAplicacion/miurl'))";
}
}
¿Cómo tener los proyectos OpenXava y Addons en una carpeta diferente a
tu propio proyecto? (nuevo en v6.1.1)?
Por defecto, los proyectos
Addons y
OpenXava han de estar
en el mismo directorio (normalmente el workspace) que tu propio proyecto.
Sin embargo, a partir de v6.1.1 puedes especificar un directorio diferente
para los proyectos
OpenXava y
Addons. Simplemente añade (o
modifica) la propiedad
openxava.base.dir de
build.xml de
tu proyecto:
<property name="openxava.base.dir" value="/home/juan/mi-openxava"/>
De esta manera usarás los proyectos
OpenXava y Addons del
directorio
/home/juan/mi-openxava.
¿Cómo correr tu aplicación en el contexto raíz (nuevo en v6.3)?
Es decir, usándola desde el navegador sin el nombre de la aplicación en la
URL, como esto:
https://localhost:8080/
Para producción es suficiente
con llamar ROOT.war al war a desplegar en Tomcat, no necesitas
cambiar tu código.
Para desarrollo puedes modificar
la clase lanzadora (com.tuempresa.tuaplicacion.run.tuaplicacion a
partir de v7.0 o _Run_TuAplicacion con v6.x) cambiando:
AppServer.run("TuAplicacion");
Por:
Y si quieres probar tu
aplicación en el contexto raíz usando JUnit, añade la siguiente entrada
en xava-junit.properties:
Por supuesto, puedes usar el
contexto raíz sólo en producción y no en desarrollo, o viceversa.