Monday, July 29, 2013

Using Spring Managed Beans in ADF application


In one of previous blogs I have written about “Custom ADF Web application to search users in OIM 11g r2”. In the same sample I have introduced Usage of Spring Managed Beans in the Backing Beans. This is how i have achieved it.

First I have created a bus context xml file in Model Project which defines all the service layer beans as shown below:



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>classpath*:customoimapp-services.properties</value>
      </list>
    </property>
  </bean>
  <bean id="oimConnectionFactory"
        class="oracle.iam.ui.custom.model.connection.OIMConnectionFactory">
    <property name="namingProviderURL"
              value="${customoimapp.JAVA_NAMING_PROVIDER_URL}"/>
    <property name="securityAuthLoginConfigKey"
              value="${customoimapp.JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY}"/>
  </bean>
  <bean id="oimService"
        class="oracle.iam.ui.custom.model.service.impl.OIMServiceImpl">
    <property name="oimConnectionFactory" ref="oimConnectionFactory"/>
    <property name="adminUserid" value="${customoimapp.adminUserid}"/>
    <property name="adminPassword" value="${customoimapp.adminPassword}"/>
  </bean>
</beans>


the properties file looks that has all the values defined is as follows:


customoimapp.JAVA_NAMING_PROVIDER_URL=t3://oimhome.com:14000
customoimapp.JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY=C:\\Software\\OIM_DESIGNCONSOLE\\designconsole\\config\\authwl.conf
customoimapp.adminUserid=xelsysadm
customoimapp.adminPassword=Passw0rd


OIMConnectionFactory class and OIMServiceImpl class looks like this:


package oracle.iam.ui.custom.model.connection;

import java.util.Hashtable;

import oracle.iam.platform.OIMClient;

public class OIMConnectionFactory {
    public OIMConnectionFactory() {
        super();
    }

    protected static final String JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY = "java.security.auth.login.config";
    private String namingProviderURL;
    private String securityAuthLoginConfigKey;

    public OIMClient init() {
        OIMClient oimClient = null;
        Hashtable env = new Hashtable();
        env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, namingProviderURL);
        env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, OIMClient.WLS_CONTEXT_FACTORY);
        System.setProperty("OIM.AppServerType", "wls");
        System.setProperty("APPSERVER_TYPE", "wls");
        System.setProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY, securityAuthLoginConfigKey);
        oimClient = new OIMClient(env);
        return oimClient;
    }


    public void setNamingProviderURL(String namingProviderURL) {
        this.namingProviderURL = namingProviderURL;
    }

    public void setSecurityAuthLoginConfigKey(String securityAuthLoginConfigKey) {
        this.securityAuthLoginConfigKey = securityAuthLoginConfigKey;
    }
}



OimServiceImpl Class:


package oracle.iam.ui.custom.model.service.impl;

import com.bea.security.providers.xacml.entitlement.parser.Users;

import oracle.iam.ui.custom.model.connection.OIMConnectionFactory;
import oracle.iam.ui.custom.model.service.OIMService;

import oracle.iam.ui.custom.model.service.bean.OIMUserBean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.security.auth.login.LoginException;

import oracle.iam.identity.exception.UserSearchException;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.platform.OIMClient;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;

public class OIMServiceImpl implements OIMService {
    public OIMServiceImpl() {
        super();
    }

    public static final String FIRST_NAME = "First Name";
    public static final String LAST_NAME = "Last Name";
    public static final String USER_LOGIN = "User Login";
    public static final String EMAIL = "Email"; 
    public static final String STARTROW = "STARTROW";
    public static final String ENDROW = "ENDROW";
    private OIMConnectionFactory oimConnectionfactory;
    private String adminUserid;
    private String adminPassword;

    /**
     * @param firstName
     * @param lastName
     * @return
     */
    public List<OIMUserBean> searchUsersInOIM(String firstName, String lastName){
        
        List<OIMUserBean> usersList = new ArrayList<OIMUserBean>();
        HashMap<String, Object> configParam = new HashMap<String, Object>();
        
        OIMClient oimClient = oimConnectionfactory.init();
        try {
            oimClient.login(adminUserid, adminPassword.toCharArray());
            System.out.println("Login Successful");
        } catch (LoginException e) {
            e.printStackTrace();
        }
        configParam.put(STARTROW, 0);
        configParam.put(ENDROW, 1000);
        String userLogin = null;
        List<User> users =null;
        
        System.out.println("Search Criteria: First Name entered is: " + firstName);
        System.out.println("Search Criteria: Last Name entered is: " + lastName);
        
        
        SearchCriteria searchCriteria = new SearchCriteria(FIRST_NAME, firstName+"*", SearchCriteria.Operator.EQUAL);
        SearchCriteria searchCriteria1 = new SearchCriteria(LAST_NAME, lastName+"*", SearchCriteria.Operator.EQUAL); 
        SearchCriteria searchCriteria2 = new SearchCriteria(searchCriteria,searchCriteria1, SearchCriteria.Operator.AND); 
        
        UserManager userManager = oimClient.getService(UserManager.class);

        try {
            users = userManager.search(searchCriteria2, null, configParam);
            System.out.println("Search Results: Size is: " + users.size());
        } catch (UserSearchException e) {
            e.printStackTrace();
        }
        if (users != null && users.size() > 0 ){
            for(User user : users){
                OIMUserBean userFromOIM = new OIMUserBean();
                userFromOIM.setFirstName((String)user.getAttribute(FIRST_NAME));
                userFromOIM.setLastName((String)user.getAttribute(LAST_NAME));
                userFromOIM.setUserId((String)user.getAttribute(USER_LOGIN));
                userFromOIM.setEMail((String)user.getAttribute(EMAIL));
                usersList.add(userFromOIM);
            }
        }
        System.out.println("Return Results: Size is: " + usersList.size());
        return usersList;
    }

