tag:blogger.com,1999:blog-42343043237275368942024-01-22T09:53:09.798-08:00Anécdotas de las Curvas del SenoSoftware Libre, Programación, Informática y #BacilDaniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.comBlogger377125tag:blogger.com,1999:blog-4234304323727536894.post-7914310968784235242011-11-07T08:25:00.000-08:002011-11-07T13:08:25.535-08:00Glassfish 3.0: Cliente Remoto EJB 3.0<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/--1tkuoWoEyU/TrgF3dN03vI/AAAAAAAABzM/x1aJD_l7VTM/s1600/mojarra_logo.bmp" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" ida="true" src="http://2.bp.blogspot.com/--1tkuoWoEyU/TrgF3dN03vI/AAAAAAAABzM/x1aJD_l7VTM/s1600/mojarra_logo.bmp" /></a></div>
<div style="text-align: justify;">
Hace poco me he visto en la necesidad de crear un cliente sobre unos session beans de <a href="http://krypto84sv.blogspot.com/search/label/jpa">EJB 3.0</a> en un servidor Glassfish 3.0 remoto para un proyecto que estoy realizando <a href="http://krypto84sv.blogspot.com/2011/11/eclipse-rap-rich-ajax-platform.html">sobre Eclipse RAP</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Esta vez realizare un pequeño ejemplo sobre como llevar a cabo la tarea apoyandome, como siempre, de <a href="http://krypto84sv.blogspot.com/search/label/spring">Spring 3.0</a> he invocare un servicio a través de JNDI.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Primeramente creare un módulo <a href="http://krypto84sv.blogspot.com/search/label/jpa">EJB</a> el cual creare una interfaz remota (es necesario que sea remota si se va a acceder al servicio fuera del contenedor). Si bien en J2EE 6 ya no es necesario utilizar interfaces a mi me gusta mas de esa manera para que no quede al descubierto la implementación de la solución y que a su vez al modulo que invocara el servicio, una interfaz le resulta mas simple usar.</div>
<br />
<textarea class="java" name="code">@Remote
public interface SesionEjemploRemote {
String getSaludo(String msg);
}
</textarea><br />
<br />
Luego realizo la implementación en el módulo EJB.<br />
<br />
<textarea class="java" name="code">@Stateless
public class SesionEjemplo implements SesionEjemploRemote {
@Override
public String getSaludo(String msg) {
return "Hola: "+msg;
}
}
</textarea><br />
<br />
Realizo el deploy en mi glassfish y procedo a realizar un cliente standalone.<br />
<br />
Para realizar el cliente es necesario importar el jar gf-client.jar que se encuentra en la carpeta lib de la instalación de glassfish 3.0.<br />
<br />
Ahora procedo a crear mi solución.<br />
<br />
<textarea class="java" name="code">import org.dani.ejb.SesionEjemploRemote;
public class EJBAction {
private SesionEjemploRemote sesionEjemplo;
public SesionEjemploRemote getSesionEjemplo() {
return sesionEjemplo;
}
public void setSesionEjemplo(SesionEjemploRemote sesionEjemplo) {
this.sesionEjemplo = sesionEjemplo;
}
}
</textarea><br />
<br />
Creo los archivos de configuración de spring.<br />
<br />
<textarea class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ctx" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
</textarea><br />
<br />
applicationContext.xml<br />
<textarea class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<jee:jndi-lookup id="sesionEjemplo" jndi-name="org.dani.ejb.SesionEjemploRemote">
<jee:environment>
java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
org.omg.CORBA.ORBInitialHost=localhost
org.omg.CORBA.ORBInitialPort=3700
</jee:environment>
</jee:jndi-lookup>
<bean id="ejbAction" class="org.dani.ejemplo.ejb.client.EJBAction">
<property name="sesionEjemplo" ref="sesionEjemplo"/>
</bean>
</beans>
</textarea><br />
<br />
Por último creo mi clase main.<br />
<br />
<textarea class="java" name="code">public class Main {
public static void main(String[] args) throws NamingException {
Main start=new Main();
EJBAction action=(EJBAction) start.getBean("ejbAction");
SesionEjemploRemote sesion=action.getSesionEjemplo();
System.out.println(sesion.getSaludo("dani"));
}
private BeanFactory factory;
public Main() {
BeanFactoryLocator beanFactoryLocator = SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference beanFactoryReference = beanFactoryLocator.useBeanFactory("ctx");
factory = beanFactoryReference.getFactory();
}
public Object getBean(String id) {
return factory.getBean(id);
}
}
</textarea><br />
<br />
Adjunto <a href="http://www.mediafire.com/file/6k6u4dhe7lqz581/Cliente%20EJB.rar">codigo fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com2tag:blogger.com,1999:blog-4234304323727536894.post-9055178982244111312011-11-01T15:49:00.000-07:002011-11-01T16:00:18.474-07:00Eclipse RAP (Rich Ajax Platform)<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Z-QrGAT-Kds/TrB1KTrEFbI/AAAAAAAABzE/22QOHEC0jvU/s1600/osxeclipseicon2561.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" ida="true" src="http://3.bp.blogspot.com/-Z-QrGAT-Kds/TrB1KTrEFbI/AAAAAAAABzE/22QOHEC0jvU/s1600/osxeclipseicon2561.jpg" /></a></div>
<div style="text-align: justify;">
¿Qué es Eclipse Rich Ajax Platform?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Es una plataforma Ajax que sirve para crear desarrollar fácilmente aplicaciones RIA (Rich Internet Applications).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Algunos se diran, ¿y que no existe ya para eso <a href="http://krypto84sv.blogspot.com/search/label/jsf%202.0">JSF</a>, Struts, etc...? claro que si, pero la diferencia las tecnologias anteriormente mencionadas es que Eclipse RAP es que se pueden crear aplicaciones "ricas" tanto web como de escritorio (Eclipse RPC) reutilizando el mismo modelo de componentes SWT de Eclipse basado en OSGI sin necesidad de duplicar esfuerzos haciendo lo mismo dos veces.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
La página oficial del proyecto Eclipse RAP es <a href="http://www.eclipse.org/rap">www.eclipse.org/rap</a>, se pueden observar <a href="http://www.eclipse.org/rap/demos/">tambien demos</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En lo personal me ha llamado mucho la atención, para mí, esta nueva tecnologia, posteriormente estare dearrollando ejemplos concretos utilizando frameworks estandar de desarrollo como lo son <a href="http://krypto84sv.blogspot.com/search/label/jpa">JPA</a>, <a href="http://krypto84sv.blogspot.com/search/label/spring">Spring</a> e <a href="http://krypto84sv.blogspot.com/search/label/hibernate">Hibernate</a>.</div>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-12701590553212240682011-10-24T08:24:00.000-07:002011-10-24T08:24:42.821-07:00JSF 2.0: TouchFaces<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9K_70pj0LgM/TqWCnQE_PVI/AAAAAAAAByg/FSkzslUOWdA/s1600/primefaces_logo_small.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" rda="true" src="http://1.bp.blogspot.com/-9K_70pj0LgM/TqWCnQE_PVI/AAAAAAAAByg/FSkzslUOWdA/s1600/primefaces_logo_small.png" /></a></div>
<div style="text-align: justify;">
Hace poco me vi en la necesidad de realizar cierto desarrollo para Iphones, pero no tenia ganas de aprender ObjectiveC, y me tope con la implementación para mobiles de <a href="http://krypto84sv.blogspot.com/search/label/primefaces">Primefaces</a> denominada TouchFaces, la cual se basa en JQTouch (JQuery).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
De ahora en adelante puedo realizar aplicaciones web basadas en <a href="http://krypto84sv.blogspot.com/search/label/jsf%202.0">JSF</a> para dispositivos apple-touch, android, blackberry, etc...</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Aca desarrollare un pequeño ejemplo de <a href="http://krypto84sv.blogspot.com/search/label/primefaces">Primefaces</a> TouchFaces.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
El managed bean es sencillo.</div>
<br />
<textarea class="java" name="code">@ManagedBean
@ViewScoped
public class DemoBean {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
</textarea><br />
<br />
Luego la parte mas importante la vista.<br />
<br />
<textarea class="xml" name="code"><f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:i="http://primefaces.prime.com.tr/touch"
xmlns:ui="http://java.sun.com/jsf/facelets">
<i:application>
<i:view id="home" title="Home">
<h:form>
<i:tableView>
<i:rowGroup title="Input Text">
<i:rowItem>
<h:inputText value="#{demoBean.text}">
</h:inputText>
</i:rowItem>
</i:rowGroup>
<i:rowGroup title="My Group">
<i:rowItem value="Detail" view="detail" update="table"/>
</i:rowGroup>
</i:tableView>
</h:form>
</i:view>
<i:view id="detail" title="Detail">
<f:facet name="leftNavBar">
<i:navBarControl label="Back" view="home" effect="flip"/>
</f:facet>
<i:tableView id="table">
<i:rowGroup title="Text">
<i:rowItem>
<h:outputText value="#{demoBean.text}"/>
</i:rowItem>
</i:rowGroup>
</i:tableView>
</i:view>
</i:application>
</f:view>
</textarea><br />
<br />
Aca la captura de pantalla desde mi ipod touch.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-QnvsCwkjJ88/TqWCsh1nJ1I/AAAAAAAAByo/jVfcmsERZrM/s1600/IMG_0054.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" rda="true" src="http://1.bp.blogspot.com/-QnvsCwkjJ88/TqWCsh1nJ1I/AAAAAAAAByo/jVfcmsERZrM/s320/IMG_0054.PNG" width="213" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-SMkLvOO-DIc/TqWCvfzg5II/AAAAAAAAByw/LFPaPw0tfNs/s1600/IMG_0055.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" rda="true" src="http://3.bp.blogspot.com/-SMkLvOO-DIc/TqWCvfzg5II/AAAAAAAAByw/LFPaPw0tfNs/s320/IMG_0055.PNG" width="213" /></a></div>
<br />
Adjunto <a href="http://www.mediafire.com/file/2d8i2a18yxhsiw5/prime-mobile.rar">codigo fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-81772081928437536612011-10-16T15:20:00.000-07:002011-10-16T15:20:51.618-07:00Primefaces: progressBarUltimamente evaluando las implementaciones de JSF me he decantado por Primefaces ya que es el que mejor se integra al ciclo de vida de JSF y utiliza JQuery que lo hace mucho rápido que incluso Richfaces e ICEfaces, aunque me falta investigar mucho mas sobre OpenFaces.<br />
<br />
Me dedicare a realizar algunos ejemplos sobre el uso de los componentes de Primefaces, que si bien ya existe un showcase pero a veces el código de ejemplo no se entiende muy claro.<br />
<br />
En esta ocasión realizare un ejemplo para el uso del componente progressBar al iniciar una página.<br />
<br />
Primero definimos el backing bean<br />
<textarea class="java" name="code">@ManagedBean
@ViewScoped
public class LoadBean {
private int progress;
@PostConstruct
public void init(){
progress=0;
LoadThread load=new LoadThread(this);
load.start();
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
}
</textarea><br />
Luego el hilo LoadThread<br />
<textarea class="java" name="code">public class LoadThread extends Thread {
private LoadBean bean;
public LoadThread(LoadBean bean) {
this.bean=bean;
}
@Override
public void run() {
for(int i=1;i<=100;i++) {
System.out.println(i);
bean.setProgress(i);
pausa();
}
}
public void pausa(){
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
</textarea><br />
La vista xhtml quedara de la siguiente forma<br />
<textarea class="xml" name="code"><html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body onload="pb.start()">
<h:form>
<h:panelGrid>
<p:progressBar widgetVar="pb" ajax="true"
onCompleteUpdate="msg"
oncomplete="dlg1.show()"
value="#{loadBean.progress}" interval="100"/>
</h:panelGrid>
<p:dialog header="PrimeFaces Dialog" widgetVar="dlg1" width="500">
For more information visit <a href="http://primefaces.org">http://primefaces.org</a>.
</p:dialog>
</h:form>
</h:body>
</html>
</textarea><br />
Adjunto <a href="http://www.mediafire.com/file/7tvogbj8h04h56f/progressbar-demo.rar">código fuente</a> para efectos de estudioDaniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com1tag:blogger.com,1999:blog-4234304323727536894.post-5087700407847178742011-10-07T12:53:00.000-07:002011-10-07T14:58:10.968-07:00JSF 2.0: Error Handling<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-aVFJubHRL4w/To9X0f4ymMI/AAAAAAAAByM/nl8SsG0q50o/s1600/mojarra_logo.bmp" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://2.bp.blogspot.com/-aVFJubHRL4w/To9X0f4ymMI/AAAAAAAAByM/nl8SsG0q50o/s1600/mojarra_logo.bmp" /></a></div>
<div style="text-align: justify;">
Ya había realizado un post sobre como <a href="http://krypto84sv.blogspot.com/2011/09/manejo-de-errores-y-validaciones-con.html">manejar las excepciones en JSF apoyandome en richfaces</a>, pero lo hicen pensando que aún seguia utilizando JSF 1.2, esta vez lo haré casi de forma similar pero esta vez para la versión 2.0 de JSF y apoyandome con primefaces y usando un poco de <a href="http://krypto84sv.blogspot.com/search/label/spring">spring</a> para poder enviar los errores al contexto de la aplicación.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Este post será muy similar a como se <a href="http://krypto84sv.blogspot.com/2011/09/manejo-de-errores-y-validaciones-en.html">manejan los errores como en swing</a>, que será implementando dos clases que capturan las excepciones en tiempo de ejecucion.</div>
<textarea class="java" name="code">public class ExceptionWrapper extends ExceptionHandlerWrapper{
private ExceptionHandler wrapper;
private IManagedBean bean;
public ExceptionWrapper(ExceptionHandler wrapper) {
this.wrapper=wrapper;
bean=(IManagedBean) FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance()).getBean("managedBean");
}
@Override
public ExceptionHandler getWrapped() {
return wrapper;
}
@Override
public void handle() throws FacesException {
Iterator<ExceptionQueuedEvent> i=getUnhandledExceptionQueuedEvents().iterator();
while(i.hasNext()) {
ExceptionQueuedEvent evt=i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) evt.getSource();
Throwable t=context.getException();
try{
String msgDetail=t.getMessage();
String msgSummary=t.getCause().getMessage();
bean.addError(msgDetail, msgSummary);
}
finally {
i.remove();
}
}
getWrapped().handle();
}
}
</textarea><br />
Luego el factory<br />
<textarea class="java" name="code">public class ExceptionFactory extends ExceptionHandlerFactory{
private ExceptionHandlerFactory parent;
public ExceptionFactory(ExceptionHandlerFactory parent) {
this.parent=parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler result=new ExceptionWrapper(parent.getExceptionHandler());
return result;
}
}
</textarea><br />
Ahora hay que registrar el exception factory en el faces-config.xml<br />
<textarea class="xml" name="code"><factory>
<exception-handler-factory>
org.dani.ejemplo.caught.ExceptionFactory
</exception-handler-factory>
</factory>
</textarea><br />
Mi bean que implementa la funcionalidad para enviar los mensajes al contexto de la aplicacion sera asi:<br />
<textarea class="java" name="code">public class ManagedBeanImpl implements IManagedBean{
protected FacesContext getCurrentContext() {
return FacesContext.getCurrentInstance();
}
private void addMessage(String detail,String summary,Severity severity) {
getCurrentContext().addMessage(null, new FacesMessage(severity, summary, detail));
}
public void addInfo(String detail, String summary) {
addMessage(detail, summary, FacesMessage.SEVERITY_INFO);
}
public void addError(String detail, String summary) {
addMessage(detail, summary, FacesMessage.SEVERITY_ERROR);
}
}
</textarea><br />
No explicare como configurar el bean anterior con spring ya que para ello ya<a href="http://krypto84sv.blogspot.com/search/label/spring"> he abordado el tema bastante</a>.<br />
Mi managed bean quedara de la siguiente manera<br />
<textarea class="java" name="code">@ManagedBean
@ViewScoped
public class ViewBean extends ManagedBeanImpl{
private String requiredField;
public String doGenericError() {
int n=1/0;
System.out.println(n);
return null;
}
public String doOk() {
if (!requiredField.equals("123")) throw new MyCustomException("Valor incorrecto");
String success="Valor correcto";
addInfo(success, success);
return null;
}
public String getRequiredField() {
return requiredField;
}
public void setRequiredField(String requiredField) {
this.requiredField = requiredField;
}
}
</textarea><br />
La plantilla la defino de la siguiente manera<br/>
<textarea name="code" class="xml">
<h:body>
<h:form>
<p:growl id="messages" />
<ui:insert name="body"/>
</h:form>
</h:body>
</textarea>
Y la pagina implementando la plantilla<br/>
<textarea name="code" class="xml">
<ui:composition template="./template.xhtml">
<ui:define name="body">
<h:panelGrid columns="2">
<h:outputText value="Campo requerido"/>
<p:inputText label="Campo" value="#{viewBean.requiredField}" required="true"/>
<p:commandButton value="Aceptar" action="#{viewBean.doOk}" update="messages"/>
<p:commandButton value="Genera Error" update="messages"
process="@this"
action="#{viewBean.doGenericError}"/>
</h:panelGrid>
</ui:define>
</ui:composition>
</textarea><br/>
El resultado seria así<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-l6C0dWTGEUI/To9YY_JKgkI/AAAAAAAAByQ/fd8AU7tBaAo/s1600/errorhandling_runtime.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="76" kca="true" src="http://2.bp.blogspot.com/-l6C0dWTGEUI/To9YY_JKgkI/AAAAAAAAByQ/fd8AU7tBaAo/s320/errorhandling_runtime.png" width="320" /></a></div>
<br />
Adjunto <a href="http://www.mediafire.com/?80cp45fx78cugv0">codigo fuente</a> para efectos de estudio. Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-18450777321634990912011-10-07T07:12:00.000-07:002011-10-07T07:12:18.661-07:00Inyectar objetos JSF 2.0 en Custom Converters<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/--jmNCdXC51Y/To8II1UVUJI/AAAAAAAAByI/9bD6sqmeJtg/s1600/mojarra_logo.bmp" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://2.bp.blogspot.com/--jmNCdXC51Y/To8II1UVUJI/AAAAAAAAByI/9bD6sqmeJtg/s1600/mojarra_logo.bmp" /></a></div>
<div style="text-align: justify;">
Ya en una entrada previa había explicado que son los <a href="http://krypto84sv.blogspot.com/2009/07/icefaces-custom-converter.html">convertidores en JSF</a> y como implementarlos, esta vez lo haré con JSF 2.0 e inyectare el acceso a datos a través de Spring.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
La clave de esto es utilizar el FacesContextUtils.</div>
<textarea class="java" name="code">@FacesConverter(forClass=MyEntity.class)
public class MyCustomConverter implements Converter{
public Object getAsObject(FacesContext context, UIComponent component, String value) {
MyDao dao=getDao();
return dao.getObjectById(Integer.valueOf(value));
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
MyEntity e=(MyEntity)value;
return e.getId().toString();
}
private MyDao getDao() {
return (MyDao) FacesContextUtils.
getWebApplicationContext(FacesContext.getCurrentInstance()).
getBean("idMyDao");
}
}
</textarea><br />
De esta forma ya no es necesario registrar el converter en el archivo faces-config.xml y puede utilizarse para cualquier tipo de componente.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-56213258770535880372011-10-05T12:56:00.000-07:002011-10-07T12:59:14.120-07:00Integracion de Liquibase con Spring y JPA<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-wg_Z0iRpOMI/ToyzsK5V8hI/AAAAAAAAByE/wclAXALPdVY/s1600/liquibase_logo.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="26" src="http://4.bp.blogspot.com/-wg_Z0iRpOMI/ToyzsK5V8hI/AAAAAAAAByE/wclAXALPdVY/s320/liquibase_logo.gif" width="137" /></a></div>
¿Qué es Liquibase?<br />
<br />
<div style="text-align: justify;">
Liquibase, es una libreria opensource para gestionar los cambios en base de datos. En la etapa de desarrollo de un sistema casi como norma debe versionarse el código fuente, pero no había un mecanismo para llevar un control de los cambios en la estructura de la base de datos y de esta necesidad nace liquibase.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En un equipo de desarrollo es habitual que cada miembro realice procedimientos almacenados, vistas o cambios en las estructuras de las tablas en función de las funciones que este desarrollando y al momento de integrar todo se vuelve un quilombo. Con liquibase los cambios se realizan a través de un archivo de cambios el cual se sincroniza con los demás miembros del equipo, de esta forma los cambios no se hacen directamente a la base de datos sino desde la aplicación al momento de su ejecución.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Desarrollare un pequeño ejemplo de como implementar esta libreria con <a href="http://krypto84sv.blogspot.com/2011/09/spring-30-y-jsf-20.html">Spring y JPA</a>, del lado de la base de datos utilizare <a href="http://krypto84sv.blogspot.com/search/label/postgresql">PostgreSQL</a>. Supondremos que ya tenemos creado nuestro acceso a datos y procedemos a configurar el contexto de spring.</div>
<br />
<textarea class="xml" name="code"><bean id="dao" class="org.dani.ejemplo.jpa.dao.DerbyImpl">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="dataSource" />
<property name="changeLog" value="classpath:/org/dani/ejemplo/liquibase/db-changelog.xml" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" depends-on="liquibase">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="liquibase-demoPU"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="org.postgresql.Driver"/>
<property name="jdbcUrl" value="jdbc:postgresql://localhost/devdb"/>
<property name="user" value="dev"/>
<property name="password" value="dev"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</textarea><br />
Ahora se debe configurar el archivo donde se declaran los cambios en la base de datos.<br />
<textarea class="xml" name="code"><?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<preConditions>
<dbms type="postgresql" />
</preConditions>
<changeSet author="dani" id="1">
<createTable tableName="responsible">
<column name="id" type="int" autoIncrement="true">
<constraints nullable="false" primaryKey="true" />
</column>
<column name="name" type="varchar"/>
</createTable>
<createTable tableName="project">
<column name="id" type="int" autoIncrement="true">
<constraints nullable="false" primaryKey="true" />
</column>
<column name="description" type="varchar" />
<column name="start_date" type="datetime" />
<column name="end_date" type="datetime" />
<column name="fk_responsible" type="int">
<constraints foreignKeyName="project-responsible" references="responsible"/>
</column>
</createTable>
<sql>insert into responsible(name) values('dani');</sql>
</changeSet>
<changeSet id="2" author="dani">
<addColumn tableName="responsible">
<column name="last_name" type="varchar"/>
</addColumn>
<update tableName="responsible">
<column name="name" value="Daniel"/>
<where>id=1</where>
</update>
</changeSet>
<changeSet id="3" author="dani">
<renameColumn tableName="responsible" oldColumnName="name" newColumnName="first_name"/>
<update tableName="responsible">
<column name="last_name" value="Herrera"/>
<where>id=1</where>
</update>
</changeSet>
</databaseChangeLog>
</textarea><br />
Cuando ejecutemos la aplicación liquibase intentara primeramente hacer efectivos los cambios configurados en db-changelog.xml<br />
<br />
En el caso de JPA, es de tener en cuenta que siempre hay que actualizar manualmente los Entity class, ya que no es parte de las funciones de liquibase.<br />
<textarea class="java" name="code">public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("/org/dani/ejemplo/liquibase/applicationContext.xml");
Derby dao=(Derby)ctx.getBean("dao");
List<Responsible> list=dao.getallResponsibles();
for(Responsible r:list)
System.out.println(r.getFirst_name());
}
</textarea><br />
Adjunto <a href="http://www.mediafire.com/?7tr7t55zigsf2gz">código fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com1tag:blogger.com,1999:blog-4234304323727536894.post-21193831607646132542011-09-30T12:46:00.000-07:002011-10-07T13:01:30.355-07:00Lazy Loading: Primefaces<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-cBHWKwKr36A/ToYb7Kn_xLI/AAAAAAAABx4/-qAOL0x_QGU/s1600/primefaces_logo.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://2.bp.blogspot.com/-cBHWKwKr36A/ToYb7Kn_xLI/AAAAAAAABx4/-qAOL0x_QGU/s1600/primefaces_logo.jpg" /></a></div>
<div style="text-align: justify;">
Otro sabor de JSF es Primefaces, si bien es una suite bastante nueva, ha tenido bastante aceptación por gran parte de programadores JSF por su fácil utilización y que se integra muy bien con JSF 2.0.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Si bien ya había explicado como realizar <a href="http://krypto84sv.blogspot.com/2011/09/lazy-loading-en-icedatatable-con.html">lazy loading con ICEfaces</a> (de forma similar tambien se hace con Richfaces) en esta ocasión mostrare como se realiza con Primefaces, que ya trae una funcionalidad especifica para el cometido.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Basandome en la entrada sobre <a href="http://krypto84sv.blogspot.com/2011/09/spring-30-y-jsf-20.html">JSF y Spring</a> nada mas me concentrare en implementar la solución sobre el managed bean.</div>
<br />
<textarea class="java" name="code">package org.dani.ejemplo.web;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.dani.ejemplo.dao.DerbyDAO;
import org.primefaces.model.LazyDataModel;
/**
*
* @author dherrera
*/
@ManagedBean
@ViewScoped
public class ViewManaged {
@ManagedProperty("#{dao}")
private DerbyDAO dao;
private LazyDataModel model;
@PostConstruct
public void init() {
model = new LazyDataModel() {
@Override
public List load(int first, int pageSize, String sortField, boolean sortOrder, Map filters) {
return dao.getFindManufacturers(first, pageSize);
}
};
model.setRowCount(dao.getTotalManufacturers());
}
public LazyDataModel getModel() {
return model;
}
public void setDao(DerbyDAO dao) {
this.dao = dao;
}
}
</textarea><br />
<br />
Luego en la pagina xhtml<br />
<br />
<textarea class="xml" name="code"><?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<p:dataTable value="#{viewManaged.model}" lazy="true" rows="4"
var="m"
paginator="true">
<p:column>
<f:facet name="header">
<h:outputText value="Nombre"/>
</f:facet>
<h:outputText value="#{m.name}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{m.email}"/>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
</textarea><br />
<br />
El resultado sera el siguiente<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-DPJLGTuryMA/ToYcNS62SlI/AAAAAAAABx8/silS1_x0zbE/s1600/primefaces_runtime.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="146" kca="true" src="http://3.bp.blogspot.com/-DPJLGTuryMA/ToYcNS62SlI/AAAAAAAABx8/silS1_x0zbE/s320/primefaces_runtime.png" width="320" /></a></div>
<br />
Puede notarse que al momento de la ejecución es mucho mas rápida que <a href="http://krypto84sv.blogspot.com/2011/09/lazy-loading-en-icedatatable-con.html">la hechiza en ICEfaces</a>, ya que es propia del framework. <br />
<br />
Adjunto <a href="http://www.mediafire.com/?dxq833hjm2f7h3n">codigo fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com2tag:blogger.com,1999:blog-4234304323727536894.post-3707809570215440172011-09-30T08:54:00.000-07:002011-10-07T13:02:59.992-07:00Lazy Loading en ice:dataTable con ICEfaces<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; text-align: justify;">
<a href="http://3.bp.blogspot.com/-0kmGGFxrB6k/ToXkjhNXb7I/AAAAAAAABxw/lhwlFnvWzPM/s1600/icefaces-logo.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://3.bp.blogspot.com/-0kmGGFxrB6k/ToXkjhNXb7I/AAAAAAAABxw/lhwlFnvWzPM/s1600/icefaces-logo.png" /></a>¿Que és lazy loading? pues traduciendolo a mi manera en español podria referirse a carga ociosa, es decir carga ociosa de datos. ¿para que se utiliza? sucede que cuando se utiliza un dataTable con JSF siempre se le envia la lista completa de registros que se obtienen de una busqueda en la base de datos y los carga todos de una vez en la tabla para usarlos con un paginador, ¿pero que sucede si tenemos una busqueda de miles de registros? no podemos carga toda esa lista en el dataTable, entonces surge la necesidad de solo traer que necesitamos ver en el paginador por bloques.</div>
<div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;">
<br /></div>
<div style="text-align: justify;">
Algunos diran que ya existe un articulo en la documentación oficial de ICEfaces para realizar un lazy loading, pero el punto es que es muy dificil de entender ya que agregan otras funcionalidades que estan demas y mi objetivo es simplificar el entendimiento de la técnica.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En esta ocasión utilizare netbeans, tomcat y spring para el acceso a datos.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Utilizare tambien la tabla "Manufacturer" de la base de datos derby "Sample" embebida en netbeans, ya que es la unica que tiene algunos cuantos registros para efectos de prueba.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
No entrare en detalle de como configurar un proyecto <a href="http://krypto84sv.blogspot.com/2009/06/uso-de-facelets-y-icefaces-en-netbeans.html">JSF con ICEfaces</a> ni de como integrarlo con <a href="http://krypto84sv.blogspot.com/2011/09/spring-30-y-jsf-20.html">Spring para el acceso a datos</a>, supondre que se ha leido las entradas respectivas.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Suponiendo que ya se <a href="http://krypto84sv.blogspot.com/2008/11/introduciendo-al-uso-de-persistencia-de.html">ha generado el entity de la tabla</a> Manufacturer creo mi acceso a datos.</div>
<br />
<textarea class="java" name="code">package org.dani.ejemplo.dao;
import java.util.List;
/**
*
* @author dherrera
*/
public interface DerbyDAO {
int getTotalManufacturers();
List<Manufacturer> getFindManufacturers(final int firstRow, final int max);
}
</textarea><br />
<br />
Luego la implementación <br />
<br />
<textarea class="java" name="code">/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.dani.ejemplo.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
/**
*
* @author dherrera
*/
public class DerbyImpl extends JpaDaoSupport implements DerbyDAO{
public int getTotalManufacturers() {
Long count=(Long) getJpaTemplate().find("Select count(m) From Manufacturer m").get(0);
return count.intValue();
}
public List<Manufacturer> getFindManufacturers(final int firstRow, final int max) {
return getJpaTemplate().execute(new JpaCallback<List<Manufacturer>>() {
public List<Manufacturer> doInJpa(EntityManager em) throws PersistenceException {
return em.createQuery("Select m From Manufacturer m").setFirstResult(firstRow).
setMaxResults(max).
getResultList();
}
});
}
}
</textarea><br />
<br />
Luego creo mi configuracion en spring <br />
<br />
<textarea class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
">
<bean id="dao" class="org.dani.ejemplo.dao.DerbyImpl">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="lazyloadingPU"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/derby"/>
<!-- Utilizar este dataSource sino se quiere obtener por jndi
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="url" value="jdbc:derby://localhost:1527/sample"/>
<property name="username" value="app"/>
<property name="password" value="app"/>
</beans>-->
</beans>
</textarea><br />
<br />
Ahora la parte fundamental es crear un custom DataModel <br />
<br />
<textarea class="java" name="code">package org.dani.ejemplo.web.model;
import java.util.List;
import javax.faces.model.DataModel;
/**
*
* @author dherrera
*/
public class LazyModel<T> extends DataModel{
List<T> list;
private int pageSize;
private int totalRows;
private int rowIndex = -1;
public LazyModel(int totalRows,int pageSize, List<T> list) {
super();
this.pageSize=pageSize;
this.totalRows=totalRows;
this.list=list;
}
@Override
public boolean isRowAvailable() {
if(list == null)
return false;
int index = getRowIndex();
return (index >=0 && index < list.size());
}
@Override
public int getRowCount() {
return totalRows;
}
@Override
public Object getRowData() {
if(list == null)
return null;
else if(!isRowAvailable())
throw new IllegalArgumentException();
else {
int dataIndex = getRowIndex();
return list.get(dataIndex);
}
}
@Override
public int getRowIndex() {
return (rowIndex % pageSize);
}
@Override
public void setRowIndex(int i) {
rowIndex=i;
}
@Override
public Object getWrappedData() {
return list;
}
@Override
public void setWrappedData(Object o) {
this.list=(List<T>) o;
}
}
</textarea><br />
<br />
Ahora me dedico a crear los managed beans. <br />
<br />
<textarea class="java" name="code">package org.dani.ejemplo.web;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
/**
*
* @author dherrera
*/
public abstract class AbstractManagedBean {
protected FacesContext getCurrentContext() {
return FacesContext.getCurrentInstance();
}
protected Object getValueExpression(String expression) {
FacesContext ctx=getCurrentContext();
ExpressionFactory factory=ctx.getApplication().getExpressionFactory();
ValueExpression ex=factory.createValueExpression(ctx.getELContext(), expression, Object.class);
return ex.getValue(ctx.getELContext());
}
public String getBundleValue(String key) {
String expression="#{setting['"+key+"']}";
return (String)getValueExpression(expression);
}
}
</textarea><br />
<br />
<textarea class="java" name="code">package org.dani.ejemplo.web;
import com.icesoft.faces.component.datapaginator.DataPaginator;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import org.dani.ejemplo.dao.DerbyDAO;
import org.dani.ejemplo.dao.Manufacturer;
import org.dani.ejemplo.web.model.LazyModel;
/**
*
* @author dherrera
*/
@ManagedBean
@ViewScoped
public class ViewBean extends AbstractManagedBean implements Serializable{
@ManagedProperty("#{dao}")
private DerbyDAO dao;
private int firstRow;
private int pageSize;
@PostConstruct
public void init() {
firstRow=1;
pageSize=Integer.valueOf(getBundleValue("paginator.page_size"));
}
public LazyModel<Manufacturer> getModel() {
int totalRows=dao.getTotalManufacturers();
List<Manufacturer> list=dao.getFindManufacturers(firstRow, pageSize);
return new LazyModel<Manufacturer>(totalRows, pageSize, list);
}
public void pageListener(ActionEvent evt) {
DataPaginator paginator=(DataPaginator) evt.getSource();
this.firstRow=paginator.getFirstRow();
}
public void setDao(DerbyDAO dao) {
this.dao = dao;
}
}
</textarea><br />
<br />
Por ultimo el diseño de la página xhtml <br />
<br />
<textarea class="xml" name="code"><?xml version='1.0' encoding='UTF-8' ?>
<!--
Document : welcomeICEfaces
Created on : 09-29-2011, 03:17:32 PM
Author : dherrera
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:icecore="http://www.icefaces.org/icefaces/core"
xmlns:ace="http://www.icefaces.org/icefaces/components"
xmlns:ice="http://www.icesoft.com/icefaces/component"
>
<h:head>
<title>ICEfaces 2</title>
<link rel="stylesheet" type="text/css" href="./xmlhttp/css/rime/rime.css"/>
</h:head>
<h:body styleClass="ice-skin-rime">
<h:form id="form">
<ice:outputConnectionStatus/>
<ice:dataPaginator for="tabla"
actionListener="#{viewBean.pageListener}"
paginator="true" fastStep="#{setting['paginator.page_size']}" paginatorMaxPages="#{setting['paginator.max_pages']}">
<f:facet name="first">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-first.gif"/>
</f:facet>
<f:facet name="last">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-last.gif"/>
</f:facet>
<f:facet name="previous">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-previous.gif"/>
</f:facet>
<f:facet name="next">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-next.gif"/>
</f:facet>
<f:facet name="fastforward">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-ff.gif"/>
</f:facet>
<f:facet name="fastrewind">
<ice:graphicImage style="border:none;"
url="./xmlhttp/css/xp/css-images/arrow-fr.gif"/>
</f:facet>
</ice:dataPaginator>
<ice:dataTable id="tabla" value="#{viewBean.model}" var="m"
rows="#{setting['paginator.page_size']}">
<ice:column>
<f:facet name="header"><ice:outputText value="#{setting['customer.name']}"/></f:facet>
<ice:outputText value="#{m.name}"/>
</ice:column>
<ice:column>
<f:facet name="header"><ice:outputText value="#{setting['customer.email']}"/></f:facet>
<ice:outputText value="#{m.email}"/>
</ice:column>
</ice:dataTable>
</h:form>
</h:body>
<h:outputStylesheet library="org.icefaces.component.skins" name="rime.css" />
</html>
</textarea><br />
<br />
El resultado sera el siguiente <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-aFNB-oK45UY/ToXlRc2BD9I/AAAAAAAABx0/Kr2zZgJFoFA/s1600/lazyloading_runtime.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" kca="true" src="http://2.bp.blogspot.com/-aFNB-oK45UY/ToXlRc2BD9I/AAAAAAAABx0/Kr2zZgJFoFA/s320/lazyloading_runtime.png" width="320" /></a></div>
A través del trace se puede observar que por cada vez que se cambia de pagina se obtiene el bloque de registros que interesa. <br />
<br />
Adjunto el <a href="http://www.mediafire.com/?gy9rixhbd7y5s7o">codigo fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com2tag:blogger.com,1999:blog-4234304323727536894.post-84550633369489374262011-09-29T08:20:00.000-07:002011-10-07T13:07:15.054-07:00Manejo de errores y validaciones en Swing<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-s0a4oZucDbA/ToSMV_DlomI/AAAAAAAABxs/bUtcZ1b4u4U/s1600/java-logo.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://4.bp.blogspot.com/-s0a4oZucDbA/ToSMV_DlomI/AAAAAAAABxs/bUtcZ1b4u4U/s1600/java-logo.png" /></a></div>
<div style="text-align: justify;">
Si bien ya explique como <a href="http://krypto84sv.blogspot.com/2011/09/manejo-de-errores-y-validaciones-con.html">manejar los errores en JSF apoyandonos en Richfaces</a>, en esta ocasión explicare como se realiza en aplicaciones de escritorio utilizando swing. Lo primero es crear el manejador de excepciones que utilizara swing que debe de heredar de la clase EventQueue. </div>
<br />
<textarea class="java" name="code">package org.dani.ejemplo.exceptions;
import java.awt.AWTEvent;
import java.awt.EventQueue;
/**
*
* @author dherrera
*/
public class GlobalErrorHandler extends EventQueue{
@Override
public void dispatchEvent(AWTEvent evt) {
try {
super.dispatchEvent(evt);
}
catch (Throwable t) {
String msg=t.getMessage();
javax.swing.JOptionPane.showMessageDialog(null, msg);
}
}
}
</textarea><br />
<br />
<div style="text-align: justify;">
Luego realizamos nuestras excepciones personalizadas heredando de RuntimeException, el objetivo de crear nuestras propias excepciones es para poder categorizarlas y realizar acciones especificas en función de estas. </div>
<textarea class="java" name="code">package org.dani.ejemplo.exceptions;
/**
*
* @author dherrera
*/
public class ValidationException extends RuntimeException{
public ValidationException(String msg) {
super(msg);
}
public ValidationException(String msg,Throwable t) {
super(msg,t);
}
}
</textarea><br />
<div style="text-align: justify;">
Para este ejemplo he creado un JFrame llamado FrameException.java el cual contiene el método main, antes de ejecutar el formulario principal de la aplicación se debe configurar el manejador de excepciones. </div>
<textarea class="java" name="code">public static void main(String args[]) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exception e) {
e.printStackTrace();
}
//Aca se configura el manejador de excepciones..!!
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
queue.push(new GlobalErrorHandler());
new FrameException().setVisible(true);
}
</textarea><br />
Luego hago el diseño del formulario <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ZHp01Xld7f8/ToSMABdz5hI/AAAAAAAABxo/pOifx4j0fb0/s1600/design_login.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="123" kca="true" src="http://3.bp.blogspot.com/-ZHp01Xld7f8/ToSMABdz5hI/AAAAAAAABxo/pOifx4j0fb0/s320/design_login.png" width="320" /></a></div>
<br />
Ahora realizo las validaciones en el boton "Aceptar" <br />
<textarea class="java" name="code">private void btnAceptarActionPerformed(java.awt.event.ActionEvent evt) {
//Excepciones en tiempo de ejecución.
String usuario=txtUsuario.getText();
String pass=txtPass.getText();
if(!usuario.equals("dani"))
throw new ValidationException("Usuario no valido");
if(!pass.equals("yosoy"))
throw new ValidationException("Contraseña no valida");
javax.swing.JOptionPane.showMessageDialog(this, "Todo correcto...!!");
}
</textarea><br />
Ahora agrego un error a proposito en el boton "Produce error". <br />
<textarea class="java" name="code">private void btnErrorActionPerformed(java.awt.event.ActionEvent evt) {
/*
Aca podria darse cualquier tipo de excepcion como
un NullPointerException, base de datos o de webservice, etc...
*/
Integer numero=1/0;
}
</textarea><br />
<br />
Adjunto el <a href="http://www.mediafire.com/?ddczp5xwtiwi04j">codigo fuente</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-47941013078408331312011-09-27T11:23:00.000-07:002011-10-07T13:05:23.676-07:00Manejo de errores y validaciones con JSF 2.0 y Richfaces 4.0<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-3GJPmPjNqfI/ToIPC4i3kEI/AAAAAAAABxk/AcKNnBkXR-M/s1600/logo-richfaces.gif" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://2.bp.blogspot.com/-3GJPmPjNqfI/ToIPC4i3kEI/AAAAAAAABxk/AcKNnBkXR-M/s1600/logo-richfaces.gif" /></a></div>
<div style="text-align: justify;">
En esta ocasión es desarrollare un ejemplo en el cual se explica la forma en la cual se deben de manejar las excepciones o validaciones personalizadas en una aplicación JSF y con ayuda de Richfaces. La importancia de controlar las excepciones es por el hecho que nuestra aplicación pueda recuperarse por si misma ante cualquier eventualidad como por ejemplo una caida de base de datos. Este ejemplo lo hice en eclipse ya que no tenia un Netbeans a la mano, así que no entrare en detalles sobre como configurar un proyecto web con JSF 2.0 y Richfaces 4.0 sobre eclipse. El ejemplo tratara sobre un simple login de usuario, para el cual he creado la clase User.java</div>
<textarea class="java" name="code">package org.dani.ejemplo.richfaces.pojo;
import java.io.Serializable;
public class User implements Serializable{
private String id;
private String pass;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getPass() {
return pass;
}
}
</textarea><br />
Luego creo mis mensajes personalizados, ya que es una buena costumbre en cualquier tipo de aplicación ya sea de escritorio, web o incluso de línea de comandos por consola.<br />
<textarea class="javascript" name="code">#CustomMessagesValidation.properties
javax.faces.component.UIInput.REQUIRED={0}: Requerido.
</textarea><br />
<textarea class="javascript" name="code">#Labels.properties
label.title=Login de Usuario Richfaces
label.id=Identificador
label.password=Contraseña
button.ok=Aceptar
label.messages.system=Mensajes sistema
button.close=Cerrar
login.password_incorrect=Password Incorrecto
login.ok=Ingreso correcto..!!
login.password.correct=yosoy
</textarea><br />
Luego configuro mis mensajes personalizados en el archivo faces-config.xml<br />
<textarea class="xml" name="code"><?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<message-bundle>
org.dani.ejemplo.richfaces.messages.CustomMessagesValidation
</message-bundle>
<resource-bundle>
<base-name>org.dani.ejemplo.richfaces.messages.Labels</base-name>
<var>label</var>
</resource-bundle>
</application>
</faces-config>
</textarea><br />
Procedo a crear mi Excepcion personalizada para validaciones muy detalladas. <textarea class="java" name="code">package org.dani.ejemplo.richfaces.exceptions;
public class CustomValidationException extends Exception {
public CustomValidationException(String msg) {
super(msg);
}
public CustomValidationException(String msg, Throwable ex) {
super(msg,ex);
}
}
</textarea><br />
Creo la clase AbstractManagedBean.java para metodos comunes entre los demás managed beans. <textarea class="java" name="code">package org.dani.ejemplo.richfaces.web;
import java.util.ResourceBundle;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.context.FacesContext;
public class AbstractManagedBean {
protected FacesContext getCurrentContext() {
return FacesContext.getCurrentInstance();
}
public void addInfo(String msg) {
addMessage(msg, FacesMessage.SEVERITY_INFO);
}
public void addError(String msg) {
addMessage(msg, FacesMessage.SEVERITY_ERROR);
}
private void addMessage(String msg,Severity severity) {
FacesMessage message=new FacesMessage(msg);
message.setSeverity(severity);
FacesContext ctx=getCurrentContext();
ctx.addMessage(null, message);
}
public String getMessage(String key) {
return (String)getExpression("label['"+key+"']");
}
private Object getExpression(String expression) {
FacesContext ctx=getCurrentContext();
ExpressionFactory factory=ctx.getApplication().getExpressionFactory();
ValueExpression ex=factory.createValueExpression(ctx.getELContext(), "#{"+expression+"}", Object.class);
return ex.getValue(ctx.getELContext());
}
}
</textarea><br />
Creo un managed bean el cual se encargara exclusivamente de realizar el render de mensajes de sistema. <textarea class="java" name="code">package org.dani.ejemplo.richfaces.web;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean(name="messagesBean")
@RequestScoped
public class MessagesBean extends AbstractManagedBean implements Serializable{
public boolean isError() {
return !getCurrentContext().getMessageList().isEmpty();
}
}
</textarea><br />
Ahora creo el managed principal que se encargara de validar el login de usuario. <textarea class="java" name="code">package org.dani.ejemplo.richfaces.web;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.dani.ejemplo.richfaces.exceptions.CustomValidationException;
import org.dani.ejemplo.richfaces.pojo.User;
@ManagedBean(name="loginBean")
@ViewScoped
public class LoginBean extends AbstractManagedBean implements Serializable{
private User user;
@PostConstruct
public void init() {
user=new User();
}
public String doAceptar() {
try {
if (!user.getPass().equals(getMessage("login.password.correct")))
throw new CustomValidationException(getMessage("login.password_incorrect"));
addInfo(getMessage("login.ok"));
}
catch (CustomValidationException e) {
addError(e.getMessage());
}
catch (Exception e) {
//Algun otro error puede ser de base de datos, etc...
addError(e.getMessage()+":"+e.getCause());
}
return null;
}
public void setUsuario(User usuario) {
this.user = usuario;
}
public User getUsuario() {
return user;
}
}
</textarea><br />
Por ultimo realizo el diseño de la pagina xhtml.<br />
<textarea class="xhtml" name="code"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>#{label['label.title']}</title>
</h:head>
<h:body>
<h:form>
<rich:panel>
<f:facet name="header">
#{label['label.title']}
</f:facet>
<h:outputText style="color:red"
value="#{label['label.password']} = #{label['login.password.correct']}"/>
<h:panelGrid columns="2">
<h:outputText value="#{label['label.id']}"/>
<h:inputText label="#{label['label.id']}" value="#{loginBean.usuario.id}" required="true"/>
<h:outputText value="#{label['label.password']}"/>
<h:inputText label="#{label['label.password']}" value="#{loginBean.usuario.pass}" required="true"/>
</h:panelGrid>
<a4j:commandButton value="#{label['button.ok']}" action="#{loginBean.doAceptar}"
render="popup"
/>
</rich:panel>
<rich:popupPanel id="popup" show="#{messagesBean.error}" minHeight="10">
<f:facet name="header">
<h:outputText value="#{label['label.messages.system']}"/>
</f:facet>
<f:facet name="controls">
<a4j:commandButton value="#{label['button.close']}" onclick="#{rich:component('popup')}.hide(); return false;"/>
</f:facet>
<rich:messages/>
</rich:popupPanel>
</h:form>
</h:body>
</html>
</textarea><br />
La estructura del proyecto sera la siguiente<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-OJTezikubKI/ToIO569eCnI/AAAAAAAABxc/dvcFCV1d29w/s1600/struct_project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" kca="true" src="http://2.bp.blogspot.com/-OJTezikubKI/ToIO569eCnI/AAAAAAAABxc/dvcFCV1d29w/s320/struct_project.png" width="227" /></a></div>
<br />
<br />
El resultado sera el siguiente.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-A3sxyxj9ou8/ToIO--65moI/AAAAAAAABxg/blIuBEGhBdE/s1600/runtime.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="137" kca="true" src="http://3.bp.blogspot.com/-A3sxyxj9ou8/ToIO--65moI/AAAAAAAABxg/blIuBEGhBdE/s320/runtime.png" width="320" /></a></div>
<br />
Adjunto el <a href="http://www.mediafire.com/?701g33bp8j1iwbf">codigo fuente del proyecto</a> para efectos de estudio. Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com2tag:blogger.com,1999:blog-4234304323727536894.post-80123320722569091732011-09-26T14:52:00.000-07:002011-10-06T10:37:34.755-07:00Spring 3.0 y JSF 2.0<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-CJD_pMxGSFA/ToDzxcewjzI/AAAAAAAABxY/IYMkqttCX0A/s1600/spring_logo.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" kca="true" src="http://2.bp.blogspot.com/-CJD_pMxGSFA/ToDzxcewjzI/AAAAAAAABxY/IYMkqttCX0A/s1600/spring_logo.jpg" /></a></div>
<div style="text-align: justify;">
Hace poco me había planteado la necesidad de utilizar una capa de servicios potente como EJB 3.0 pero sin utilizar un servidor de aplicaciones sino un simple tomcat, ya que este no es un contenedor de EJB. Así que me decidi por la combinación <a href="http://krypto84sv.blogspot.com/2011/09/spring-30-e-hibernate-jpa-20.html">Spring 3.0 y JSF 2.0</a>, la reseta de implementación JPA 2.0 para Spring utilizare Hibernate. Aca desarrollare un ejemplo de como utilizar las dos tecnologías antes mencionadas. Antes que nada es necesario configurar un datasource el cual accederemos desde spring vía jndi, para el ejemplo accederemos a la base de datos derby que esta embebida con netbeans. En el archivo contex.xml del tomcat creamos el datasource.</div>
<textarea class="xml:collapse" name="code"><Resource name="jdbc/derby" auth="Container"
type="javax.sql.DataSource" driverClassName="org.apache.derby.jdbc.ClientDriver"
url="jdbc:derby://localhost:1527/sample"
username="app" password="app" maxActive="20" maxIdle="10" maxWait="-1"/>
</textarea> <br />
Ahora procedemos con la capa de acceso a datos <a href="http://krypto84sv.blogspot.com/2008/11/introduciendo-al-uso-de-persistencia-de.html">generando los entities de las tablas</a> "customer" y "discount_code". Modificamos el archivo persistence.xml que debera quedar de la siguiente manera: <textarea class="xml:collapse" name="code"><?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="SpringWebPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source/>
<class>org.dani.ejemplo.beans.Customer</class>
<class>org.dani.ejemplo.beans.DiscountCode</class>
<exclude-unjava.util.Listed-classes>true</exclude-unjava.util.Listed-classes>
<properties/>
</persistence-unit>
</persistence>
</textarea> <br />
Creare la interfaz con la con la cual las transacciones de spring funcionaran<br />
<textarea class="java:collapse" name="code">package org.dani.ejemplo.dao;
import java.util.*;
import org.dani.ejemplo.beans.*;
/**
*
* @author dherrera
*/
public interface DerbyDAO {
java.util.List<org.dani.ejemplo.beans.Customer> getAllCustomers();
}
</textarea> <br />
Luego creo la implementación<br />
<textarea class="java:collapse" name="code">package org.dani.ejemplo.dao;
import java.util.java.util.List;
import org.dani.ejemplo.beans.Customer;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author dherrera
*/
public class DerbyDAOImpl extends JpaDaoSupport implements DerbyDAO{
@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=true)
public java.util.List<Customer> getAllCustomers() {
return getJpaTemplate().find("select c from Customer c");
}
}
</textarea><br />
El siguiente paso es configurar el archivo de spring applicationContex.xml en la ubicación WEB-INF <textarea class="xml:collapse" name="code"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
<!-- Acceso a datos -->
<bean id="dao" class="org.dani.ejemplo.dao.DerbyDAOImpl">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- Datasource configurado en contex.xml de Tomcat-->
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/derby"/>
<!-- Configurando el entityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="SpringWebPU"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<!-- Utilizado para utilizar la anotación @Transactional-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Configurando el transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
</textarea> <br />
Ahora vamos con la parte de la vista. Se debe configurar el proyecto web para que JSF pueda interactuar con Spring. Se agregan las siguientes líneas en el archivo web.xml:<br />
<textarea class="xml:collapse" name="code"><java.util.Listener>
<java.util.Listener-class>org.springframework.web.context.ContextLoaderjava.util.Listener</java.util.Listener-class>
</java.util.Listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
</textarea><br />
Luego se debe configurar el archivo faces-config.xml para que spring pueda realizar inyección de dependencias a través de el lenguaje de extextareasiones de JSF, se debe crear sino existe. <textarea class="xml:collapse" name="code"><?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
<resource-bundle>
<base-name>org.dani.ejemplo.web.msg.bundle</base-name>
<var>msg</var>
</resource-bundle>
</application>
</faces-config>
</textarea> <br />
Luego creo el managed bean<br />
<textarea class="java:collapse" name="code">package org.dani.ejemplo.web;
import java.util.java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.dani.ejemplo.beans.Customer;
import org.dani.ejemplo.dao.DerbyDAO;
/**
*
* @author dherrera
*/
@ManagedBean
@ViewScoped
public class BeanManager {
@ManagedProperty("#{dao}") //id del bean DerbyDAO
private DerbyDAO dao;
private java.util.List<Customer> customers;
@PostConstruct
public void init() {
customers=dao.getAllCustomers();
}
// <editor-fold defaultstate="collapsed" desc="Propiedades">
public void setDao(DerbyDAO dao) {
this.dao = dao;
}
public java.util.List<Customer> getCustomers() {
return customers;
}
public void setCustomers(java.util.List<Customer> customers) {
this.customers = customers;
}
// </editor-fold>
}
</textarea> <br />
Por ultimo desplegamos la java.util.Lista "customers" del managed bean en nuestra página xhtml <textarea class="xml:collapse" name="code"><?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>#{msg['jsf.titulo']}</title>
</h:head>
<h:body>
<h:form>
<h2>#{msg['jsf.titulo']}</h2>
<h:dataTable value="#{beanManager.customers}" var="c" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="#{msg['customer.label.name']}"/>
</f:facet>
<h:outputText value="#{c.name}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg['customer.label.email']}"/>
</f:facet>
<h:outputText value="#{c.email}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg['customer.label.state']}"/>
</f:facet>
<h:outputText value="#{c.state}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{msg['discountcode.label.code']}"/>
</f:facet>
<h:outputText value="#{c.discountCode.discountCode}"/>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
</textarea> <br />
El resultado sera el siguiente <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-DLtMbpPa6_I/ToDydRd0P6I/AAAAAAAABxU/iX21pIW9V6I/s1600/resultado.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="http://4.bp.blogspot.com/-DLtMbpPa6_I/ToDydRd0P6I/AAAAAAAABxU/iX21pIW9V6I/s320/resultado.png" width="320" /></a></div>
Adjunto el <a href="http://www.mediafire.com/?xlz4q6yv06l6i39">código fuente</a> para efectos de estudio. Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com1tag:blogger.com,1999:blog-4234304323727536894.post-77255667269335617782011-09-24T21:06:00.000-07:002011-10-07T13:07:55.172-07:00Swing Beans Binding JSR 295<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-OTnYPPJFjvE/Tn6oLpyLGrI/AAAAAAAABxI/AgZm1rqcj0A/s1600/lg_Java+Logo.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-OTnYPPJFjvE/Tn6oLpyLGrI/AAAAAAAABxI/AgZm1rqcj0A/s1600/lg_Java+Logo.JPG" /></a></div>
<div style="text-align: justify;">
Siempre me había llamado la atención poder enlazar componentes de swing con algún objeto o lista de objetos de manera similar a como se realiza con JSF. Este no es un tema nuevo ya que se puede realizar desde ya hace bastante pero la mayoria de personas (al menos las que programan aplicaciones de escritorio en java) lo desconocen.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En esta ocasión realizare un ejemplo basandome en la entrada anterior sobre <a href="http://krypto84sv.blogspot.com/2011/09/spring-30-e-hibernate-jpa-20.html">Spring 3.0 e Hibernate</a>, en el cual ya he generado el acceso a datos.</div>
<br />
El ejemplo que desarrollare sera un pequeño CRUD e utilizare las herramientas Netbeans 7.0, Spring 3.0 e Hibernate 3.6.7<br />
<br />
Mi clase de acceso a datos es la siguiente:<br />
<br />
<pre class="java" name="code">package org.dani.ejemplo.jpa.dao;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import java.util.*;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
*
* @author dherrera
*/
public class DerbyDAOImpl extends JpaDaoSupport implements DerbyDAO{
@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
public List<product> getAllProducts() {
return getJpaTemplate().find("Select p From Product p order by p.productId desc");
}
@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
public List<manufacturer> getAllManufacturer() {
return getJpaTemplate().find("Select m From Manufacturer m");
}
@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
public List<productcode> getAllProductCode() {
return getJpaTemplate().find("Select p From ProductCode p");
}
@Transactional(propagation=Propagation.REQUIRES_NEW,readOnly=false)
public Product updateProduct(Product p) {
return getJpaTemplate().merge(p);
}
public Integer getNewProductId() {
javax.persistence.EntityManager em=getJpaTemplate().getEntityManagerFactory().createEntityManager();
javax.persistence.Query q=em.createQuery("select max(p.productId)+1 from Product p", Integer.class);
return (Integer) q.getSingleResult();
}
@Transactional(propagation=Propagation.REQUIRES_NEW,readOnly=false)
public Product addProduct(Product p) {
return updateProduct(p);
}
@Transactional(propagation=Propagation.REQUIRES_NEW,readOnly=false)
public void deleteProduct(final Product p) {
getJpaTemplate().remove(getJpaTemplate().getReference(Product.class, p.getProductId()));
}
}
</productcode></manufacturer></product></pre>
<br />
<br />
<div style="text-align: justify;">
Obtengo las listas de tipo observable de productos y listas simples para manufacteros y códigos de producto con sus respectivos getters y setters para que los componentes dentro del formulario principal FrameBinding.java puedan accesar a ellas en el contructor del formulario.</div>
<br />
<pre class="java" name="code">public FrameBinding() {
ctx = new ClassPathXmlApplicationContext("/org/dani/ejemplo/jpa/applicationContext.xml");
dao = (DerbyDAO) ctx.getBean("dao");
fillModelTable();
manufacturers=dao.getAllManufacturer();
productCodes=dao.getAllProductCode();
initComponents();
actions();
}
private void fillModelTable() {
if (products!=null) {
products.clear();
products.addAll(dao.getAllProducts());
}
else products=ObservableCollections.observableList(dao.getAllProducts());
}
</pre>
<br />
Antes que nada es necesario modificar el entity Product.java añadiendole lo siguiente:<br />
<br />
<pre class="java" name="code">@Transient
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
</pre>
<br />
<br />
<div style="text-align: justify;">
Y para cada setter de las propiedades agregar el FirePropertyChange, esto es para efectos de poder utilizar una lista observable para que la tabla siempre pueda saber cuando cambia una propiedad de la lista de productos que utilizamos.</div>
<br />
<pre class="java" name="code">public void setManufacturer(Manufacturer manufacturer) {
Manufacturer old=this.manufacturer;
this.manufacturer = manufacturer;
changeSupport.firePropertyChange("manufacturer", old, manufacturer);
}
</pre>
<br />
<br />
Por ultimo tambien creo una propiedad transient para efectos de utilizarla en un JComboBox como se explicara mas adelante.<br />
<br />
<pre class="java" name="code">public boolean getBooleanAvailable() {
return available!=null && !available.isEmpty() && available.equals("TRUE");
}
public void setBooleanAvailable(boolean res) {
String old=this.available;
available=res?"TRUE":"FALSE";
changeSupport.firePropertyChange("booleanAvailable", old, available);
}
</pre>
<br />
<br />
Todo esto es necesario hacerlo ya que en una clase Entity no se puede utilizar la anotación @Bindable antes del nombre de la clase y esta realiza automaticamente lo anterior expuesto y así poder utilizar el pojo en una ObservableList.<br />
<br />
El diseño del formulario seria el siguiente:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-fMH4L0ydMOk/Tn6lCGT6qqI/AAAAAAAABws/HwmVcnQJrNo/s1600/dise%25C3%25B1o_formulario.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="98" src="http://2.bp.blogspot.com/-fMH4L0ydMOk/Tn6lCGT6qqI/AAAAAAAABws/HwmVcnQJrNo/s320/dise%25C3%25B1o_formulario.png" width="320" /></a></div>
<br />
<br />
Luego en vista de diseño del formulario doy clic derecho a la tabla, selecciono propiedades y elijo la sección "binding" edito la propiedad "elements" y lo lleno con la lista de productos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-g6XNdrA4tqc/Tn6lijz82LI/AAAAAAAABww/pSDg1xJL4Ew/s1600/element_products.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/-g6XNdrA4tqc/Tn6lijz82LI/AAAAAAAABww/pSDg1xJL4Ew/s320/element_products.png" width="296" /></a></div>
<br />
Luego realizo de la misma manera el binding de la propiedad "selected" en propiedades>binding de la caja de texto, apunto hacia la propiedad virtual "selected" de la tabla que es de tipo Product y luego selecciono "description"<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-IfiozlBa12U/Tn6l44ytS6I/AAAAAAAABw0/0emN8xjemv8/s1600/description_jtextbox.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://2.bp.blogspot.com/-IfiozlBa12U/Tn6l44ytS6I/AAAAAAAABw0/0emN8xjemv8/s320/description_jtextbox.png" width="294" /></a></div>
<br />
<br />
Luego hago lo mismo con el checkbox solamente que ahora en lugar de apuntar a la propiedad "description" del elemento seleccionado de la tabla lo haré a la propiedad "booleanAvailable".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-zjIbLPlBSsU/Tn6mCS8oZoI/AAAAAAAABw4/T7BkSHNEf_Y/s1600/boolean_combo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://4.bp.blogspot.com/-zjIbLPlBSsU/Tn6mCS8oZoI/AAAAAAAABw4/T7BkSHNEf_Y/s320/boolean_combo.png" width="294" /></a></div>
<br />
<br />
Luego para los combos se hace similar que una tabla seleccionando la lista que le corresponde a cada jcombobox, por ejemplo para el combo de Manufacturer se selecciona la lista de manufacturers que se encuentra en el formulario para su propiedad elements.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-CGqcNO1tqC4/Tn6mue8uSjI/AAAAAAAABw8/IV3xFW2pJE4/s1600/elements_combo_manufacturer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/-CGqcNO1tqC4/Tn6mue8uSjI/AAAAAAAABw8/IV3xFW2pJE4/s320/elements_combo_manufacturer.png" width="294" /></a></div>
<br />
<br />
Y para elegir el elemento seleccionado por defecto apuntamos la propiedad virtual "selectedItem" hacia "selected" de la tabla.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-dSRdJSW6juk/Tn6n4V5CtAI/AAAAAAAABxE/BMyHxR3P7EQ/s1600/selected.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/-dSRdJSW6juk/Tn6n4V5CtAI/AAAAAAAABxE/BMyHxR3P7EQ/s320/selected.png" width="294" /></a></div>
<br />
<br />
Se realiza el mismo procedimiento para el combo de códigos de producto solamente con la variante que se escoge la lista de product_code del formulario.<br />
<br />
Se puede jugar con otras propiedades, así como por ejemplo para los botones hice el enlace para la propiedad enable, para que se valide que los botones de Actualizar y borrar solamente esten activos cuando se haya seleccionado un item de la tabla.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-CY8l226LtiQ/Tn6m1pyHWfI/AAAAAAAABxA/NTj21YQC9IE/s1600/enable_botones.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-CY8l226LtiQ/Tn6m1pyHWfI/AAAAAAAABxA/NTj21YQC9IE/s320/enable_botones.png" width="294" /></a></div>
<br />
<br />
Por ultimo agrego el código de CRUD habitual en los demás botones.<br />
<br />
<pre class="java" name="code">private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
dao.updateProduct(selected);
fillModelTable();
javax.swing.JOptionPane.showMessageDialog(this, "Actualizado");
}
private void btnNuevoActionPerformed(java.awt.event.ActionEvent evt) {
Integer id=dao.getNewProductId();
Product nuevo=new Product();
nuevo.setProductId(id);
nuevo.setDescription(txtDescripcion.getText());
nuevo.setManufacturer((Manufacturer) comboManufacturer.getSelectedItem());
nuevo.setProductCode((ProductCode) comboProductCode.getSelectedItem());
nuevo.setBooleanAvailable(checkAvailable.isSelected());
selected=dao.addProduct(nuevo);
fillModelTable();
}
private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {
try {
dao.deleteProduct(selected);
fillModelTable();
}
catch (DataIntegrityViolationException e) {
javax.swing.JOptionPane.showMessageDialog(this, "El producto tiene orden de compra (tabla PURCHASE_ORDER)");
}
}
</pre>
<br />
Aca el ejemplo en tiempo de ejecución.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-c8j1h4OxuDg/Tn6s2urX1hI/AAAAAAAABxM/-XgCHW3zLIQ/s1600/ejecucion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="http://2.bp.blogspot.com/-c8j1h4OxuDg/Tn6s2urX1hI/AAAAAAAABxM/-XgCHW3zLIQ/s320/ejecucion.png" width="320" /></a></div>
<br />
<br />
Adjunto <a href="http://www.mediafire.com/?k7dq277yvmks6lb">el ejemplo</a> para efectos de estudio.<br />
<br />Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-7757121974800178902011-09-19T13:08:00.000-07:002011-10-07T13:09:44.073-07:00Spring 3.0 e Hibernate JPA 2.0<a href="http://1.bp.blogspot.com/-8gDly8OHVDs/TnevcgNBytI/AAAAAAAABwE/yx863pM3Aio/s1600/hibernate_logo.gif"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5654180761402723026" src="http://1.bp.blogspot.com/-8gDly8OHVDs/TnevcgNBytI/AAAAAAAABwE/yx863pM3Aio/s320/hibernate_logo.gif" style="cursor: hand; float: left; height: 63px; margin: 0px 10px 10px 0px; width: 220px;" /></a> Hace unos días me decici a integrar Spring con la implementacion JPA 2.0 de Hibernate. En esta ocasión la versión de spring que usare es la 3.0 de Hibernate 3.6.7 y la base de datos de ejemplo (derby - sample) que se encuentra embebida en Netbeans.<br />
<br />
Los jars necesarios para utilizar la implementación JPA de Hibernate, en donde {hibernate-path} es la ruta donde esta descomprimido la distribución final de Hibernate 3.6.7:<br />
<br />
<div>
<pre class="javascript" name="code">{hibernate-path}\lib\jpa\hibernate-jpa-2.0-api-1.0.1.Final.jar
{hibernate-path}\lib\required\antlr-2.7.6.jar
{hibernate-path}\lib\required\commons-collections-3.1.jar
{hibernate-path}\lib\required\dom4j-1.6.1.jar
{hibernate-path}\lib\required\javassist-3.12.0.GA.jar
{hibernate-path}\lib\required\jta-1.1.jar
{hibernate-path}\lib\required\slf4j-api-1.6.1.jar
{hibernate-path}\hibernate3.jar</pre>
<br />
Como nota aclaratoria es tambien necesario agregar el jar <strong>aopalliance.jar</strong> para poder utilizar la anotación @Transactional, en este ejemplo no realizaremos un CRUD por esa razón no se incluye.<br />
<br />
<br />
Y la versión 3.0 de Spring que viene con Netbeans.<br />
<br />
Las tablas que utilizare son "Product", "Manufacturer" y "Product_Code", al mapear las tablas con el asistente de Netbeans obtengo sus clases<br />
<br />
La unidad de persistencia debera quedar de la siguiente forma:<br />
<br />
<pre class="xml" name="code"><persistence schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xsi="http://www.w3.org/2001/XMLSchema-instance">
<persistence-unit name="JpaSpringPU" type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.dani.ejemplo.jpa.dao.ProductCode</class>
<class>org.dani.ejemplo.jpa.dao.Product</class>
<class>org.dani.ejemplo.jpa.dao.Manufacturer</class>
<properties></properties>
</persistence-unit></persistence>
</pre>
<br />
<br />
Creo el acceso a datos para las tablas.<br />
<br />
<pre class="java" name="code">package org.dani.ejemplo.jpa.dao;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import java.util.*;
/**
*
* @author dherrera
*/
public class DerbySampleDAO extends JpaDaoSupport{
public List<product> getAllProducts() {
return getJpaTemplate().find("Select p From Product p");
}
}</pre>
<br />
<br />
Luego procedo a configurar el archivo de configuración de spring<br />
<pre class="xml" name="code"><beans aop="http://www.springframework.org/schema/aop" schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" xmlns="http://www.springframework.org/schema/beans" xsi="http://www.w3.org/2001/XMLSchema-instance">
<bean class="org.dani.ejemplo.jpa.dao.DerbySampleDAO" id="dao">
<property name="entityManagerFactory" ref="entityManagerFactory"></property></bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"></property>
<property name="persistenceUnitName" value="JpaSpringPU"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"></property>
<property name="generateDdl" value="false"></property>
</bean>
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"></bean>
</property></bean>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"></property>
<property name="url" value="jdbc:derby://localhost:1527/sample"></property>
<property name="username" value="app"></property>
<property name="password" value="app"></property></bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
<property name="dataSource" ref="dataSource"></property></bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"></bean>
</beans>
</pre>
<br />
<br />
<br />
Y la forma de uso sera de la siguiente forma:<br />
<br />
<pre class="java" name="code">package org.dani.ejemplo.jpa;
import java.util.List;
import org.dani.ejemplo.jpa.dao.DerbySampleDAO;
import org.dani.ejemplo.jpa.dao.Product;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* @author dherrera
*/
public class Init {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("/org/dani/ejemplo/jpa/applicationContext.xml");
DerbySampleDAO dao=(DerbySampleDAO) ctx.getBean("dao");
List<product> list=dao.getAllProducts();
for(Product product:list)
System.out.println(product.getDescription());
}
}</pre>
<br />
Adjunto el código <a href="http://www.mediafire.com/?o6r8zn6u9ues6km">fuente de ejemplo aca</a>.</div>
Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-90858822742531968102011-09-10T13:18:00.000-07:002011-09-10T14:40:17.728-07:00Ejecutar un reporte alojado en JasperServer<a href="http://1.bp.blogspot.com/-sQxDgeOko1Q/TmvGxNY7r-I/AAAAAAAABv8/Z_2tj2DTQc4/s1600/jasperservericon.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 250px; height: 57px;" src="http://1.bp.blogspot.com/-sQxDgeOko1Q/TmvGxNY7r-I/AAAAAAAABv8/Z_2tj2DTQc4/s320/jasperservericon.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5650828706176544738" /></a>Tengo ya bastante de no realizar un post en el blog, pero ahora que dispongo de tiempo quiero compartir la forma en como se ejecuta un reporte alojado en Jasper Server, a través de su webservice.<div><br /></div><div>Para efectos de prueba tengo creada una tabla sobre postgresql con la siguiente estructura:</div><div><pre name="code" class="sql">CREATE TABLE contact<br />(<br />id serial NOT NULL,<br />first_name character varying(50),<br />last_name character varying(50),<br />CONSTRAINT pk_contact PRIMARY KEY (id)<br />);<br /><br />CREATE TABLE address<br />(<br />id serial NOT NULL,<br />street character varying(50),<br />fk_contact integer NOT NULL,<br />CONSTRAINT pk_address PRIMARY KEY (id),<br />CONSTRAINT address_contact FOREIGN KEY (fk_contact)<br />REFERENCES contact (id) MATCH SIMPLE<br />ON UPDATE NO ACTION ON DELETE NO ACTION<br />);<br />CREATE TABLE phone<br />(<br />id serial NOT NULL,<br />"number" character varying(10),<br />fk_contact integer NOT NULL,<br />CONSTRAINT pk_phone PRIMARY KEY (id),<br />CONSTRAINT phone_contact FOREIGN KEY (fk_contact)<br />REFERENCES contact (id) MATCH SIMPLE<br />ON UPDATE NO ACTION ON DELETE NO ACTION<br />);<br /></pre>Y he creado el siguiente reporte a traves de iReport:<br /><pre name="code" class="xml"><!--?xml version="1.0" encoding="UTF-8"?--><br /><jasperreport xmlns="http://jasperreports.sourceforge.net/jasperreports" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report_query" language="groovy" pagewidth="595" pageheight="842" columnwidth="555" leftmargin="20" rightmargin="20" topmargin="20" bottommargin="20"><br /><property name="ireport.zoom" value="1.0"><br /><property name="ireport.x" value="0"><br /><property name="ireport.y" value="0"><br /><parameter name="id" class="java.lang.Integer"><br /><querystring><br /><!--[CDATA[SELECT C.FIRST_NAME, C.LAST_NAME, AD.STREET, PH.NUMBER FROM CONTACT C INNER JOIN ADDRESS AD ON C.ID=AD.FK_CONTACT INNER JOIN PHONE PH ON PH.FK_CONTACT=C.ID WHERE C.ID=$P{id}]]--><br /></querystring><br /><field name="first_name" class="java.lang.String"><br /><field name="last_name" class="java.lang.String"><br /><field name="street" class="java.lang.String"><br /><field name="number" class="java.lang.String"><br /><background><br /><band splittype="Stretch"><br /></band></background><br /><title><br> <band height="79" splitType="Stretch"><br> <staticText><br> <reportElement x="181" y="31" width="192" height="20"/><br> <textElement textAlignment="Center"/><br> <text><![CDATA[REPORTE DE PRUEBA]]></text><br> </staticText><br> </band><br> </title><br /><pageheader><br /><band height="35" splittype="Stretch"><br /></band></pageheader><br /><columnheader><br /><band height="20" splittype="Stretch"><br /><textfield><br /><reportelement x="0" y="0" width="100" height="20"><br /><textelement><br /><textfieldexpression><!--[CDATA[$F{first_name}]]--></textfieldexpression><br /></textelement></reportelement></textfield><br /><textfield><br /><reportelement x="100" y="0" width="100" height="20"><br /><textelement><br /><textfieldexpression><!--[CDATA[$F{last_name}]]--></textfieldexpression><br /></textelement></reportelement></textfield><br /><textfield><br /><reportelement x="200" y="0" width="100" height="20"><br /><textelement><br /><textfieldexpression><!--[CDATA[$F{street}]]--></textfieldexpression><br /></textelement></reportelement></textfield><br /><textfield><br /><reportelement x="300" y="0" width="100" height="20"><br /><textelement><br /><textfieldexpression><!--[CDATA[$F{number}]]--></textfieldexpression><br /></textelement></reportelement></textfield><br /></band><br /></columnheader><br /><detail><br /><band height="125" splittype="Stretch"><br /></band></detail><br /><columnfooter><br /><band height="45" splittype="Stretch"><br /></band></columnfooter><br /><pagefooter><br /><band height="54" splittype="Stretch"><br /></band></pagefooter><br /><summary><br /><band height="42" splittype="Stretch"><br /></band></summary><br /></field></field></field></field></parameter></property></property></property></jasperreport><br /></pre><br /><br />Luego de subir y configurar debidamente el reporte en Jasper Server (leer la documentacion de Jasper Server) procedemos a crear el cliente.<br /><br /></div><div>Antes que nada debemos de tener claro todas las librerias que se requiren para el cometido, yo las he tomado de mi instalación de iReport 4.1.1, tomaremos como base que <ireport-install> es la ruta de instalación de iReport en nuestro equipo que le llamare {ireport-install} <ireport-install>, tambien se necesitan dos librerias alojadas de la instalación del Jasper Server en el tomcat o servidor de aplicaciones donde se encuentre a esta ruta le denominare {js-install}<js-install></js-install></ireport-install></ireport-install></div><div><br /></div><div><ireport-install></ireport-install></div><br /><pre name="code" class="js">{ireport-install}/ireport/modules/ext/js_activation-1.1.jar<br />{ireport-install}/ireport/modules/ext/js_axis-1.4patched.jar<br />{ireport-install}/ireport/modules/ext/js_commons-codec-1.3.jar<br />{ireport-install}/ireport/modules/ext/js_commons-discovery-0.2.jar<br />{ireport-install}/ireport/modules/ext/js_commons-httpclient-3.1.jar<br />{ireport-install}/ireport/modules/ext/js_jasperserver-common-ws-3.5.0.jar<br />{ireport-install}/ireport/modules/ext/js_jaxrpc.jar<br />{ireport-install}/ireport/modules/ext/js_mail-1.4.jar<br />{ireport-install}/ireport/modules/ext/js_saaj-api-1.3.jar<br />{ireport-install}/ireport/modules/ext/js_wsdl4j-1.5.1.jar<br />{ireport-install}/ireport/modules/com-jaspersoft-ireport-jasperserver.jar<br />{ireport-install}/ireport/modules/com-jaspersoft-ireport.jar<br />{ireport-install}/ireport/modules/ext/jasperreports-4.1.1.jar<br />{ireport-install}/platform9/lib/org-openide-util.jar<br />{ireport-install}/ide10/modules/ext/xerces-2.8.0.jar<br />{js-install}/WEB-INF/lib/jasperserver-api-metadata-4.1.0.jar<br />{js-install}/WEB-INF/lib/jasperserver-api-metadata-impl-4.1.0.jar<br /></pre><br /><br />Yo me cree una libreria en netbeans la cual denomine JSClient en el cual inclui todos esos jars. Procedi a crear mi clase JasperServerClient.java:<br /><pre name="code" class="java">package org.dani.jasper.server.ws.client;<br /><br />import com.jaspersoft.ireport.jasperserver.JServer;<br />import com.jaspersoft.jasperserver.api.metadata.xml.domain.impl.ResourceDescriptor;<br />import net.sf.jasperreports.engine.JasperPrint;<br />/**<br />*<br />* @author Daniel Alberto<br />*/<br />public class JasperServerClient {<br /><br />private static String WEBSERVICE_URL="http://localhost:8080/jasperserver/services/repository";<br />private static String USER="jasperadmin";<br />private static String PASS="jasperadmin";<br /><br />private JServer server;<br /><br />public JasperServerClient() {<br /> server=new JServer();<br /> server.setUrl(JasperServerClient.WEBSERVICE_URL);<br /> server.setUsername(JasperServerClient.USER);<br /> server.setPassword(JasperServerClient.PASS); <br />}<br /><br />public JasperPrint runReport(String uri,java.util.Map parameters) throws Exception {<br /> ResourceDescriptor rd=new ResourceDescriptor();<br /> rd.setWsType(ResourceDescriptor.TYPE_REPORTUNIT);<br /> rd.setUriString(uri);<br /> return server.getWSClient().runReport(rd, parameters);<br />}<br />}<br /></pre><br /><br />Luego utilizo el cliente:<br /><pre name="code" class="java">package org.dani.jasper.server.client;<br /><br />import org.dani.jasper.server.ws.client.JasperServerClient;<br />import java.util.*;<br />import net.sf.jasperreports.engine.JasperPrint;<br />import net.sf.jasperreports.view.JasperViewer;<br /><br />/**<br />*<br />* @author Daniel Alberto<br />*/<br />public class Principal {<br /><br />private JasperServerClient client=new JasperServerClient();<br /><br />public static void main(String[] args) throws Exception {<br /> Principal p=new Principal();<br /> p.runReportQuery(); <br />}<br /><br />public void runReportQuery() throws Exception {<br /> String report="/reports/report_query";<br /> Map params=new HashMap();<br /> params.put("id", 1);<br /> JasperPrint print=client.runReport(report, params);<br /> JasperViewer.viewReport(print);<br />}<br /><br />}<br /></pre><br /><br />Si aparece una advertencia en tiempo de ejecucion que dice: ADVERTENCIA: NetBeans implementation of Preferences not found: java.lang.Exception, hacer caso omiso.<br /><br />Luego se mostrar el reporte de forma satisfactoria. Pueden descargar el ejemplo a traves de <a href="http://www.mediafire.com/?44f0i84dsupps4g">este link</a>.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com2tag:blogger.com,1999:blog-4234304323727536894.post-75880648837595452832010-08-12T22:48:00.000-07:002010-08-12T22:53:53.337-07:00VisualSwing4Eclipse: al fin Swing sobre Eclipse<a href="http://4.bp.blogspot.com/_tPLVjrBRifE/TGTc69hSHfI/AAAAAAAABvY/0HWzotNcKmM/s1600/logo.png"><img src="http://4.bp.blogspot.com/_tPLVjrBRifE/TGTc69hSHfI/AAAAAAAABvY/0HWzotNcKmM/s320/logo.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5504767550058274290" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 110px; height: 80px; " /></a><div style="text-align: justify;">Ya sé, ya sé, tengo un revergo de no escribir pero no queria dejar pasar la oportunidad de al menos dar a conocer que al fin hay diseñador de interfaces swing para eclipse completamente gratis, sí así es, completamente gratis.</div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">El proyecto se denomina <a href="http://code.google.com/p/visualswing4eclipse/">visualswing4eclipse</a> es un plugin que funciona para las versiones de Eclipse 3.3 en adelante, es decir que incluso funciona perfectamente con la nueva versión de Eclipse Helios.</div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">Adjunto una captura de pantalla de mi eclipse helios</div><div><br /></div><div><a href="http://1.bp.blogspot.com/_tPLVjrBRifE/TGTddekNszI/AAAAAAAABvg/hOXKmVSaqi8/s1600/SwingDesigner4Eclipse.PNG"><img src="http://1.bp.blogspot.com/_tPLVjrBRifE/TGTddekNszI/AAAAAAAABvg/hOXKmVSaqi8/s320/SwingDesigner4Eclipse.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5504768143044490034" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 320px; height: 193px; " /></a></div><div style="text-align: center;"><span class="Apple-style-span" style="font-size: x-small;">Click para agrandar</span></div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">Me alegra que al fin puedo diseñar mis interfaces Swing tener que usar netbeans.</div>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com7tag:blogger.com,1999:blog-4234304323727536894.post-83126597091854831022009-10-22T21:47:00.001-07:002009-10-22T22:05:18.776-07:00Combate mortal con Nexuiz<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://cyphergaming.net/database/upload/nexuiz_logo.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 107px; height: 103px;" src="http://cyphergaming.net/database/upload/nexuiz_logo.jpg" alt="" border="0" /></a>Hace unos días la mara del trabajo me ha enviciado con el juego Unreal Tournament, así que era mi obligación encontrar algún juego similar de combate en primera persona, de buena calidad y sobre todo que fuera software libre.<br /><br />Pues googleando por alli me tope con <a href="http://www.alientrap.org/nexuiz/">Nexuiz</a> que practimente parece una copia de Unreal, pero que es lo mas importante que nos ofrece <a href="http://www.alientrap.org/nexuiz/">Nexuiz</a>?<br /><ul><li>Esta disponible para Windows, GNU/Linux y Mac OS X.</li><li>Es multijugador soporta hasta 64 jugadores simultaneamente.</li><li>Puede realizarse batallas con bots.</li></ul><br />¿Como obtenerlo?<br /><br />Si utilizan sistemas basados en Debian así como Ubuntu, el juego esta disponible desde los mismos repositorios y se intala haciendo nada mas:<br /></div><br /><span style="font-weight: bold;"># apt-get install nexuiz</span><br /><br /><div style="text-align: justify;">Solo hay un detalle, que la versión que esta en los repositorios es la 2.4.2, pero si lo descargamos directamente desde la página tendremos la versión 2.5.2, al descargarlo directamente desde la página tendremos una archivo que pesa aproximadamente casi 1 GB pero allí viene incluidas los ejecutables para las diferentes plataformas anteriormente mencionadas, nomas consiste en descomprimir y jugar eso es todo.<br /><br />Así que invito a que descarguen el juego para darnos riata, adjunto un video para que se entusiasmen.<br /></div><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/4E5kRPp9m3E&hl=es&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/4E5kRPp9m3E&hl=es&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com11tag:blogger.com,1999:blog-4234304323727536894.post-22080863334051949342009-10-04T12:27:00.000-07:002009-10-04T17:40:23.273-07:00EJB: Usando consultas SQL nativas<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/Ssj3TR5CSlI/AAAAAAAABuo/8LsMX0JIm_s/s1600-h/java_logo.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 72px; height: 134px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/Ssj3TR5CSlI/AAAAAAAABuo/8LsMX0JIm_s/s320/java_logo.png" alt="" id="BLOGGER_PHOTO_ID_5388828864741001810" border="0" /></a>Cuando hablamos de <a href="http://www.google.com.sv/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fes.wikipedia.org%2Fwiki%2FEnterprise_JavaBeans&ei=cvjISofmHcG1lAf4yqmSAw&rct=j&q=ejb+wiki&usg=AFQjCNHCvnMYDHFpjol_Gie81tsMbE2Jnw">EJB (Enterprise JavaBeans)</a> indudablemente tenemos que hablar sobre <a href="http://krypto84sv.blogspot.com/2008/11/introduciendo-al-uso-de-persistencia-de.html">JPA</a>.<br /><br />Siempre me ha parecido algo rigido el hecho de tener que usar consultas <a href="http://www.google.com.sv/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fedocs.beasys.com%2Fkodo%2Fdocs41%2Ffull%2Fhtml%2Fejb3_langref.html&ei=3PjISuHcMJKnlAfU9rGSAw&rct=j&q=jpql&usg=AFQjCNHjVK46Nokg9lT_PFkCRUKuzJThbg">JPQL</a> para generar mis Entity Class, aunque estar este tipo de consultar resulta beneficioso a la hora de cambiar de base de datos completamente ya que para la base de datos es transparente el <a href="http://www.google.com.sv/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fedocs.beasys.com%2Fkodo%2Fdocs41%2Ffull%2Fhtml%2Fejb3_langref.html&ei=3PjISuHcMJKnlAfU9rGSAw&rct=j&q=jpql&usg=AFQjCNHjVK46Nokg9lT_PFkCRUKuzJThbg">JPQL</a>. y aporta mucho a a la portabilidad del código con respecto a la base de datos.<br /><br />Pero en ocasiones necesitamos hacer uso de caracteristicas propias de la base datos para crear consultas mas complejas y nos vemos limitados por el <a href="http://www.google.com.sv/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fedocs.beasys.com%2Fkodo%2Fdocs41%2Ffull%2Fhtml%2Fejb3_langref.html&ei=3PjISuHcMJKnlAfU9rGSAw&rct=j&q=jpql&usg=AFQjCNHjVK46Nokg9lT_PFkCRUKuzJThbg">JPQL</a> entonces vemos la necesidad de utilizar consultas SQL nativas y a la vez son mucho más rapidas que las JPQL.<br /><br />¿Como se utilizan?<br /><br />Se podría decir que la sintaxis es la siguiente:<br /><br /><span style="font-size:85%;"><span style="font-weight: bold;">Query createNativeQuery(String sql, Class entityClass)</span></span><br /><br />Donde:<br /><br /><span style="font-weight: bold;">Parametro uno: String sql</span><br />Es la consulta SQL nativa en el cual deben de ir los campos que conformaran nuestra Entity Class.<br /><br /><span style="font-weight: bold;">Parametro dos: Class entityClass</span><br />Es la Entity Class resultante de la consulta nativa SQL.<br /><br />Ahora como siempre recalco, es tipico de este blog desarrollar un pequeño ejemplito de uso.<br /><br />Asumiendo, ya tenemos generadas nuestra Entity Class llamada Persona procedremos a generar una lista de "personas".<br /><br /><span style="font-size:78%;"><span style="font-weight: bold;">EntityManagerFactory emf=Persistence.createEntityManagerFactory("nombreUnidadPersistencia");</span><br /></span><pre style="font-weight: bold;"><span style="font-size:78%;"><a name="IDX-CHP-9-1419"></a></span></pre><span style="font-size:78%;"><span style="font-weight: bold;">EntityManager em=em.createEntityManager();</span><br /><span style="font-weight: bold;">String consulta="select * from persona";</span><br /><span style="font-weight: bold;">Query q=em.createNativeQuery(consulta,com.paquete.modelo.Persona.class);</span><br /><span style="font-weight: bold;">Persona[] personas=(Persona[])q.getResultList().toArray(new Persona[0]);</span><br /><br /><span style="font-weight: bold;">for(Persona p:personas)</span><br /><span style="font-weight: bold;">System.out.println(p.getPropiedad());</span><br /></span><br />A veces no queremos tener un array de Entity Class sino que queremos obtener un valor escalar proveniente de una función sum, avg, max, etc...<br /><br /><span style="font-weight: bold;font-size:78%;" >EntityManagerFactory emf=Persistence.createEntityManagerFactory("nombreUnidadPersistencia");<br /></span><pre style="font-weight: bold;"><span style="font-size:78%;"><a name="IDX-CHP-9-1419"></a></span></pre><span style="font-weight: bold;font-size:78%;" >EntityManager em=em.createEntityManager();<br />String consulta="select sum(campo) from tabla";<br /></span><span style="font-size:78%;"><span style="font-weight: bold;">Query q=em.createNativeQuery(consulta);</span></span><br /><span style="font-weight: bold;font-size:78%;" >double total=((BigDecimal)((List)q.getSingleResult()).get(0)).doubleValue();</span><br /><br />De esta forma podemos trabajar con consultas SQL nativas y poder hacer uso de las capacidades de nuestra base de datos.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com5tag:blogger.com,1999:blog-4234304323727536894.post-41510755301228260212009-10-02T21:36:00.000-07:002009-10-24T00:21:43.754-07:00JSF y la clase AbstractPageBean<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SsbVNU80MwI/AAAAAAAABuY/YBZbZzVoqIk/s1600-h/java_logo.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 72px; height: 134px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SsbVNU80MwI/AAAAAAAABuY/YBZbZzVoqIk/s320/java_logo.png" alt="" id="BLOGGER_PHOTO_ID_5388228429134181122" border="0" /></a>Hace poco un compa me comentaba que al desarrollar algunos de los ejemplos que he realizado con JSF e ICEfaces no sabía que librería era necesaria para utilizar la clase AbstractPageBean, esta clase la uso para efectos de poder utilizar el método getBean(String) y obtener ya sea managed bean instanciados o el valor actual en un recorrido por una dataTable entre otros usos mas.<br /><br />Pues para resolver esta duda la librería que se utiliza es llamada "<span style="font-weight: bold;">JSF 1.1 Design-Time Support - Deprecated</span>" que esta incluida en Netbeans.<br /><br />Como es de fijarse como bien dice el nombre de esta libreria es de <a href="http://www.srbyte.com/2009/04/deprecated-code-codigo-obsoleto.html">uso obsoleto </a>es por esa razón que ultimamente no la he estado utilizando así que implemento mi propio método getBean de esta forma:<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SsbYpLahP3I/AAAAAAAABug/OpgegUY4wDI/s1600-h/getbean.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 90px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SsbYpLahP3I/AAAAAAAABug/OpgegUY4wDI/s320/getbean.png" alt="" id="BLOGGER_PHOTO_ID_5388232206145634162" border="0" /></a><br />Así puedo hacer llamadas incluso a SessionBeans y ApplicationBeans.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com1tag:blogger.com,1999:blog-4234304323727536894.post-2089081975561921502009-09-27T21:25:00.001-07:002009-09-27T21:57:39.266-07:00Creando tablas dinámicas con OpenOffice.org Calc<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SsA6v-bwT1I/AAAAAAAABto/Iq1JdLuekjM/s1600-h/calc_logo.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 180px; height: 135px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SsA6v-bwT1I/AAAAAAAABto/Iq1JdLuekjM/s320/calc_logo.jpg" alt="" id="BLOGGER_PHOTO_ID_5386369750222786386" border="0" /></a>Muchas de las cosas que se suelen utilizar con frecuencia en Microsoft Excel son las "Tablas dinamicas" y como yo soy partidario de usar siempre en lo posible software libre me decidi a realizar un pequeño ejemplo en cual se puede realizar lo mismo pero utilizando OpenOffice.org Calc.<br /><br />En el caso de Calc no se llaman "Tablas dinamicas" sino "Piloto de datos".<br /><br />Y como es de costumbre en este blog para poder entender de lo que estoy hablando es necesario elaborar un pequeño ejemplo.<br /><br />Supongamos que tengo un archivo en cual esta conformado por las siguientes columnas:<br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SsA-EsBRMgI/AAAAAAAABt4/qvt5h9W-bk8/s1600-h/datos.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 313px; height: 320px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SsA-EsBRMgI/AAAAAAAABt4/qvt5h9W-bk8/s320/datos.png" alt="" id="BLOGGER_PHOTO_ID_5386373404591993346" border="0" /></a><br /><div style="text-align: justify;">Este archivo tiene reflejadas las ventas de ciertas sucursales por fecha y nosotros queremos generar un reporte en el cual podamos ver la venta de cada sucursal por semana y con filtro de mes.<br /><br />Para ello seleccionamos todas las celdas que conformaran la base de datos de la tabla en nuestro caso seria desde la columna A hasta la F.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SsBAUg6Ja_I/AAAAAAAABuA/zwrniazfyYs/s1600-h/seleccion_data.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 313px; height: 320px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SsBAUg6Ja_I/AAAAAAAABuA/zwrniazfyYs/s320/seleccion_data.png" alt="" id="BLOGGER_PHOTO_ID_5386375875510496242" border="0" /></a><br /><div style="text-align: justify;">Luego debemos ir al menú Datos > Piloto de datos > Inicio.<br />Luego aparece otra ventana que nos pregunta la fuente de datos seleccionamos la que ya viene marcada por defecto que es "Selección actual", al dar aceptar aparecera la ventana para diseñar nuestra tabla dinamica.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SsBAvnuCMZI/AAAAAAAABuI/ny5myZ1AHUs/s1600-h/conf_tabla.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 194px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SsBAvnuCMZI/AAAAAAAABuI/ny5myZ1AHUs/s320/conf_tabla.png" alt="" id="BLOGGER_PHOTO_ID_5386376341195207058" border="0" /></a><br /><div style="text-align: justify;">Es importante que al diseñar se elija el botón "Opciones" y establecer que la tabla dinamica se cree en una nueva hoja.<br /><br />Luego de esto obtenemos nuestra tabla dinamica.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/SsBBSekI7LI/AAAAAAAABuQ/iknSUbjaOjI/s1600-h/tabla_dinamica.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 216px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/SsBBSekI7LI/AAAAAAAABuQ/iknSUbjaOjI/s320/tabla_dinamica.png" alt="" id="BLOGGER_PHOTO_ID_5386376940033207474" border="0" /></a>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com8tag:blogger.com,1999:blog-4234304323727536894.post-54143197056208494422009-09-27T14:06:00.000-07:002009-09-27T21:59:45.126-07:00JSF: Creando reglas de navegación con Netbeans<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/Sr_UVM_wQLI/AAAAAAAABso/x1NI0n7BIBo/s1600-h/java-logo-small.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 125px; height: 166px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/Sr_UVM_wQLI/AAAAAAAABso/x1NI0n7BIBo/s320/java-logo-small.png" alt="" id="BLOGGER_PHOTO_ID_5386257140089372850" border="0" /></a>Si bien muchos han leido la <a href="http://wiki.netbeans.org/NavegandoPaginasVisualJSF">documentación de la misma página de Netbeans para las reglas de navegación</a>, la explicación no da explicación para reusar la regla de navegación para varias páginas.<br /><br />Es decir que solamente puedo utilizar la regla de navegación a través de una tan sola página, pero si de repente tenemos el mismo link en varias páginas no nos servira.<br /><br />¿Como solucionamos este problema?<br /><br />Es de una forma muy sencilla, para entenderlo crearemos una regla de navegación con tres simples jsp.<br /><br />Luego de crear el proyecto y crear los tres jsp, debemos ir al archivo faces-config.xml y dar clic en el botón "XML".<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_jMncZ8mI/AAAAAAAABsw/-rrCVHvoLGk/s1600-h/faces-config-diagrama.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 137px;" src="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_jMncZ8mI/AAAAAAAABsw/-rrCVHvoLGk/s320/faces-config-diagrama.png" alt="" id="BLOGGER_PHOTO_ID_5386273485244461666" border="0" /></a><br /><div style="text-align: justify;">Luego no aparece era el código xml del archivo, ahora debemos dar clic derecho sobre cualquier parte del documento y escoger la opción <span style="font-weight: bold;">JavaServer Faces > Add Navigation Case...</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_pdDyveNI/AAAAAAAABtY/No6mnrdK1E0/s1600-h/navigation_case.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 246px;" src="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_pdDyveNI/AAAAAAAABtY/No6mnrdK1E0/s320/navigation_case.png" alt="" id="BLOGGER_PHOTO_ID_5386280364802013394" border="0" /></a><br /></div><div style="text-align: justify;">Luego de esto en el campo "From view" debemos escribir un asterisco esto indica para poder utilizar la regla de navegación desde cualquier link en cualquier página, no escribiremos nada en el campo "From Action" así que en el siguiente campo llamado "From Outcome" debemos escribir la cadena que devolvera el método en el backing bean para acceder al link y por ultimo en el campo "To View" buscamos la página jsp, jspx o xhtml que deseemos acceder a través del link y procedemos a hacer clic en el botón "Add".<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_kr0grudI/AAAAAAAABs4/p_e3zGx2SlY/s1600-h/navigation_case_ejemplo.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 246px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_kr0grudI/AAAAAAAABs4/p_e3zGx2SlY/s320/navigation_case_ejemplo.png" alt="" id="BLOGGER_PHOTO_ID_5386275120839637458" border="0" /></a><br /><div style="text-align: justify;">Ahora para crear una nueva regla realizamos los pasos mencionados anteriormente nada mas con la variante que el campo "From Outcome" y "To View" cambiaran, en el ejemplo que estamos desarrollando para el siguiente link lo llenamos así:<br /><br /></div><span style="font-size:85%;"> <span style="font-weight: bold;">From Outcome: pagina_2</span><span style="font-weight: bold;"><br /></span><span style="font-weight: bold;">To View: pagina2.jspx</span></span><br /><br />Y lo hacemos nuevamente con la tercera regla.<br /><br /><span style="font-weight: bold;font-size:85%;" >From Outcome: pagina_3<br />To View: pagina3.jspx</span><br /><br />Y nuestro archivo debera quedar de la siguiente manera:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_mDEgn-OI/AAAAAAAABtA/sQfWa5zR-lI/s1600-h/xml_faces_config.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 197px;" src="http://1.bp.blogspot.com/_tPLVjrBRifE/Sr_mDEgn-OI/AAAAAAAABtA/sQfWa5zR-lI/s320/xml_faces_config.png" alt="" id="BLOGGER_PHOTO_ID_5386276619782977762" border="0" /></a><br />Con este nueva estructura nuestro diagrama ser verá así:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_qZKd2obI/AAAAAAAABtg/VmcpIfaw56c/s1600-h/nuevo_diagrama.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 210px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_qZKd2obI/AAAAAAAABtg/VmcpIfaw56c/s320/nuevo_diagrama.png" alt="" id="BLOGGER_PHOTO_ID_5386281397385601458" border="0" /></a><br /><div style="text-align: justify;">Luego procedemos a crear nuestro Managed Bean de scope Request para implementar las reglas que hemos creado, yo le he llamado "LinksBean"<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/Sr_nWRSEQdI/AAAAAAAABtI/FW5joegJetw/s1600-h/LinksBean.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 308px; height: 320px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/Sr_nWRSEQdI/AAAAAAAABtI/FW5joegJetw/s320/LinksBean.png" alt="" id="BLOGGER_PHOTO_ID_5386278049140720082" border="0" /></a><br /><div style="text-align: justify;">Luego nada mas debemos enlazar el backing bean a los commandLink de la página jsp.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/Sr_oQb_IGfI/AAAAAAAABtQ/ymmRzVbx9bw/s1600-h/pagina1.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 226px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/Sr_oQb_IGfI/AAAAAAAABtQ/ymmRzVbx9bw/s320/pagina1.png" alt="" id="BLOGGER_PHOTO_ID_5386279048446482930" border="0" /></a><br /><div style="text-align: justify;">Luego de esto nada mas debemos ejecutar la aplicación, <a href="http://www.mediafire.com/file/gmmyzzdhzz2/WebNavegacion.tar.gz">adjunto el proyecto</a> para efectos de estudio. Si usas Windows recuerda tener instalado <a href="http://www.google.com.sv/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fwww.winrar.es%2F&ei=OOm_SqqfLMSa8Abx18ygAQ&rct=j&q=winrar&usg=AFQjCNFGXrJ5Wow50F4-NrngrLM23LTXvg">winrar</a> para poder descomprimir el proyecto.<br /></div>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com1tag:blogger.com,1999:blog-4234304323727536894.post-26147288953442295482009-09-27T13:49:00.001-07:002009-09-27T14:00:54.133-07:00JSF: Redireccionando a páginas de terceros a través de un BackingBean<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_QiXmBAdI/AAAAAAAABsg/74DV7YORIAk/s1600-h/j2ee_logo.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 150px; height: 100px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/Sr_QiXmBAdI/AAAAAAAABsg/74DV7YORIAk/s320/j2ee_logo.jpg" alt="" id="BLOGGER_PHOTO_ID_5386252968225997266" border="0" /></a>Si bien existe la posibilidad para manejar los enlaces de nuestro proyecto Web con <a href="http://krypto84sv.blogspot.com/search/label/jsf">JSF</a> a través del archivo de configuración faces-config.xml, a veces nos vemos en la necesidad de tener enlaces en las páginas de nuestro proyecto que redireccionan a sitios de terceros a través de una validación en el Backing Bean.<br /><br />La manera de hacerlo es de la siguiente forma:<br /></div><br /><span style="font-size:85%;">String url=<span style="color: rgb(255, 153, 0);">"http://krypto84sv.blogspot.com"</span>;<br />FacesContext fc=FacesContext.getCurrentInstance();<br />fc.getExternalContext().redirect(url);</span><br /><br /><div style="text-align: justify;">Notese que la cadena "url" va la url completa de la dirección donde queremos redireccionar, este método se puede también utilizar para ir a una página en especifico de nuestro proyecto, pero es mucho mas eficiente utilizar las reglas de navegación propias del faces-config.xml para moverse dentro de nuestro mismo proyecto.<br /></div>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com0tag:blogger.com,1999:blog-4234304323727536894.post-52685628204000227582009-08-06T19:09:00.001-07:002009-08-10T08:44:15.815-07:00ICEfaces: Editando registros en Crosstab<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tPLVjrBRifE/SldnoYBaXPI/AAAAAAAABmg/S438fH5Mjl4/s320/ICEfaces.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 63px; height: 70px;" src="http://1.bp.blogspot.com/_tPLVjrBRifE/SldnoYBaXPI/AAAAAAAABmg/S438fH5Mjl4/s320/ICEfaces.jpg" alt="" border="0" /></a>Al leer un comentario en la entradade como crear <a href="http://krypto84sv.blogspot.com/2009/06/crosstab-con-icefaces.html">Crosstab con ICEfaces</a>, me hacian la consulta de como poder relacionar un id de un registro con un valor puesto en un inputtext dentro de la tabla, así que me decidi desarrollar un ejemplo como es de costumbre en este blog para poder resolver el problema.<br /><br />El ejemplo que expondre no varia mucho del que esta hecho en la entrada de <a href="http://krypto84sv.blogspot.com/2009/06/crosstab-con-icefaces.html">Crosstab con ICEfaces</a>, pues la estructura de la base de datos es la misma.<br /><br />También en la clase "Dao" se debe agregar dos métodos los cuales son:<br /></div><ul><li>ActualizarPrecio</li><li>NuevoPrecio</li></ul><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SnuOkoLveWI/AAAAAAAABsA/MgOImtkvItQ/s1600-h/NuevosMetodos.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 215px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SnuOkoLveWI/AAAAAAAABsA/MgOImtkvItQ/s320/NuevosMetodos.png" alt="" id="BLOGGER_PHOTO_ID_5367040140855179618" border="0" /></a>Despues el Managed Bean Pagina queda así:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/SnuR33WrGJI/AAAAAAAABsI/sagK0levaYM/s1600-h/PaginaManaged.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 308px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/SnuR33WrGJI/AAAAAAAABsI/sagK0levaYM/s320/PaginaManaged.png" alt="" id="BLOGGER_PHOTO_ID_5367043769879959698" border="0" /></a>Y la estructa de la tabla en xhtml es la siguiente:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tPLVjrBRifE/SnuSHcHpFFI/AAAAAAAABsQ/PShIidfCyZ8/s1600-h/xmlTabla.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 207px;" src="http://4.bp.blogspot.com/_tPLVjrBRifE/SnuSHcHpFFI/AAAAAAAABsQ/PShIidfCyZ8/s320/xmlTabla.png" alt="" id="BLOGGER_PHOTO_ID_5367044037447062610" border="0" /></a><br /><div style="text-align: justify;">Al ejecutar la aplicación a través de la ruta http://localhost:8084/EjemploTabla que se verá así:<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SnuSWkniieI/AAAAAAAABsY/rCuLLIUTuzM/s1600-h/EjemploTabla.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 254px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SnuSWkniieI/AAAAAAAABsY/rCuLLIUTuzM/s320/EjemploTabla.png" alt="" id="BLOGGER_PHOTO_ID_5367044297426373090" border="0" /></a><br /><div style="text-align: justify;">¿Como es el funcionamiento de la aplicación?<br /><br />Pues por cada InputText <ice:inputtext> se ejecuta <span style="color: rgb(51, 51, 255);"><ice:inputtext></ice:inputtext></span> su respectivo evento ValueChangeListener ejecuta el evento ActualizarPrecio del managed bean Pagina al cambiar el valor de cada caja de texto y el método evalua si el precio existe lo actualizar de lo contrario lo crea.<br /></ice:inputtext></div><br /><a href="http://www.mediafire.com/?sharekey=5455cd43eb345dd0d5a101cf914073b49730a35054fe6752">Comparto el proyecto</a> para efectos de estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com5tag:blogger.com,1999:blog-4234304323727536894.post-59762861778774367402009-07-25T18:07:00.000-07:002009-07-25T18:23:50.425-07:00Cambio de imagen en Anécdotas de las curvas del seno<div style="text-align: justify;">Como es de notar ahora mi blog ha cambiado y mucho, pues ya tenia mucho de no darme a la tarea de embellecerlo un poco y es que tambien han habiado muchos cambios en mi vida, pues tambien tengo nueva computadora es una <a href="http://h10010.www1.hp.com/wwpc/co/es/ho/WF06b/321957-321957-3329744-64354-64354-3873767-3958585.html">HP Pavilio dv2-1010la</a> que ya tiene instalado el todo poderoso Debian y todos sus dispositivos funcionando a la perfección.<br /></div><br /><div style="text-align: justify;"><div style="text-align: center;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://h10010.www1.hp.com/wwpc/images/emea/NU834LA_190x170.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 170px; height: 190px;" src="http://h10010.www1.hp.com/wwpc/images/emea/NU834LA_190x170.jpg" alt="" border="0" /></a><span style="font-size:78%;">Mi nueva adquisición</span><br /><br /></div><div style="text-align: justify;">Ahora espero tener un poco mas de actividad bloguera y contrubuir con mis post sobre <a href="http://krypto84sv.blogspot.com/search/label/java">Java</a> a todos los amigos de la UES.<br /><br />Saludos.<br /></div></div>Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com3tag:blogger.com,1999:blog-4234304323727536894.post-17349293730263244592009-07-20T14:48:00.000-07:002009-07-25T17:45:50.612-07:00JSF: Conectando tablas de FoxPro con Java y ICEfaces<div style="text-align: justify;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tPLVjrBRifE/SldnoYBaXPI/AAAAAAAABmg/S438fH5Mjl4/s320/ICEfaces.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 63px; height: 70px;" src="http://1.bp.blogspot.com/_tPLVjrBRifE/SldnoYBaXPI/AAAAAAAABmg/S438fH5Mjl4/s320/ICEfaces.jpg" alt="" border="0" /></a>En el trabajo ultimamente he estado arto de tener que estar creando aplicaciones en la cual se tiene que alimentar por medio de un archivo de Excel en las interfaces web y esto se debe que casi todo esta elaborado con tablas de fox, entonces me decidi a averiguar si hay alguna manera de pegarme a dichas tablas y a la vez tener los beneficios de <a href="http://krypto84sv.blogspot.com/2008/11/introduciendo-al-uso-de-persistencia-de.html">JPA</a>.<br /><br />Googleando un poco me di cuenta que no existe un driver JDBC especifico para tablas de Fox Pro, entonces la solución es conectarse a través de <a href="http://es.wikipedia.org/wiki/Open_Database_Connectivity">ODBC</a>, pues mucho me van a decir que utilizar ODBC es lento pero por el momento no he encontrado otra manera, y lo otro es que me amarra utilizar windows del lado del servidor de aplicaciones, intente usar <a href="http://www.unixodbc.org/">unixODBC</a> pero no existe driver para tablas Dbase así que por el momento estoy amarrado a windows utilizando esta conectividad.<br /><br />Pues bien ahora voy a la parte que mas me gusta y es la de desarrollar un ejemplo, en el cual creare un proyecto Java Library Class con <a href="http://krypto84sv.blogspot.com/search/label/netbeans">Netbeans</a> en cual puede ser utilizado tanto en un proyecto web como en una aplicación de escritorio con Swing o alguna interfaz en Java que este en en escucha, o como putas les pegue la regalada gana usarlo siempre con Java.<br /></div><br /><span style="font-weight: bold;">Paso 0</span><br /><br />Antes de empezar es necesario tener instalado el Driver de Microsoft Visual FoxPro que esta disponible en la siguiente dirección:<br /><br /><a href="http://msdn.microsoft.com/en-us/vfoxpro/bb190233.aspx">http://msdn.microsoft.com/en-us/vfoxpro/bb190233.aspx</a><br /><br /><span style="font-weight: bold;">Paso 1</span><br /><br /><div style="text-align: justify;">Crear el origen de datos de las tablas, para este ejemplo yo creo que un archivo de base de datos de Fox con una tabla llamada "Persona", tambien funciona perfectamente con tablas libres.<br /><br />Nos dirigimos a Panel de Control / Herramientas administrativas / Orígenes de datos (ODBC) estando alli en la ficha DSN de usuario damos clic en "Agregar" y nos aparecera el listado de Drivers a utilizar en nuestro caso seleccionaremos "Driver para o Microsoft Visual FoxPro" o cualquier otro similar que se llame Visual FoxPro que al fin y al cabo son iguales.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SmTrI06tG4I/AAAAAAAABoA/ZLPjM-0z73Y/s1600-h/SeleccionDriver.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 236px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SmTrI06tG4I/AAAAAAAABoA/ZLPjM-0z73Y/s320/SeleccionDriver.PNG" alt="" id="BLOGGER_PHOTO_ID_5360667993354083202" border="0" /></a><br />Luego de esto debemos elegir la ruta nuestro archivo de base de datos o la ruta del directorio donde tengamos nuestras tablas libres y asignamos nombre a nuestro Origen de datos en mi caso le llame "FoxPro"<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SmTrdDcg91I/AAAAAAAABoI/eeEszuImxio/s1600-h/RegistroOrigenDato.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 150px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SmTrdDcg91I/AAAAAAAABoI/eeEszuImxio/s320/RegistroOrigenDato.PNG" alt="" id="BLOGGER_PHOTO_ID_5360668340851373906" border="0" /></a><br />Damos clic en "Ok" y tendremos listo nuestro origen de datos.<br /><br /><span style="font-weight: bold;">Paso 2</span><br /><br />Dentro de <a href="http://krypto84sv.blogspot.com/search/label/netbeans">Netbeans</a> 6.7 es necesario crear una conexión de base de datos de tipo "JDBC-ODBC Bridge" en username y password se coloca un usuario y contraseña de windows y la cadena de URL JDBC se coloca el nombre del Origen de datos que en nuestro caso es "FoxPro".<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SmTtymRNWLI/AAAAAAAABoQ/PkltJewUDn4/s1600-h/ConexionNetbeans.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 215px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SmTtymRNWLI/AAAAAAAABoQ/PkltJewUDn4/s320/ConexionNetbeans.PNG" alt="" id="BLOGGER_PHOTO_ID_5360670909999700146" border="0" /></a><br /><span style="font-weight: bold;">Paso 3</span><br /><br /><div style="text-align: justify;">Procedemos a crear un proyecto Java Class Library, que le nombrare "JavaFox", que contendra nuestro Entity Class de la tabla Persona. Para este caso en particular creare la unidad de persistencia a parte y la clase Entidad ya que el asistente de Netbeans no puede crearlo por nosotros ya que fox no sabe sobre esquemas y asi no funciona bien el asistente.<br /><br />Cree mi paquete llamado "org.dani.ejemplo.fox" doy clic derecho sobre este me voy a "Nuevo" selecciono la categoría "Persistence" y selecciono "Unidad de persistencia", en la ventana de dialogo del asistente podemos como libreria de persistencia Hibernate o Toplink en mi caso siempre me gusta usar mas TopLink asi que elijo esta, también elijo la conexión de base de datos que creamos anteriormente y en la opción de Table Generation Strategy marcamos "none" y por ultimo damos clic en Finish.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SmTu9qbtALI/AAAAAAAABoY/IdyQ7-Ao3lU/s1600-h/UnidadPersistencia.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 186px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SmTu9qbtALI/AAAAAAAABoY/IdyQ7-Ao3lU/s320/UnidadPersistencia.PNG" alt="" id="BLOGGER_PHOTO_ID_5360672199607648434" border="0" /></a><span style="font-weight: bold;">Paso 4</span><br /><br /><div style="text-align: justify;">Ahora procedemos a crear nuestra Entity Class de la tabla Persona, damos clic derecho sobre el paquete que habíamos creado seleccionamos de nuevo la categoría "Persistencia" pero ahora escogemos "Entity Class" y completamos la clase de esta manera:<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SmT_4YFfdDI/AAAAAAAABog/n9PyhrbBzrg/s1600-h/ClasePersona.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 310px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SmT_4YFfdDI/AAAAAAAABog/n9PyhrbBzrg/s320/ClasePersona.PNG" alt="" id="BLOGGER_PHOTO_ID_5360690800480973874" border="0" /></a><br /><span style="font-weight: bold;">Paso 5</span><br /><br /><div style="text-align: justify;">Creamos un <a href="http://krypto84sv.blogspot.com/2009/06/uso-de-facelets-y-icefaces-en-netbeans.html">proyecto web Con ICEfaces y Facelets</a>, yo lo llamare "WebFox", tambien debemos importar el proyecto anterior a este, ya sin perder ya tanto el tiempo nos diponemos a crear nuestro Managed Bean llamado "TemplateClient", el cual tendra la funcionalidad de listar, modificar y guardar registros de la tabla de FoxPro.<br /></div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tPLVjrBRifE/SmUBArghuFI/AAAAAAAABow/vt9OH8ecwGk/s1600-h/TemplateClient.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 258px; height: 320px;" src="http://3.bp.blogspot.com/_tPLVjrBRifE/SmUBArghuFI/AAAAAAAABow/vt9OH8ecwGk/s320/TemplateClient.PNG" alt="" id="BLOGGER_PHOTO_ID_5360692042645223506" border="0" /></a><span style="font-weight: bold;">Paso 6</span><br /><br />Ahora solo debemos editar la parte de la vista que es el templateclient.xhtml<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SmUCU677SDI/AAAAAAAABpQ/AnSpGsK9t8s/s1600-h/template-client.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 286px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SmUCU677SDI/AAAAAAAABpQ/AnSpGsK9t8s/s320/template-client.PNG" alt="" id="BLOGGER_PHOTO_ID_5360693489895688242" border="0" /></a><br />Ya hecho todo lo anterior nada mas bastara con ejecutar nuestra aplicación<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tPLVjrBRifE/SmUCepMI_tI/AAAAAAAABpY/T7llT7RPUp4/s1600-h/firefoxApp.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 242px;" src="http://2.bp.blogspot.com/_tPLVjrBRifE/SmUCepMI_tI/AAAAAAAABpY/T7llT7RPUp4/s320/firefoxApp.PNG" alt="" id="BLOGGER_PHOTO_ID_5360693656930549458" border="0" /></a><br />Comparto <a href="http://www.mediafire.com/?sharekey=5455cd43eb345dd0d5a101cf914073b49730a35054fe6752">el proyecto</a> para efectos del estudio.Daniel Albertohttp://www.blogger.com/profile/04243634599457276349noreply@blogger.com4