Mostrando entradas con la etiqueta JDeveloper. Mostrar todas las entradas
Mostrando entradas con la etiqueta JDeveloper. Mostrar todas las entradas

jueves, 27 de febrero de 2020

jQuery en ADF

Ejemplo práctico de como usar jQuery en ADF, en este caso como cambiar el type de un inputText para el caso de querer mostrar los caracteres de un campo contraseña.

<af:resource type="javascript"
                     source="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"/>
        <af:resource type="javascript">

          function showPasswordMethod(e) {
              var inputPassword1 = $("input[id*=it2]")[0];
              if (inputPassword1.type == "text") {
                  inputPassword1.type = "password";
                  $("img[id*=imgShowPassword]")[0].src = "/webcenter/../wcstatic/img/genericas/eye_black.png";
              }
              else {
                  inputPassword1.type = "text";
                  $("img[id*=imgShowPassword]")[0].src = "/webcenter/../wcstatic/img/genericas/eye_red.png";
              }
          }
        </af:resource>


<af:inputText label="Contraseña actual" id="it2" required="true"                                     styleClass="resetPasswordField oldpwd" value="#{resetPasswordBean.oldpassword}"
 secret="true" autoComplete="off"/>

<af:image source="/../wcstatic/img/genericas/eye_black.png"                                  id="imgShowPassword" inlineStyle="position: absolute;bottom: 190px; right: 14px; cursor: pointer;">
      <af:clientListener method="showPasswordMethod" type="click"/>
</af:image>


miércoles, 20 de febrero de 2019

Atributo ClearCacheOnCommit en ADF

En un desarrollo reciente disponemos de una tabla ADF con varios registros, basado en un VO Entity updatable en donde se puede operar con acciones CreateInsert y Delete, con su posterior Commit, cada row con un atributo PK independiente.

Nos surgió la problemática de que, sin salir de la taskflow, al realizar el CreateInsert y a continuación realizar el Delete de esa misma row (con las opciones out of the box de binding mediante getCurrent) veíamos como se borraba de la tabla pero no de base de datos.

¿Cual era el problema? Para explicarlo mostramos el ciclo de vida de ADF:

Resultado de imagen de create insert delete adf diagram binding 


Cuando se realiza la operación CreateInsert, se inserta y accede al binding correspondiente, se accede al AppModule y se inserta en base de datos, pero no se actualiza el datacontrol con dicha información, es decir, se inserta la row en el iterator pero no ha refrescado con la PK que ha devuelto la base de datos, por lo que la row insertada y que se ve en la tabla no tiene actualizado el campo PK devuelto por el modelo.
Como se puede deducir, si no refrescas el iterator o pides de nuevo los datos a la base de datos, esa row no se actualiza con su verdadero PK por lo que al borrar inmediatamente después lo va a borrar del iterator pero no de base de datos.

La solución consiste en usar el atributo ClearCacheOnCommit en el fichero AppModule de nuestra aplicación:




Dicho atributo permite refrescar los VO después de realizar la operación Commit, por lo que siempre vamos a tener en este caso deseablemente el valor introducido en base de datos.
Si no se refleja esta variable en el AppModule, por defecto no aparecerá y tomará el valor "false", como se indica en la documentación (esto es del método isClearCacheOnCommit de la interfaz Transaction para consultar dicho valor):

isClearCacheOnCommit

public boolean isClearCacheOnCommit()
Returns the flag indicating whether all Entity Object caches will be cleared after the transaction is committed.After the transaction is committed, the value of this flag is used to determine whether the Entity Object caches are cleared or not. If this flag value is false, the cache contents are kept. In this case, the cache may contain data that is stale in that it does not match the newest data (changes made by another user and committed).
If this flag is true, the caches are cleared after the transaction is committed. When the user brings in data by traversing row collection, the latest data from the database will be brought into Entity caches.
Returns:
the current value of clear-cache-on-commit flag.
See Also:
RowSet.executeQuery(), setClearCacheOnCommit(boolean val)








viernes, 13 de mayo de 2016

Error al desplegar aplicación ADF en Weblogic nuevo

Cuando hemos montado un Weblogic que albergará aplicaciones ADF, la primera vez que intentamos desplegar nos aparece el error siguiente:

Error while processing library references. Unresolved application library references, defined in weblogic-application.xml: [Extension-Name: adf.oracle.domain, exact-match: false]