    public void setOimConnectionfactory(OIMConnectionFactory oimConnectionfactory) {
        this.oimConnectionfactory = oimConnectionfactory;
    }


    public void setAdminUserid(String adminUserid) {
        this.adminUserid = adminUserid;
    }

    public void setAdminPassword(String adminPassword) {
        this.adminPassword = adminPassword;
    }
}


That concludes changes to the Model Project. Now coming to the View Project:

Added a beanRefContext.xml in View src folder

beanRefContext.xml definition:


<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for servicelayer-context.
  - Contains context & bean references in other context files
  - Author: Venkata Nunna
  - Created Date:07/26/2013
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean id="servicelayer-context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
      <constructor-arg>
        <list>
                        <value>CustomOIMAPP-bus-context.xml</value>
        </list>
      </constructor-arg>
   </bean>
</beans>

Added customoimapp-servlet.xml with empty definition. We can add beans that are specific to Web Layer if required here.



<?xml version="1.0" encoding="UTF-8"?>
<beans 
 xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 
  
</beans>

Modfiy web.xml to load the context files:


<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <description>If this parameter is true, there will be an automatic check of the modification date of your JSPs, and saved state will be discarded when JSP's change. It will also automatically check if your skinning css files have changed without you having to restart the server. This makes development easier, but adds overhead. For this reason this parameter should be set to false when your application is deployed.</description>
    <param-name>org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <description>Whether the 'Generated by...' comment at the bottom of ADF Faces HTML pages should contain version number information.</description>
    <param-name>oracle.adf.view.rich.versionString.HIDDEN</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <param-name>oracle.adf.view.rich.dvt.DEFAULT_IMAGE_FORMAT</param-name>
    <param-value>HTML5</param-value>
  </context-param>
  <context-param>
    <param-name>org.apache.myfaces.trinidad.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.SKIP_XML_INSTRUCTIONS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>org.apache.myfaces.trinidad.ALTERNATE_VIEW_HANDLER</param-name>
    <param-value>org.apache.myfaces.trinidadinternal.facelets.TrinidadFaceletViewHandler</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.DECORATORS</param-name>
    <param-value>oracle.adfinternal.view.faces.facelets.rich.AdfTagDecorator</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.RESOURCE_RESOLVER</param-name>
    <param-value>oracle.adfinternal.view.faces.facelets.rich.AdfFaceletsResourceResolver</param-value>
  </context-param>
