mi primera aproximación a Google App Engine (de ahora en demás GAE) fue adaptar esta entrada MVC en JSP a GAE; esto requiere ciertos cambios a nivel de código el almacenamiento ya no se hará sobre MySQL sino el almacén de datos de GAE, el motor de persistencia usado en GAE será JDO, la arquitectura seguirá siendo MVC, y se realizarán pequeños cambios a nivel de GUI, la funcionalidad será la misma.
Bueno siguiendo con el ejemplo anterior esta vez explicare mi aplicación del patrón MVC en JSP corriendo sobre GAE, no es la intención explicar lo que es MVC. De igual manera mi intención tampoco es explicar las bases de esta aplicación, ni las APIs usadas.
conocimientos previos:
Esta vez solo se colgará el código la explicación esta en la presentación de arriba.
la estructura dela aplicación sería algo muy parecido a:
el modelo bajo el cual se trabajo es este:
Base de datos
¿?… el primer choque que tuve con GAE fue este: y… ¿donde está mi base de datos?, ¿donde están las sentencias SQL?.
esta se crea automaticamente (por configuraciones sobre JDO @Anotaciones o XML) y no es relacional es BigTable.
LA APLICACIÓN EN FUNCIONAMIENTO ESTÁ AQUÍ
LAS JAVA
Beans
Departamento.java
package ingenio.ds.gae.model.entity;
import java.io.Serializable;
import java.lang.Comparable;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;
@SuppressWarnings("serial")
@PersistenceCapable (identityType=IdentityType.APPLICATION)
public class Departamento implements Serializable,Comparable{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent(valueStrategy=IdGeneratorStrategy.SEQUENCE)
private Long id;
@Persistent
private String nombre;
@Persistent
private String descripcion;
public Departamento(){
super();
}
public Long getId(){
return id;
}
public Key getKey(){
return key;
}
public String getNombre(){
return nombre;
}
public String getDescripcion(){
return descripcion;
}
public void setKey(Key key){
this.key=key;
}
public void setId(Long id ){
this.id=id;
}
public void setNombre(String nombre ){
this.nombre=nombre;
}
public void setDescripcion(String descripcion ){
this.descripcion=descripcion;
}
public String toString(){
return(
"DATOS:::DEPARTAMENTO:::...\n"+
"ID : "+id+"\n"+
"NOMBRE : "+nombre+"\n"+
"DESCRIPCION : "+descripcion+"\n"+
"");
}
public int compareTo(Departamento departamento){
return nombre.compareTo(departamento.getNombre());
}
}
Empleado.java
package ingenio.ds.gae.model.entity;
import java.io.Serializable;
import java.lang.Comparable;
import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Key;
@SuppressWarnings("serial")
@PersistenceCapable (identityType=IdentityType.APPLICATION)
public class Empleado implements Serializable,Comparable{
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent(valueStrategy=IdGeneratorStrategy.SEQUENCE)
private Long id;
@Persistent
private String nombre;
@Persistent
private String apellido;
@Persistent
private Integer identificacion;
@Persistent
private Key departamento;
@Persistent
private Double sueldo;
@Persistent
private Double transporte;
@Persistent
private Date fdn;
@Persistent
private Blob foto;
@Persistent
private BlobKey fotoKey;
public Empleado(){
super();
}
public Key getKey(){
return key;
}
public Long getId(){
return id;
}
public String getNombre(){
return nombre;
}
public String getApellido(){
return apellido;
}
public Integer getIdentificacion(){
return identificacion;
}
public Key getDepartamento(){
return departamento;
}
public Double getSueldo(){
return sueldo;
}
public Double getTransporte(){
return transporte;
}
public Date getFdn(){
return fdn;
}
public Blob getFoto(){
return foto;
}
public void setKey(Key key){
this.key=key;
}
public BlobKey getFotoKey(){
return fotoKey;
}
public void setId(Long id ){
this.id=id;
}
public void setNombre(String nombre ){
this.nombre=nombre;
}
public void setApellido(String apellido ){
this.apellido=apellido;
}
public void setIdentificacion(Integer identificacion ){
this.identificacion=identificacion;
}
public void setDepartamento(Key departamento ){
this.departamento=departamento;
}
public void setSueldo(Double sueldo ){
this.sueldo=sueldo;
}
public void setTransporte(Double transporte ){
this.transporte=transporte;
}
public void setFdn(Date fdn){
this.fdn=fdn;
}
public void setFoto(Blob foto){
this.foto=foto;
}
public void setFotoKey(BlobKey fotoKey){
this.fotoKey=fotoKey;
}
public String toString(){
return(
"DATOS:::EMPLEADO:::...\n"+
"ID : "+id+"\n"+
"NOMBRE : "+nombre+"\n"+
"APELLIDO : "+apellido+"\n"+
"IDENTIFICACION : "+identificacion+"\n"+
"DEPARTAMENTO : "+departamento+"\n"+
"SUELDO : "+sueldo+"\n"+
"TRANSPORTE : "+transporte+"\n"+
"FDN : "+fdn+"\n"+
"FOTO : "+foto+"\n"+
"");
}
public int compareTo(Empleado empleado){
return apellido.compareTo(empleado.getApellido());
}
}
Persitence
PMF.java
package ingenio.ds.gae.model;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
public final class PMF {
//Variable encargada de controlar las peticiones
private static final PersistenceManagerFactory instance =JDOHelper.getPersistenceManagerFactory("transactions-optional");
//Para que no puedan instanciar la clase
private PMF(){}
//Retorna la instancia encargada de controlar las peticiones
public static PersistenceManagerFactory get(){
return instance;
}
}
JDO.java
package ingenio.ds.gae.model.jdo;
import ingenio.ds.gae.model.PMF;
import java.io.IOException;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import com.google.appengine.api.datastore.Key;
public class JDO {
final static int FETCH_MAX_RESULTS = 10;
private Class _class;
public static JDO getInstance(Class _class) {
return new JDO(_class);
}
protected JDO(Class _class) {
this._class = _class;
}
@SuppressWarnings("unchecked")
public List findAll(){
final PersistenceManager pm = PMF.get().getPersistenceManager();
final Query query = pm.newQuery(_class);
query.setRange(0, FETCH_MAX_RESULTS);
List results = ((List) query.execute());
return results;
}
@SuppressWarnings("unchecked")
public List findAllByParameter(String parametro,String tipo, Object valor){
final PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(_class,parametro+" == _param ");
query.declareParameters(tipo+" _param");
List results = (List) query.execute(valor);
return results;
}
@SuppressWarnings("unchecked")
public T findOneByParameter(String parametro,String tipo, Object valor) throws IOException{
final PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(_class,parametro+" == _param ");
query.declareParameters(tipo+" _param");
List results = (List) query.execute(valor);
if(results.size() return (results.size()==0)?null:results.get(0);
}
public T findByKey(Key key){
final PersistenceManager pm = PMF.get().getPersistenceManager();
T objeto=pm.getObjectById(_class, key) ;
pm.close();
return objeto;
}
public void insert(T objeto){
final PersistenceManager pm = PMF.get().getPersistenceManager();
pm.currentTransaction().begin();
pm.makePersistent(objeto);
pm.currentTransaction().commit();
pm.close();
}
public void update(T objeto){
final PersistenceManager pm = PMF.get().getPersistenceManager();
pm.currentTransaction().begin();
pm.makePersistent(objeto);
pm.currentTransaction().commit();
pm.close();
}
public void delete(Key key){
final PersistenceManager pm = PMF.get().getPersistenceManager();
pm.currentTransaction().begin();
T object_odl = _class.cast(pm.getObjectById(key, false));
pm.deletePersistent(object_odl);
pm.currentTransaction().commit();
}
}
Actions
Action.java
package ingenio.ds.gae.controller.actions;
import ingenio.ds.gae.model.jdo.JDO;
import java.io.IOException;
import javax.jdo.PersistenceManager;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.logging.Logger;
public abstract class Action {
protected HttpServletRequest request;
protected HttpServletResponse response;
protected ServletContext application;
protected PersistenceManager pm;
@SuppressWarnings("rawtypes")
protected JDO jdo;
protected static final Logger logger = Logger.getLogger(Action.class.getName());
public abstract void run()throws ServletException, IOException;
public void setRequest(HttpServletRequest request){
this.request=request;
}
public void setResponse(HttpServletResponse response){
this.response=response;
}
public void setApplication(ServletContext application){
this.application=application;
}
public void setPersistenceManager(PersistenceManager model){
this.pm=model;
}
}
AgregarEmpleado.java
package ingenio.ds.gae.controller.actions;
//clases de la aquitectura
import ingenio.ds.gae.model.entity.Departamento;
import ingenio.ds.gae.model.entity.Empleado;
import ingenio.ds.gae.model.jdo.JDO;
//calses para que sea servlet
import java.io.IOException;
import javax.servlet.ServletException;
//clases para almacenamiento de blobs
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
//clases para el tratamiento de los datos
import java.util.Map;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class AgregarEmpleado extends Action {
private static final DateFormat formato_fecha = new SimpleDateFormat("dd/MM/yyyy");
@SuppressWarnings("unchecked")
public void run()throws ServletException, IOException{
String dir="/index.jsp?pagina=ge";
BlobstoreService blobstoreService= BlobstoreServiceFactory.getBlobstoreService();
Map blobs = blobstoreService.getUploadedBlobs(request);
BlobKey blobKey = blobs.get("foto");
Empleado empleado=new Empleado();
empleado.setNombre(request.getParameter("nombre"));
empleado.setApellido(request.getParameter("apellido"));
empleado.setIdentificacion(Integer.parseInt(request.getParameter("identificacion")));
jdo= JDO.getInstance(Departamento.class);
Departamento departamento=(Departamento)jdo.findOneByParameter("id", "Integer", Integer.parseInt(request.getParameter("departamento")));
empleado.setDepartamento(departamento.getKey());
empleado.setSueldo(Double.parseDouble(request.getParameter("sueldo")) );
empleado.setTransporte(Double.parseDouble(request.getParameter("transporte")));
try {
empleado.setFdn(formato_fecha.parse(request.getParameter("fdn")));
} catch (ParseException e) {e.printStackTrace();}
empleado.setFotoKey(blobKey);
dir+="&blob-key="+blobKey.getKeyString();
jdo= JDO.getInstance(Empleado.class);
jdo.insert(empleado);
response.sendRedirect(dir);
}
}
AgregarDepartamento.java
package ingenio.ds.gae.controller.actions;
//clases para que sea servlet
import ingenio.ds.gae.model.entity.Departamento;
import ingenio.ds.gae.model.jdo.JDO;
//clases para el manejo de servlet
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.RequestDispatcher;
public class AgregarDepartamento extends Action {
@SuppressWarnings("unchecked")
public void run()throws ServletException, IOException{
try {
Departamento departamento=new Departamento();
departamento.setNombre(request.getParameter("nombre"));
departamento.setDescripcion(request.getParameter("descripcion"));
jdo= JDO.getInstance(Departamento.class);
jdo.insert(departamento);
}catch (Exception ex) {
throw new ServletException(ex.getMessage());
}
RequestDispatcher rd=application.getRequestDispatcher("/index.jsp?pagina=gd");
if(rd==null){
throw new ServletException("pagina no encontrada");
}
rd.forward(request,response);
}
}
FileUpload.java
package ingenio.ds.gae.controller.actions;
//clases para manejo de blobs
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import java.util.Map;
//posibles excepciones
import javax.servlet.ServletException;
import java.io.IOException;
public class FileUpload extends Action {
public void run()throws ServletException, IOException {
try {
Object blobstoreService_obj=request.getSession().getAttribute("blobstoreService") ;
BlobstoreService blobstoreService = (BlobstoreService) blobstoreService_obj;
Map blobs = blobstoreService.getUploadedBlobs(request);
BlobKey myFile = null;
myFile = blobs.get("myFile");
if (myFile != null){
logger.info("EEEMMM LA FOTO NO ES NULL");
logger.warning("EEEMMM LA FOTO NO ES NULL");
}else{
logger.info("PLOP, ESTÁ VAINA NO FUNCIONÓ");
logger.warning("PLOP, ESTÁ VAINA NO FUNCIONÓ");
}
} catch (Exception ex) {
throw new ServletException(ex);
}
}
}
FileRead.java
package ingenio.ds.gae.controller.actions;
//clases para el tratamiento de blobs
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
//posibles excepciones
import javax.servlet.ServletException;
import java.io.IOException;
public class FileRead extends Action {
public void run()throws ServletException, IOException {
try {
BlobstoreService blobstoreService= BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey= (BlobKey)request.getSession().getAttribute("blobKey");
if(blobKey==null){
String _blobKey=request.getParameter("blob-key");
blobKey = new BlobKey(_blobKey);
}
blobstoreService.serve(blobKey, response);
} catch (Exception ex) {
throw new ServletException(ex);
}
}
}
Controlador
Controller.java
package ingenio.ds.gae.controller;
//clases con las cuales trabaja
import ingenio.ds.gae.controller.actions.Action;
import ingenio.ds.gae.model.PMF;
import java.util.Map;
import java.util.HashMap;
import java.util.StringTokenizer;
import javax.jdo.PersistenceManager;
//clases para que sea servlet
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//posibles excepciones
import javax.servlet.ServletException;
import java.io.IOException;
@SuppressWarnings("serial")
public class Controller extends HttpServlet{
final PersistenceManager pm = PMF.get().getPersistenceManager();
public void doGet(HttpServletRequest rq, HttpServletResponse rp)throws IOException, ServletException{
ejecutar(rq, rp);
}
public void doPost(HttpServletRequest rq, HttpServletResponse rp)throws IOException, ServletException{
ejecutar(rq, rp);
}
private void ejecutar(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException{
HttpSession session=request.getSession();
@SuppressWarnings("unchecked")
Map mapaAcciones = (Map)session.getAttribute("mapaAcciones");
if(mapaAcciones==null){
mapaAcciones=new HashMap();
}
ServletContext context=getServletContext();
try {
String infoRuta = request.getPathInfo();
if(infoRuta==null){
throw new ServletException("RUTA DESCONOCIDA");
}
Action accion= (Action) mapaAcciones.get(infoRuta);
if(accion==null){
StringTokenizer st = new StringTokenizer(infoRuta,"/");
if(st.countTokens()!=2){
throw new ServletException("estado interno invalido- no hay informacion de ruta["+infoRuta+"]");
}
String evento = st.nextToken();
String bean = st.nextToken();
String servlet="ingenio.ds.gae.controller.actions."+ evento + bean;
try {
@SuppressWarnings("rawtypes")
Class claseAccion = Class.forName(servlet);
accion = (Action) claseAccion.newInstance();
mapaAcciones.put(infoRuta,accion);
session.setAttribute("mapaAcciones",mapaAcciones);
}catch (ClassNotFoundException ex){
throw new ServletException("No se pudo cargar la clase "+servlet+": "+ex.getMessage());
}catch (InstantiationException ex){
throw new ServletException("No se pudo instanciar un objeto de la clase "+servlet+": "+ex.getMessage());
}catch (IllegalAccessException ex){
throw new ServletException(servlet+": "+ex.getMessage());
}
}
if(pm==null){
throw new ServletException("MODELO DE CONEXION A BD NULO, IMPOSIBLE CONTINUAR CON LA OPERACION");
}
accion.setRequest(request);
accion.setPersistenceManager(PMF.get().getPersistenceManager());
accion.setResponse(response);
accion.setApplication(context);
accion.run();
} catch (Exception e) {
throw new ServletException("Error... \n"+e);
}
}
public String getServletInfo() {
return "CONTROLADOR DE ACCIONES Y REDIRECCIONAMIENTO (SIN MI NO HAY COMUNICACION ENTRE LO QUE VES Y LO QUE NO VES);";
}
}
LAS JSP
InitModel.jsp
<%
String BASEURL=request.getContextPath();
String CONTROLLER=BASEURL+"/servlet";
String ABSOLUTEURL=application.getInitParameter("ABSOLUTEURL");
String IMGSFOLDER="/";
application.setAttribute("CONTROLLER",CONTROLLER);
application.setAttribute("BASEURL",BASEURL);
application.setAttribute("ABSOLUTEURL",ABSOLUTEURL);
application.setAttribute("IMGSFOLDER",IMGSFOLDER);
%>
index.jsp
<%@ include file="WEB-INF/InitModel.jsp"%>
<html>
<head>
<title>MVC on GAE</title>
<style type="text/css">
<%@ include file="estilo.css"%>
</style>
<!--En este ejercicio repasaremos por la gran mayoria de entradas de JSP-->
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="5">
<tr>
<td colspan="2" valign="top" align="right">
<div id="titulo" align="right">
<img src="<%=application.getAttribute("ABSOLUTEURL")%>logo.png"
width="282" height="95">
</div></td>
</tr>
<tr>
<td valign="top">
<ul>
<li><a href="<%=application.getAttribute("ABSOLUTEURL")%>index.jsp">MENU</a></li>
<li><a href="<%=application.getAttribute("ABSOLUTEURL")%>index.jsp?pagina=gd">Departamentos</a></li>
<li><a href="<%=application.getAttribute("ABSOLUTEURL")%>index.jsp?pagina=ge">Empleados</a></li>
</ul></td>
<td>
<%
String pagina = request.getParameter("pagina");
if (pagina == null) {pagina = "";}
%>
<%if (pagina.matches("gd")) {%>
<%@ include file="gestion_departamento.jsp"%>
<%}%>
<%if (pagina.matches("ge")) {%>
<%@ include file="gestion_empleado.jsp"%>
<%}%>
</td>
</tr>
</table>
</body>
</html>
gestion_departamento.jsp
<table width="100%" border="0" cellspacing="0" cellpadding="5">
<tr>
<td valign="top">
<jsp:include page="registro_departamento.jsp"/>
</td>
<td>
<div style="height:650px; overflow:scroll;">
<jsp:include page="listar_departamento.jsp"/>
</div>
</td>
</tr>
</table>
registro_departamento.jsp
<form action="<%=application.getAttribute("CONTROLLER").toString()%>/Agregar/Departamento" method="post" enctype="application/x-www-form-urlencoded">
<table id="registro" width="110" border="0" cellspacing="0" cellpadding="5">
<tr align="center">
<td colspan="2" align="center">DATOS DEPARTAMENTO</td>
</tr>
<tr>
<td>NOMBRE</td>
<td><input name="nombre" type="text"> </td>
</tr>
<tr>
<td>DESCRIPCION</td>
<td><textarea name="descripcion" cols="20" rows="5"></textarea></td>
</tr>
<tr align="center">
<td colspan="2" align="center"><input type="submit" value="Guargar"></td>
</tr>
</table>
</form>
listar_departamento.jsp
<%@ page import="java.util.List"%>
<%@ page import="ingenio.ds.gae.model.entity.Departamento"%>
<%@ page import="ingenio.ds.gae.model.jdo.JDO"%>
<%
JDO<Departamento> jdo=JDO.getInstance(Departamento.class);
List<Departamento> lista_departamento=jdo.findAll();
%>
<table border="1" cellspacing="0" cellpadding="5">
<tr><td colspan="3" align="center" >LISTA DE DEPARTAMENTOS </td></tr>
<tr><td calign="center" >ID</td><td calign="center" >NOMBRE</td><td calign="center" >DESCRIPCION</td></tr>
<%for(int i=0;i<lista_departamento.size();i++){
Departamento departamento=(Departamento)lista_departamento.get(i);
out.print("<tr>");
out.print("<td>"+departamento.getId()+"</td>");
out.print("<td>"+departamento.getNombre()+"</td>");
out.print("<td>"+departamento.getDescripcion()+"</td>");
out.print("</tr>");
}%>
</table>
</body>
</html>
gestion_empleado.jsp
<table width="100%" border="0" cellspacing="0" cellpadding="5">
<tr>
<td valign="top">
<jsp:include page="registro_empleado.jsp"/>
</td>
<td>
<div style="height:650px; overflow:scroll;">
<jsp:include page="listar_empleado.jsp"/>
</div>
</td>
</tr>
</table>
registro_empleado.jsp
<%@ page import="java.util.List"%>
<%@ page import="ingenio.ds.gae.model.entity.Departamento"%>
<%@ page import="ingenio.ds.gae.model.jdo.JDO"%>
<%@ page import="com.google.appengine.api.blobstore.BlobstoreServiceFactory" %>
<%@ page import="com.google.appengine.api.blobstore.BlobstoreService" %>
<%
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
String url="";
url=((String)application.getAttribute("CONTROLLER"))+"/Agregar/Empleado";
url=blobstoreService.createUploadUrl(url);
%>
<form action="<%=url%>" method="post" enctype="multipart/form-data">
<table id="registro" width="110" border="0" cellspacing="0" cellpadding="5">
<tr align="center">
<td colspan="2" align="center">DATOS EMPLEADO</td>
</tr>
<tr>
<td>Nombre</td>
<td><input name="nombre" type="text" value=""> </td>
</tr>
<tr>
<td>Apellido</td>
<td><input name="apellido" type="text" value=""></td>
</tr>
<tr>
<td>Identificacion</td>
<td><input name="identificacion" type="text" value=""></td>
</tr>
<tr>
<td>Fecha de nacimiento</td>
<td><input name="fdn" type="text" value="dd/MM/yyyy"></td>
</tr>
<tr>
<td valign="top">Departamento</td>
<td>
<select name="departamento">
<%
JDO<Departamento> jdo=JDO.getInstance(Departamento.class);
List<Departamento> lista_departamento=jdo.findAll();
for(int i=0;i<lista_departamento.size();i++){
Departamento departamento=lista_departamento.get(i);
out.print("<option value='"+departamento.getId()+"'>"+departamento.getNombre()+"</option>");
}%>
</select>
</td>
</tr>
<tr>
<td>Sueldo</td>
<td><input name="sueldo" type="text" value="00000"></td>
</tr>
<tr>
<td>Auxilio de transporte</td>
<td><input name="transporte" type="text" value="000"></td>
</tr>
<tr>
<td>Foto</td>
<td><input name="foto" type="file"></td>
</tr>
<tr align="center">
<td colspan="2" align="center"><input type="submit" value="Guargar"></td>
</tr>
</table>
</form>
listar_empleado.jsp
<%@ page import="java.util.List"%>
<%@ page import="ingenio.ds.gae.model.entity.Empleado"%>
<%@ page import="ingenio.ds.gae.model.jdo.JDO"%>
<%
JDO<Empleado> jdo=JDO.getInstance(Empleado.class);
List<Empleado> lista_empleado=jdo.findAll();
Double total_sueldo=0.0;
Double total_auxili=0.0;
%>
<table border="1" cellspacing="0" cellpadding="5">
<tr><td colspan="2" align="center" >DATOS NOMINA </td></tr>
<%for(int i=0;i<lista_empleado.size();i++){
Empleado empleado=(Empleado)lista_empleado.get(i);
total_sueldo=total_sueldo+empleado.getSueldo();
total_auxili=total_auxili+empleado.getTransporte();
session.setAttribute("empleado",empleado);
%>
<tr>
<jsp:include page="ver_empleado.jsp"/>
</tr>
<%}%>
<tr><td>TOTAL SUELDO</td> <td><%=total_sueldo%></td> </tr>
<tr><td>TOTAL AUXILIO</td> <td><%=total_auxili%></td> </tr>
<tr><td>TOTAL NOMINA</td> <td><%=total_sueldo+total_auxili%></td> </tr>
</table>
</body>
</html>
ver_empleado.jsp
<%@ page import="java.util.List"%>
<%@ page import="ingenio.ds.gae.model.entity.Empleado"%>
<%@ page import="ingenio.ds.gae.model.entity.Departamento"%>
<%@ page import="ingenio.ds.gae.model.jdo.JDO"%>
<%@ page import="java.util.Date"%>
<%
JDO<Departamento> jdo=JDO.getInstance(Departamento.class);
Empleado empleado=(Empleado)session.getAttribute("empleado");
Departamento departamento =jdo.findByKey(empleado.getDepartamento());
Date hoy=new Date();
int edad= (hoy.getYear()*365+hoy.getMonth()*30+hoy.getDate());
edad=edad-(empleado.getFdn().getYear()*365+empleado.getFdn().getMonth()*30+empleado.getFdn().getDate());
edad=edad/365;
%>
<td>
<img width="150" height="200" src="/servlet/File/Read?blob-key=<%=empleado.getFotoKey().getKeyString() %>"/> <br/>
<%=edad%> Años
</td>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="1">
<tr><td>ID</td><td><%=empleado.getId()%></td></tr>
<tr>
<td>NOMBRE</td><td><%=empleado.getNombre()+" "+empleado.getApellido()%></td>
</tr>
<tr>
<td>IDENTIFICACION</td><td><%=empleado.getIdentificacion()%></td>
</tr>
<tr>
<td>DEPARTAMENTO</td><td><%=(""+departamento.getNombre() +"")%></td>
</tr>
<tr>
<td>SUELDO</td><td><%=empleado.getSueldo()%></td>
</tr>
<tr>
<td>AUXILIO</td><td><%=empleado.getTransporte()%></td>
</tr>
<tr>
<td>TOTAL DEVENGADO</td><td><%=empleado.getTransporte()+empleado.getSueldo()%></td>
</tr>
</table>
</td>
LA CONFIGURACIÓN
XMLs
appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application></application>
<version>1</version>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
<sessions-enabled>true</sessions-enabled>
</appengine-web-app>
web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>EJERCICIO GAE 01 MODELO-VISTA-CONTROLADOR</display-name>
<description> XML de configuracion para aplicar el patron MVC en JSP</description>
<context-param>
<param-name>ABSOLUTEURL</param-name>
<param-value>http://localhost:9999/</param-value>
</context-param>
<servlet>
<servlet-name>controlador</servlet-name>
<servlet-class>ingenio.ds.gae.controller.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>controlador</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
jdoconfig.xml
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>
Properties
loggin.properties
# A default java.util.logging configuration.
# (All App Engine logging is through java.util.logging by default).
#
# To use this configuration, copy it into your application's WEB-INF
# folder and add the following to your appengine-web.xml:
#
#
#
#
#
# Set the default logging level for all loggers to WARNING
.level = WARNING
log4j.properties
# A default log4j configuration for log4j users.
#
# To use this configuration, deploy it into your application's WEB-INF/classes
# directory. You are also encouraged to edit it as you like.
# Configure the console as our one appender
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n
# tighten logging on the DataNucleus Categories
log4j.category.DataNucleus.JDO=WARN, A1
log4j.category.DataNucleus.Persistence=WARN, A1
log4j.category.DataNucleus.Cache=WARN, A1
log4j.category.DataNucleus.MetaData=WARN, A1
log4j.category.DataNucleus.General=WARN, A1
log4j.category.DataNucleus.Utility=WARN, A1
log4j.category.DataNucleus.Transaction=WARN, A1
log4j.category.DataNucleus.Datastore=WARN, A1
log4j.category.DataNucleus.ClassLoading=WARN, A1
log4j.category.DataNucleus.Plugin=WARN, A1
log4j.category.DataNucleus.ValueGeneration=WARN, A1
log4j.category.DataNucleus.Enhancer=WARN, A1
log4j.category.DataNucleus.SchemaTool=WARN, A1
10.414252
-75.526329