jDeveloper Skinning


Hola de nuevo

Tiene mucho que no escribía pero pues creo que me quedé estancado y no había tenido oportunidad de hacer algo diferente (entiéndase trabajar con una nueva tecnología).

Hace 2 meses renuncié a mi trabajo en Element Studios (una agencia digital) para unirme a Globant (una consultora de TI).

Al desarrollar software, muchas de las aplicaciones son de carácter empresarial, por lo cual en la mayoría de los casos, se programa con JAVA o .NET.
En este caso me tocó participar en un proyecto, el cuál se desarrolló en Java utilizando Oracle ADF.

Al dedicarme a trabajar como frontend desde hace ya un tiempo, mi función en el proyecto fue aplicar estilos para que la aplicación fuera agradable a la vista del usuario.

El problema con el que me enfrenté fue que ADF no te permite manipular libremente el DOM y tampoco te permite generar tus propios estilos. ADF tiene un conjunto de herramientas para las cuales genera sus propios selectores, por lo escribir estilos de la manera en la que normalmente lo haría un frontend, no sirve de mucho. Al momento de compilar y renderear en el browser, todo el DOM está construido en tablas (una verdadera patada en las bolas).

Si se requiere modificar los estilos que ADF tiene por default, existe una herramienta que se llama Skin Editor, la cual te permite generar skins (estilos) para aplicarlos en tu proyecto.

Oracle Skin EditorOracle Skin Editor

El Skin Editor funciona de la siguiente manera: si conoces el elemento que quieres modificar, lo seleccionas de la lista de elementos y te mostrará un estado por default y en algunos casos, algún otro estado como podría ser un hover, o un active; en caso de que no existiera algún estado que quisieras modificar, en la parte superior aparece un símbolo de “+”, el cual te permitirá agregar una nueva regla, como podría ser :hover.
Del lado derecho de la ventana aparecen muchos input fields, cada uno de los cuales representa una propiedad del elemento, entiendase, color, background color, font-weight, etc.
Una vez que se definieron los estilos del elemento se tienen que guardar los cambios y posteriormente hacer un deploy del skin a un archivo .jar, el cual podrá ser incluido en el proyecto java.

Issues

El proyecto ya llevaba buen tiempo de desarrollo cuando yo me incorporé y estaba trabajado en versiones. El skin estaba dentro de su propio branch, y el proyecto completo estaba dentro de otro. Lo que hice fue descargar ambos y solo trabajar en el branch que contenía el skin.

En el file system del proyecto, había una carpeta que contenía el archivo .jar que contenía el skin.

En teoría, en la configuración del proyecto, se pueden agregar y/o quitar librerías y/o archivos .jar, en este caso lo que quería hacer era quitar la referencia al .jar del file system y agregar una referencia al branch del skin.

Screenshot (39)

Extrañamente, esto nunca funcionaba, siempre que compilaba el proyecto para ejecutarlo en el browser, nunca veía reflejados los cambios que había hecho. Cosas como un bold en una fuente o un tamaño de letra, no se veían reflejados en el proyecto.
La solución al problema fue eliminar ese archivo .jar que se encontraba en el file system del proyecto y fue entonces que el programa reconoció que el skin que quería utilizar era el que se encontraba en el branch del skin y no el skin que se encontraba en el branch del proyecto.

IE11

Todo iba de maravilla, los estilos funcionaban correctamente, hasta que llegó el momento de hacer pruebas xBrowsing.
Como normalmente se hace, se prometió soporte a las últimas 3 versiones de IE (Internet Explorer). En IE9 y 10 todo se veía bien, hubo que hacer algunos ajustes, pero todo marchaba de maravilla, pero cuando se revisó la aplicación en IE11, muchos de los estilos no se aplicaban y se veía horrible.