Esto es porque hay librerias de ADF de Weblogic que no se han aplicado a todos los destinos (en concreto al manejado de ADF). Para ello debemos asegurarnos que las siguientes librerías tengan aplicado como destino tanto el nodo Admin como el manejado:

  • adf.oracle.domain
  • adf.oracle.businesseditor
  • adf.oracle.domain.webapp
  • jstl
  • jsf
La aplicación del destino se realiza en la siguiente pestaña de la librería (en Deployments) en concreto:





jueves, 28 de abril de 2016

Refrescar un iterador Bean Data Control en ADF

Cuando implementamos un formulario ADF basado en un Bean Java como es un Data Control, nos hemos encontrado que al navegar en una misma Bounded Taskflow entre diferentes jsff, los datos modificados del Bean no se han actualizado en la siguiente página.

Esto es debido a que cuando se modifican los datos del Bean mediante Java, hay que hacer un refresh del iterator que se alimenta del Data Control.
Por defecto la opción "CacheResults" de un iterator va a estar como true:




Si no queremos modificar esta opción, el método más adecuado es añadir el método "Execute" del iterator antes de cargar la página que no estaba refrescando. El método "Execute" se encuentra dentro de las Operations del iterator en la pestaña de Data Controls:

 


lunes, 7 de marzo de 2016

Integración WS-ADF

Vamos a mostrar la integración de un WS para su consumo desde ADF. Para ello vamos a realizar los siguientes pasos:

1º) Creamos un proyecto Java donde residirá el punto de entrada al WS.











2º) Seleccionamos en el proyecto con New => Web Service  Client and Proxy.

3º) Indicamos la URL del WSDL del servicio e indicamos que queremos copiar el WSDL en nuestro proyecto.







4º) Dejamos las opciones por defecto hasta "Policy" donde debemos marcar la política del WS (tipo de autenticación y seguridad). En nuestro caso es la oracle/wss_http_token_service_policy




5º) Observamos la estructura de ficheros que se han creado. En la clase nameServicioPortClient se muestra un ejemplo de como se crea el servicio:

    public static void main(String[] args) {
        GlanceVolcadoBindQSService glanceVolcadoBindQSService = new GlanceVolcadoBindQSService();

        // Configure security feature
        SecurityPoliciesFeature securityFeatures = new SecurityPoliciesFeature(new String[] {
                                                                               "oracle/wss_http_token_client_policy" });
        GlanceVolcadoPtt glanceVolcadoPtt = glanceVolcadoBindQSService.getGlanceVolcadoBindQSPort(securityFeatures);
        // Add your code to call the desired methods.


    }


6º) Creamos un paquete aparte donde crearemos propiamente el servicio:

    public int getGlanceVolcado(String cdIdenti, int pendientes, Date fecha) {
        System.out.println("AnaliticasOperacionesServiceImpl::Llamada servicio...");
        int respuesta = -1;
        GlanceVolcadoBindQSService glanceVolcadoBindQSService = new GlanceVolcadoBindQSService();

        // Configure security feature
        SecurityPoliciesFeature securityFeatures = new SecurityPoliciesFeature(new String[] {
                                                                               "oracle/wss_http_token_client_policy" });


// Add your code to call the desired methods.

//Objecto que sirve el servicio
         GlanceVolcadoPtt glanceVolcadoPtt = glanceVolcadoBindQSService.getGlanceVolcadoBindQSPort(securityFeatures);
        try {

//Cogemos los parámetros de la request del contexto, en este caso el usuario y contraseña de la //policy
            Map<String, Object> reqContext = ((BindingProvider) glanceVolcadoPtt).getRequestContext();
            reqContext.put(BindingProvider.USERNAME_PROPERTY, AnaliticasOperacionesConstants.wss_http_token_client_policy_username);
            reqContext.put(BindingProvider.PASSWORD_PROPERTY, AnaliticasOperacionesConstants.wss_http_token_client_policy_pwd);



//Creamos un objecto de tipo solicitud para pasar los parámetros necesarios
            VolcadoRequestType request = new VolcadoRequestType();
            request.setCdidenti(cdIdenti);
            DatatypeFactory df = DatatypeFactory.newInstance();
            GregorianCalendar gc = new GregorianCalendar();
            gc.setTimeInMillis(fecha.getTime());
            request.setFechaIni(df.newXMLGregorianCalendar(gc));
            request.setPendientes(pendientes);
            System.out.println("AnaliticasOperacionesServiceImpl::getGlanceVolcado::cdIdenti::"+cdIdenti);
            System.out.println("AnaliticasOperacionesServiceImpl::getGlanceVolcado::pendientes::"+pendientes);
            System.out.println("AnaliticasOperacionesServiceImpl::getGlanceVolcado::fecha::"+fecha);

//Hacemos la llamada al servicio y recogemos la respuesta
            VolcadoResponseType response = glanceVolcadoPtt.glanceVolcado(request);
            if (response != null) {

//El resultado de la llamada al servicio
                respuesta = response.getResult();
                System.out.println("AnaliticasOperacionesServiceImpl::getGlanceVolcado::Respuesta::"+response.getResult());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("AnaliticasOperacionesServiceImpl::Fin llamada servicio");
        return respuesta;
    }


 6º) En nuestro proyecto ViewController, primeramente en "Dependencies" debemos añadir el build output del proyecto del servicio para poder utilizar sus clases.





7º) Creamos una clase Bean que contendrá la llamada al método del servicio de la clase creada anteriormente:

