www.opitz-consulting.com/go/3-4-11
JavaScript ist eine sehr dynamische Sprache und verh?lt sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag zeigt, wie Cross-Browser-Tests f¨¹r JavaScript entwickelt werden k?nnen.
Die Java- und JavaScript-Experten Stefan Scheidt und Tobias Bosch von OPITZ CONSULTING pr?sentierten diesen Vortrag bei der Jax 2012 am 18.04.2012 in Mainz.
--
Sie m?chten mobile Gesch?ftsl?sungen in Ihrem Unternehmen nutzen? Wir beraten Sie gerne. Lesen Sie hier mehr zu unseren Leistungen in diesem Bereich und informieren Sie sich zu unserem Workshop f¨¹r die professionelle Web-App-Entwicklung mit JavaScript: www.opitz-consulting.com/go/3-4-898
JavaScript ist eine sehr dynamische Sprache und verh?lt sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag zeigt, wie Cross-Browser-Tests f¨¹r JavaScript entwickelt werden k?nnen.
Vortrag von der MobileTech Conference 2011
JavaScript ist eine sehr dynamische Sprache und verh?lt sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag zeigt, wie Cross-Browser-Tests f¨¹r JavaScript entwickelt werden k?nnen.
Vortrag von der MobileTech Conference 2011
3. EL PROBLEMA
? Spring naci¨® como una herramienta de
configuraci¨®n e integraci¨®n de tecnolog¨ªas
dispares
? No siempre podemos esperar que dichas
tecnolog¨ªas dispares se configuren
necesariamente con Spring
?Para eso existe Spring!
3
4. EL PROBLEMA
? ItsNat es un framework web
Java que tiene su propio sistema de
configuraci¨®n
? ItsNat se configura de la forma m¨¢s potente y
flexible que existe
A trav¨¦s de llamadas a m¨¦todos
? Desde el d¨ªa 0 se concibi¨® para poder ser
¡°sobrecargado¡± con APIs de m¨¢s alto nivel, por
ejemplo con¡ ?Spring!
4
8. PERO HAY QUE CONOCER C?MO SE
CONFIGURA ItsNat PARA APLICAR
Spring
8
9. EJEMPLO ItsNat ¡°PURO¡±: el servlet
? ItsNat no define un servlet concreto, el usuario
debe crear uno (o m¨¢s)
¨C Se configura en el m¨¦todo init
? La inmensa mayor¨ªa de los flags de configuraci¨®n usados
son opcionales (coinciden con el valor por defecto)
public class servlet extends HttpServletWrapper
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet();
ItsNatServletConfig itsNatConfig =
itsNatServlet.getItsNatServletConfig();
ItsNatServletContext itsNatCtx =
itsNatConfig.getItsNatServletContext();
9
10. EJEMPLO ItsNat ¡°PURO¡± : el servlet
? ItsNatHttpServlet, ItsNatServletConfig
y ItsNatServletContext son los objetos ra¨ªz de
configuraci¨®n en ItsNat
itsNatCtx.setMaxOpenDocumentsBySession(6);
String serverInfo = getServletContext().getServerInfo();
boolean gaeEnabled = serverInfo.startsWith(
"Google App Engine");
itsNatCtx.setSessionReplicationCapable(gaeEnabled);
itsNatCtx.setSessionSerializeCompressed(false);
itsNatCtx.setSessionExplicitSerialize(false);
10
13. EJEMPLO ItsNat ¡°PURO¡± : el servlet
? Ahora registramos en el servlet un template
core_example.xhtml con su procesador de carga
CoreExampleLoadListener
¨C Ejemplo sencillo de p¨¢gina HTML con AJAX
String pathPrefix = getServletContext().getRealPath("/");
pathPrefix += "/WEB-INF/pages/manual/";
ItsNatDocumentTemplate docTemplate;
docTemplate = itsNatServlet.registerItsNatDocumentTemplate(
"manual.core.example","text/html",
pathPrefix + "core_example.xhtml");
docTemplate.addItsNatServletRequestListener(
new CoreExampleLoadListener());
13
14. EJEMPLO ItsNat ¡°PURO¡± : el servlet
? Y otro ejemplo de generaci¨®n de p¨¢gina XML
docTemplate = itsNatServlet.registerItsNatDocumentTemplate(
"manual.core.xmlExample","text/xml",
pathPrefix + "xml_example.xml");
docTemplate.addItsNatServletRequestListener(
new CoreXMLExampleLoadListener());
? Que a su vez inserta un template fragment
¨C Los template fragment no tienen procesador
ItsNatDocFragmentTemplate docFragTemplate;
docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate(
"manual.core.xmlFragExample","text/xml",
pathPrefix + "xml_fragment_example.xml");
14
16. EJEMPLO ItsNat ¡°PURO¡±
? CoreExampleLoadListener es un mero lanzador del
gestor del documento en cada carga de p¨¢gina
public class CoreExampleLoadListener
implements ItsNatServletRequestListener
{
public CoreExampleLoadListener() {}
public void processRequest(ItsNatServletRequest request,
ItsNatServletResponse response)
{
ItsNatHTMLDocument itsNatDoc =
(ItsNatHTMLDocument)request.getItsNatDocument();
new CoreExampleDocument(itsNatDoc);
}
}
16
17. EJEMPLO ItsNat ¡°PURO¡±
? CoreExampleDocument gestiona el estado de la
p¨¢gina recibiendo los eventos AJAX
public class CoreExampleDocument implements EventListener
{
protected ItsNatHTMLDocument itsNatDoc;
protected Element clickElem1;
protected Element clickElem2;
public CoreExampleDocument(ItsNatHTMLDocument itsNatDoc)
{
this.itsNatDoc = itsNatDoc;
load();
}
...
17
21. EJEMPLO ItsNat ¡°PURO¡±
? CoreXMLExampleLoadListener : como en XML
no hay AJAX no necesitamos una clase wrapper de
documento. Se incluye el template fragment
manual.core.xmlFragExample
public class CoreXMLExampleLoadListener
implements ItsNatServletRequestListener
{
public CoreXMLExampleLoadListener() { }
public void processRequest(ItsNatServletRequest request,
ItsNatServletResponse response)
{
ItsNatDocument itsNatDoc = request.getItsNatDocument();
Document doc = itsNatDoc.getDocument();
Element discsElem = doc.getDocumentElement();
...
21
24. OBJETIVOS
1. Un ¨²nico servlet gen¨¦rico reutilizable:
itsnatspring.itsnatservlet
2. La configuraci¨®n se realizar¨¢ totalmente en un
archivo XML de Spring en el classpath:
itsnatex/spring.xml
3. Las ¨²nicas clases del usuario ser¨¢n las clases
contenedoras del documento ItsNat (=p¨¢gina):
itsnatex.CoreExampleDocument
itsnatex.CoreXMLExampleDocument
24
25. CONSECUENCIAS
? Adem¨¢s del servlet gen¨¦rico reutilizable
necesitaremos una serie de clases de utilidad
tambi¨¦n gen¨¦ricas y reutilizables
? Dichas clases quedar¨¢n incompletas, s¨®lo
cubriremos las necesidades de este ejemplo
¨C ItsNat tiene m¨¢s m¨¦todos de configuraci¨®n
25
26. EL SERVLET
package itsnatspring;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import org.itsnat.core.http.HttpServletWrapper;
import org.itsnat.core.http.ItsNatHttpServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
public class itsnatservlet extends HttpServletWrapper
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet();
GenericApplicationContext rootContext = new GenericApplicationContext();
ItsNatBeansRegistryUtil.registerSingletons(rootContext, itsNatServlet);
rootContext.refresh();
26
27. EL SERVLET
String springXMLPath = config.getInitParameter("spring_config");
if (springXMLPath == null)
throw new RuntimeException("spring_config initialization
parameter is not specified in web.xml");
ApplicationContext context =
new ClassPathXmlApplicationContext(
new String[] {springXMLPath},rootContext);
}
}
? Se registran como singleton los objetos de
configuraci¨®n de ItsNat en un
ApplicationContext gen¨¦rico ra¨ªz y se carga
en otro nuevo nuestro XML Spring
27
28. ItsNatBeansRegistryUtil
package itsnatspring;
import org.itsnat.core.ItsNatServletConfig;
import org.itsnat.core.ItsNatServletContext;
import org.itsnat.core.http.ItsNatHttpServlet;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
public class ItsNatBeansRegistryUtil
{
public final static String itsNatHttpServletBean = "itsNatHttpServlet";
public final static String itsNatServletConfigBean = "itsNatServletConfig";
public final static String itsNatServletContextBean = "itsNatServletContext";
public static ItsNatHttpServlet getItsNatHttpServlet(ApplicationContext context) {
return context.getBean(itsNatHttpServletBean,ItsNatHttpServlet.class);
}
public static ItsNatServletConfig getItsNatServletConfig(ApplicationContext context){
return context.getBean(itsNatServletConfigBean,ItsNatServletConfig.class);
}
public static ItsNatServletContext getItsNatServletContext(ApplicationContext context){
return context.getBean(itsNatServletContextBean,ItsNatServletContext.class);
}
28
29. ItsNatBeansRegistryUtil
public static void registerSingletons(AbstractApplicationContext context,
ItsNatHttpServlet itsNatServlet)
{
ItsNatServletConfig itsNatServletCofig =
itsNatServlet.getItsNatServletConfig();
ItsNatServletContext itsNatServletContext =
itsNatServletCofig.getItsNatServletContext();
ConfigurableListableBeanFactory beanFact = context.getBeanFactory();
beanFact.registerSingleton(itsNatHttpServletBean,itsNatServlet);
beanFact.registerSingleton(itsNatServletConfigBean,itsNatServletCofig);
beanFact.registerSingleton(itsNatServletContextBean,itsNatServletContext);
}
}
? El resultado es el registro manual como
singleton de los objetos de conf. de ItsNat
29
32. ItsNatServletContextBean
? Este bean singleton de utilidad nos sirve para
recordar los flags definidos y al final registrarlos de
forma efectiva en el ItsNatServletContext
¨C Como se necesita el ApplicationContext
implementamos
ApplicationContextAware
¨C Como necesitamos actuar cuando termine la
configuraci¨®n del bean, implementamos
InitializingBean
32
37. LocaleBean
? Este ¡°factory bean¡± nos permite configurar un objeto y
hacerlo p¨²blico a trav¨¦s del ¡°factory method¡±
getLocale()
package itsnatspring;
import java.util.Locale;
import org.springframework.beans.factory.InitializingBean;
public class LocaleBean implements InitializingBean
{
protected String language;
protected String country;
protected Locale locale;
public LocaleBean() { }
public String getCountry() { return country; }
public void setCountry(String country) { this.country = country; }
public String getLanguage() { return language; }
37
38. LocaleBean
public void setLanguage(String language) { this.language = language; }
public Locale getLocale() { return locale; }
@Override
public void afterPropertiesSet() throws Exception
{
Locale[] availablelocales = Locale.getAvailableLocales();
for(Locale locale : availablelocales)
if (locale.getLanguage().equals(language) &&
locale.getCountry().equals(country))
{
this.locale = locale;
return;
}
this.locale = new Locale(language,country);
}
}
38
39. ? Desde ahora s¨®lo mostraremos las clases de
utilidad m¨¢s interesantes
? A partir del XML puede intuirse la
funcionalidad de las dem¨¢s
¨C Obteni¨¦ndose los singleton de configuraci¨®n de
ItsNat a trav¨¦s del ApplicationContext
¨C El cual es obtenido implementando
ApplicationContextAware
39
42. ItsNatServletRequestListenerBean
? Este bean es MUY interesante pues act¨²a como ¡°ItsNat
document loader listener¡± gen¨¦rico
? Nos obligar¨¢ a que la clase procesadora del documento
implemente una sencilla interfaz especial llamada:
ItsNatDocumentInitialize
package itsnatspring;
import org.itsnat.core.ItsNatServletRequest;
import org.itsnat.core.ItsNatServletResponse;
public interface ItsNatDocumentInitialize
{
public void load(ItsNatServletRequest request,
ItsNatServletResponse response);
}
42