<!-- Spring Related Context --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/customoimapp-servlet.xml</param-value> </context-param> <context-param> <param-name>locatorFactorySelector</param-name> <param-value>classpath*:beanRefContext.xml</param-value> </context-param> <context-param> <param-name>parentContextKey</param-name> <param-value>servicelayer-context</param-value> </context-param> <!-- Spring Related Content -->
<filter> <filter-name>JpsFilter</filter-name> <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class> <init-param> <param-name>enable.anonymous</param-name> <param-value>true</param-value> </init-param> </filter> <filter> <filter-name>trinidad</filter-name> <filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class> </filter> <filter> <filter-name>ServletADFFilter</filter-name> <filter-class>oracle.adf.share.http.ServletADFFilter</filter-class> </filter> <filter-mapping> <filter-name>JpsFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <filter-mapping> <filter-name>trinidad</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping> <filter-mapping> <filter-name>ServletADFFilter</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>resources</servlet-name> <servlet-class>org.apache.myfaces.trinidad.webapp.ResourceServlet</servlet-class> </servlet> <servlet> <servlet-name>BIGRAPHSERVLET</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.graph.GraphServlet</servlet-class> </servlet> <servlet> <servlet-name>BIGAUGESERVLET</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.gauge.GaugeServlet</servlet-class> </servlet> <servlet> <servlet-name>MapProxyServlet</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.geoMap.servlet.MapProxyServlet</servlet-class> </servlet> <servlet> <servlet-name>GatewayServlet</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.graph.FlashBridgeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/adf/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/afr/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>BIGRAPHSERVLET</servlet-name> <url-pattern>/servlet/GraphServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>BIGAUGESERVLET</servlet-name> <url-pattern>/servlet/GaugeServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>MapProxyServlet</servlet-name> <url-pattern>/mapproxy/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/bi/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>GatewayServlet</servlet-name> <url-pattern>/flashbridge/*</url-pattern> </servlet-mapping> <mime-mapping> <extension>swf</extension> <mime-type>application/x-shockwave-flash</mime-type> </mime-mapping> </web-app>

Now coming to using the Spring Managed Beans in your Backing bean, this is how you achieve it:

Declare the Service bean in your Backing Bean and in the getter method use WebApplicationContextUtils to get the Spring Managed bean.

Backing Bean code:



package oracle.iam.ui.custom.app.view.backing.bean;

import java.io.Serializable;

import java.util.ArrayList;

import javax.faces.context.FacesContext;

import javax.servlet.ServletContext;

import oracle.adf.view.rich.component.rich.RichDocument;
import oracle.adf.view.rich.component.rich.RichForm;
import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.component.rich.layout.RichPanelBox;
import oracle.adf.view.rich.component.rich.nav.RichCommandButton;
import oracle.adf.view.rich.component.rich.output.RichPanelCollection;
import oracle.adf.view.rich.component.rich.output.RichSeparator;

import oracle.adf.view.rich.context.AdfFacesContext;

import oracle.iam.ui.custom.model.service.OIMService;
import oracle.iam.ui.custom.model.service.bean.OIMUserBean;
import oracle.iam.ui.custom.model.service.impl.OIMServiceImpl;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SearchUsersBackingBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private ApplicationContext ctx;
    private RichForm f1;
    private RichDocument d1;
    private RichPanelBox pb1;
    private RichInputText it1;
    private RichInputText it2;
    private RichCommandButton cb1;
    private ArrayList<OIMUserBean> usersList = null;
    private boolean showResults = false;
    private RichSeparator s1;
    private RichPanelCollection pc1;
    private RichTable t1;

    private OIMService oimService;

    public void setF1(RichForm f1) {
        this.f1 = f1;
    }

    public RichForm getF1() {
        return f1;
    }

    public void setD1(RichDocument d1) {
        this.d1 = d1;
    }

    public RichDocument getD1() {
        return d1;
    }

    public void setPb1(RichPanelBox pb1) {
        this.pb1 = pb1;
    }

    public RichPanelBox getPb1() {
        return pb1;
    }

    public void setIt1(RichInputText it1) {
        this.it1 = it1;
    }

    public RichInputText getIt1() {
        return it1;
    }

    public void setIt2(RichInputText it2) {
        this.it2 = it2;
    }

    public RichInputText getIt2() {
        return it2;
    }

    public void setCb1(RichCommandButton cb1) {
        this.cb1 = cb1;
    }

    public RichCommandButton getCb1() {
        return cb1;
    }

    public String searchUsersInOIM() {
        //OIMServiceImpl oimService = new OIMServiceImpl();
        usersList =
                (ArrayList<OIMUserBean>)this.getOimService().searchUsersInOIM((String)getIt1().getValue(),
                                                                    (String)getIt2().getValue());
        System.out.println("FirstName from UI: " + getIt1().getValue());
        System.out.println("LastName from UI: " + getIt2().getValue());
        //setDummyResults();
        if (usersList.size() > 0) {
            showResults = true;
        }
        return "success";
    }

    public void setUsersList(ArrayList usersList) {
        this.usersList = usersList;
    }

    public ArrayList getUsersList() {
        return usersList;
    }

    private void setDummyResults() {
        usersList = new ArrayList<OIMUserBean>();
        usersList.add(new OIMUserBean("Test1f", "Test1l", "TestUL1",
                                      "test1@test.com"));
        usersList.add(new OIMUserBean("Test2f", "Test2l", "TestUL2",
                                      "test2@test.com"));
    }

    public void setS1(RichSeparator s1) {
        this.s1 = s1;
    }

    public RichSeparator getS1() {
        return s1;
    }

    public void setPc1(RichPanelCollection pc1) {
        this.pc1 = pc1;
    }

    public RichPanelCollection getPc1() {
        return pc1;
    }

    public void setT1(RichTable t1) {
        this.t1 = t1;
    }

    public RichTable getT1() {
        return t1;
    }

    public void setShowResults(boolean showResults) {
        this.showResults = showResults;
    }

    public boolean isShowResults() {
        return showResults;
    }

    public void setOimService(OIMService oimService) {
        this.oimService = oimService;
    }

    public OIMService getOimService() {
        if (this.oimService == null)
            this.oimService = (OIMService)getBean("oimService");

        return oimService;
    }

    /**
     * Get the Spring-managed bean by name from the WebApplicationContext .
     *
     * @param name
     * @return
     * @throws BeansException
     */
    protected Object getBean(String name){
        if (ctx == null) {
            try {
                return WebApplicationContextUtils.getWebApplicationContext((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getBean(name);
            } catch (BeansException e) {
                System.out.println("Beans Exception" + e);
            }
        }
        try {
            return ctx.getBean(name);
        } catch (BeansException e) {
            System.out.println("Beans Exception" + e);
        }
        return null;
    }


}