public class PruebaBean {
    public PruebaBean() {
        super();
    }
   
    public int getGlanceVolcado(String cdIdenti, int pendientes, Date fecha){
        AnaliticasOperacionesServiceImpl impl = new AnaliticasOperacionesServiceImpl();
        return impl.getGlanceVolcado(cdIdenti, pendientes, fecha);
    }
}



8º) Creamos un DataControl de la clase creada, mediante botón derecho en la clase "Create Data
Control":







9º) Ahora el método puede ser accesible desde cualquier taskflow y realizar la llamada al servicio



 





martes, 23 de febrero de 2016

Paso variables entre capa View-Controller y Model

Se nos plantea la problemática de necesitar pasar unos parámetros de la capa View-Controller al Model, en concreto para hacer un override del método prepareSession de Model para setear el contexto del usuario logado. A nivel de MVC no está bien visto que la capa VC acceda al M, pero es la única forma que hemos encontrado para hacerlo.

Para ello, en el bean de Session definido en la aplicación, definimos las dos variables que necesitamos pasar al Model:

        //Preparamos en session el cdempresa y cddelega
        ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
        HttpSession userSession = (HttpSession) ectx.getSession(true);
        userSession.setAttribute("cdDelega", cddelega);
        userSession.setAttribute("cdEmpresa", (cdempresa+cdempresa));


 Ahora, en el implement del Module:

        Map sessionScope = ADFContext.getCurrent().getSessionScope();
        if (sessionScope.get("cdDelega") != null && sessionScope.get("cdEmpresa") != null) {
            String cdDelega = (String) sessionScope.get("cdDelega");
            String cdEmpresa = (String) sessionScope.get("cdEmpresa");

            ...

miércoles, 4 de noviembre de 2015

Escapar texto HTML con la opción "target" de a href

El planteamiento es el siguiente: se pretende que, en un texto HTLM que contiene un elemento a href incrustado en una página ADF, se produzca la redirección a la nueva página pero en una nueva ventana del navegador.

ADF tiene un elemento llamado "outputFormatted" que permite escapar texto HTML en una caja de texto. Hasta aquí todo correcto. El problema viene que ese texto HTML contiene un elemento a href con la etiqueta target ="_blank", por lo que se quiere que dicha redirección vaya a una nueva página en blanco. Si traducimos esto a ADF quedaría un bundle properties:

OT_FORMATTED_LINK=<html>Esto es un texto formateado con un <a href="http://www.google.es" target="_blank" title="El enlace">enlace</a> entre medio del cuerpo</html>

Si esto lo introducimos en el outputFormatted quedaría:

 <af:outputFormatted value="#{bundle.OT_FORMATTED_LINK}" id="of1"/>

donde bundle es el nombre del bundle dado en las properties del proyecto, y en el faces-config.

Si hacemos esto, la opción target del elemento "a" no la ejecuta.

Solución: sustituir el elemento outputFormatted por un outputText, con la propiedad escape="false".

<af:outputText value="#{bundle.OT_FORMATTED_LINK}" id="ot1"
                         escape="false"/>


lunes, 29 de junio de 2015

Llamada función JS desde managed bean

Para realizar una llamda a una función JS desde un managed bean (por ejemplo, cuando se inicialice el constructor de la clase), hay que proceder de la siguiente manera:

import javax.faces.context.FacesContext;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

FacesContext context = FacesContext.getCurrentInstance();
ExtendedRenderKitService service = Service.getRenderKitService(context, ExtendedRenderKitService.class);
service.addScript(context, "var popup = AdfPage.PAGE.findComponent('idPopup'); popup.show();");