/**********************************************************************
* $Source: /cvsroot/jameica/jameica.webadmin/src/de/willuhn/jameica/webtools/BeanHandler.java,v $
* $Revision: 1.3 $
* $Date: 2011/06/28 09:56:26 $
* $Author: willuhn $
*
* Copyright (c) by willuhn - software & services
* All rights reserved
*
**********************************************************************/
package de.willuhn.jameica.webtools;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import de.willuhn.annotation.Inject;
import de.willuhn.annotation.Lifecycle;
import de.willuhn.datasource.BeanUtil;
import de.willuhn.jameica.webadmin.annotation.Request;
import de.willuhn.jameica.webadmin.annotation.Response;
import de.willuhn.logging.Logger;
/**
* Hilfsklasse fuer den Lifecycle der Beans.
*/
public class BeanHandler
{
private static Map<String,Object> context = new HashMap<String,Object>();
/**
* Liefert die Instanz der angegebenen Bean.
* Die Funktion wertet intern aus, ob fuer die Bean ein
* Lifecycle definiert ist und entscheidet selbst, ob eine neue Instanz
* erzeugt wird oder eine existierende wiederverwendet wird.
* Ist keine Lifecycle-Annotation angegeben, wird per Default
* ein Request-Lifecycle verwendet.
* @param config die Request-Config.
* @param className Name der Klasse der Bean.
* @return die Instanz der Bean.
* @throws Exception wenn sich die Bean nicht instanziieren liess.
*/
static Object getBean(RequestConfig config, String className) throws Exception
{
// Keine Klasse angegeben
if (className == null || className.length() == 0)
{
Logger.debug("no class name given");
return null;
}
// Den folgenden Code koennte man mit einem try/finally auch
// so umstellen, dass der Aufruf "injectContext" nur einmal
// noetig ist. So ist es aber besser lesbar, da die Lifecycles
// besser getrennt sind.
Object bean = context.get(className);
////////////////////////////////////////////////////////////////////////////
// Lifecycle "CONTEXT"
if (bean != null)
{
// Aktuelle Annotations registrieren.
injectContext(bean,config);
return bean;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Lifecycle "SESSION"
HttpSession session = config.getRequest().getSession();
bean = session.getAttribute(className);
if (bean != null)
{
// Wir haben die Bean noch in der Session. Dann
// koennen wir sie auch nochmal verwenden
injectContext(bean,config);
return bean;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Lifecycle "REQUEST" und Erst-Request
// Wenn wir hier angekommen sind, hat die Bean entweder
// den Lifecycle "REQUEST" oder es ist der allererste Aufruf.
// Wir muessen so oder so eine neue Instanz erzeugen
Class c = config.getClassloader().loadClass(className);
bean = c.newInstance();
// Lifecycle ermitteln
Lifecycle lc = (Lifecycle) c.getAnnotation(Lifecycle.class);
Lifecycle.Type type = lc != null ? lc.value() : Lifecycle.Type.REQUEST;
switch(type)
{
case CONTEXT:
context.put(className,bean);
break;
case SESSION:
session.setAttribute(className,bean);
break;
}
injectContext(bean,config);
return bean;
////////////////////////////////////////////////////////////////////////////
}
/**
* Injiziert die Context-Infos.
* @param bean die Bean.
* @throws Exception
*/
private static void injectContext(Object bean, RequestConfig config) throws Exception
{
Inject.inject(bean,Request.class,config.getRequest());
Inject.inject(bean,Response.class,config.getResponse());
}
/**
* Durchsucht die Bean nach Properties mit den gleichen Namen wie Parameter im Request
* und uebernimmt die zugehoerigen Werte des Requests ueber die gleichnamigen Setter
* in die Bean.
* @param bean die Bean.
* @param request der HTTP-Request.
* @throws Exception
*/
static void applyRequest(Object bean, HttpServletRequest request) throws Exception
{
Enumeration e = request.getParameterNames();
while (e.hasMoreElements())
{
String name = null;
String value = null;
try
{
name = (String) e.nextElement();
value = request.getParameter(name);
BeanUtil.set(bean,name,value);
}
catch (Exception ex)
{
// Das koennen wir durchaus ignorieren - das darf passieren
}
}
}
}
/**********************************************************************
* $Log: BeanHandler.java,v $
* Revision 1.3 2011/06/28 09:56:26 willuhn
* @N Lifecycle-Annotation aus jameica.webadmin in util verschoben
*
* Revision 1.2 2011-03-30 12:14:05 willuhn
* @N Neuer Injector fuer DI
*
* Revision 1.1 2010-10-27 14:32:18 willuhn
* @R jameica.webtools ist jetzt Bestandteil von jameica.webadmin. Das separate webtools-Plugin ist nicht mehr noetig
*
* Revision 1.2 2010/03/04 13:20:43 willuhn
* @C Request-Properties nicht auf globale Beans anwenden
*
* Revision 1.1 2010/02/01 15:13:36 willuhn
* @N Neues Element "beans" fuer globale Beans in webtools.xml
* @N Default-Action via Attribut "action"
*
**********************************************************************/