Por mucho tiempo estuve buscando en la web alguna solución al problema. Lo que encontré fue que la versión 11.1.1.7 del jDeveloper no es compatible con IE11. En general por lo que entendí, aunque el navegador sea moderno o más reciente, no significa que la aplicación va a funcionar del todo bien. Existe un desfase entre la versión del framework y la versión del browser.
En este caso se daban 2 posibles soluciones:

  1. Descargar un patch para habilitar compatibilidad con navegadores. Para descargar el patch, se necesitaba una licencia, pero me parece que la licencia tiene un costo, y era todo un lío solicitar la licencia con el cliente, ya que al parecer ellos ya habían instalado el parche en su servidor de pruebas. Sin embargo, a pesar de que el servidor ya tenía instalado el patch, seguía sin ver correctamente la aplicación en IE11.
  2. Actualizar a la versión 12 del framework para habilitar la compatibilidad con IE11, además de que con la versión 12 del framework, el doctype que se utiliza en la aplicación es el de HTML5. El problema que se genera es que al actualizar la versión del framework cabe la posibilidad de que la aplicación deje de funcionar, ya que hay elementos que pueden llegar a cambiar o que la manera en la que se utilizan no sea la misma entre una versión y otra.

Encontré un blog, en donde Jonas de Graaff da una solución (workaround) a este problema de compatibilidad con IE11. La solución que se propone es que se le haga creer al servidor que el cliente está haciendo una petición utilizando un explorer 9 o 10 (ésta información se obtiene a través de los encabezados que se envían al servidor). Para esto, se necesita generar un filtro y agregarlo al archivo web.xml.

 package view;  

 import java.io.IOException;  

 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;  

 public class IECompatibleFilter implements Filter {
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  

     String userAgentStr = ((HttpServletRequest)request).getHeader("user-agent");
     // Check to see if we have to do with a IE request. If so, we return a wrapped request.
     if (userAgentStr != null && (userAgentStr.contains("MSIE 1") ||
                                     userAgentStr.contains("Trident"))) {
       ServletRequest wrappedRequest = new WrapperRequest((HttpServletRequest)request);
       chain.doFilter(wrappedRequest, response);
     } else {
       chain.doFilter(request, response);
     }
   }  

   public void destroy() {
   }  

   public void init(FilterConfig arg0) throws ServletException {
   }  

   private class WrapperRequest extends HttpServletRequestWrapper {
     public WrapperRequest(HttpServletRequest request) {
       super(request);
     }  

     public String getHeader(String name) {
       // IE 10: replace 'MSIE 10.x' into 'MSIE 9.x' for ADF 11.1.1.6 and below
       HttpServletRequest request = (HttpServletRequest)getRequest();
       if ("user-agent".equalsIgnoreCase(name) && request.getHeader("user-agent").contains("MSIE 10")) {
         return request.getHeader("user-agent").replaceAll("MSIE [^;]*;", "MSIE 9.0;");
       }
       // IE 11: replace the whole agent-string into an MSIE 9.0 string for ADF 11.1.1.6 and below
       // or MSIE 10.0 for ADF 11.1.1.7 or higher
       if ("user-agent".equalsIgnoreCase(name) && request.getHeader("user-agent").contains("Trident")) {
         //Choose your preferred version
         String newAgentStr = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.2; Trident/6.0)";
         return newAgentStr;
       }
       return request.getHeader(name);
     }
   }
 }

 

 ...
  <filter>
   <filter-name>IECompatibleFilter</filter-name>
   <filter-class>view.IECompatibleFilter</filter-class>
  </filter>
  <filter>
   <filter-name>trinidad</filter-name>
   <filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class>
  </filter>
 ...
  <filter-mapping>
   <filter-name>IECompatibleFilter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>
  <filter-mapping>
   <filter-name>trinidad</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
   <dispatcher>FORWARD</dispatcher>
   <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
 ...

Agregando estos 2 bloques de código en el proyecto, pude ver correctamente la aplicación en IE11. De esta manera le quite un peso de encima al equipo de desarrollo y el cliente quedó contento.

La verdad es que soy un inexperto en java, en caso de que existieran dudas o comentarios, podrían ir directamente al blog de Jonas, de donde saqué la información.

Anuncios
Esta entrada fue publicada el 3 julio, 2015 a las 14:01. Se guardó como Tech y etiquetado como , , , , , , , , , , , , , . Añadir a marcadores el enlace permanente. Sigue todos los comentarios aquí gracias a la fuente RSS para esta entrada.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: