Wednesday, July 11, 2012

No Cache For JSF/JSPX Page To Avoid Use OF Browser Back Button In JDeveloper 11g / Use OF No-Cache With JSF LifeCycle

Oracle JDeveloper 11.1.1.3
Internet Explorer-8
FireFox-13


In one of my ADF application, I wanted to discourage the use of browser back button. But users never mind to pinpoint the security gaps.
Not finding any proper solution for disabling back button, I decided to expire the cache of page which back button uses to show the saved page.Well, you can't trust on browser, so this technique is not guaranteed to fill gap in security.

The simplest approrach for JSPX page is to add a Scriptlet under <jsp:root> tag with header information.
In Structure window under <jsp:root> tag drag a jsp:scriptlet & write the header information for no-cache.
You can get <scriptlet> from Component Palette & switching to "JSP" selection.
Write header information under <jsp:scriptlet> tag.

















You can also write header info by switching jspx page code editor something like this -
 <?xml version='1.0' encoding='UTF-8'?>  
 <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"  
      xmlns:f="http://java.sun.com/jsf/core"  
      xmlns:h="http://java.sun.com/jsf/html"  
      xmlns:af="http://xmlns.oracle.com/adf/faces/rich">  
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>  
  <jsp:scriptlet>  
   response.setHeader("Pragma", "no-cache");  
   response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");  
   response.setDateHeader("Expires", 0);   
   response.addHeader("Cache-Control","post-check=0, pre-check=0"); 
  </jsp:scriptlet>  


Using above method was giving "500 Internal Server Error".  I did not investigated the reason for error. May be this error is context based for my project source files.

The other way was to use same header information with simple JSF Page Lifecycle.
I created a java class & wired it with managed bean with request scope since I wanted no-cache for
every single request of page. Select <f:view> in Structure Panel from JSPX Page. Add Phase Listener method to fire in 'BeforePhase' for page lifecycle.

  

Write header information in beforePhase listener method.



Sunday, July 8, 2012

Some Useful All Time Handy Backing Bean Code In JDeveloper

Some handy codes for backing bean for my record. I am following biemond's blogs for this -
http://biemond.blogspot.com/2009/03/some-handy-code-for-backing-beans-adf.html
http://biemond.blogspot.com/2011/01/some-handy-code-for-your-managed-beans.html

Part 1 of 2009 starts here -

   1:  // print the roles of the current user  
   2:  for ( String role : ADFContext.getCurrent().getSecurityContext().getUserRoles() ) {  
   3:     System.out.println("role "+role);  
   4:  }  
   5:    
   6:    
   7:  // get the ADF security context and test if the user has the role users         
   8:  SecurityContext sec = ADFContext.getCurrent().getSecurityContext();  
   9:  if ( sec.isUserInRole("users") ) {  
  10:  }  
  11:  // is the user valid  
  12:  public boolean isAuthenticated() {  
  13:   return ADFContext.getCurrent().getSecurityContext().isAuthenticated();  
  14:  }  
  15:  // return the user  
  16:  public String getCurrentUser() {  
  17:   return ADFContext.getCurrent().getSecurityContext().getUserName();  
  18:  }  
  19:    
  20:    
  21:  // get the binding container  
  22:  BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();  
  23:    
  24:  // get an ADF attributevalue from AttributeBinding in ADF page definitions  
  25:  AttributeBinding attr = (AttributeBinding)bindings.getControlBinding("test");  
  26:  attr.setInputValue("test");  
  27:    
  28:  // get an Action or MethodAction by OperationBinding in PageDef 
  29:  OperationBinding method = bindings.getOperationBinding("methodAction");  
  30:  method.execute();  
  31:  List errors = method.getErrors();  
  32:  
  33:  method = bindings.getOperationBinding("methodAction");  
  34:  Map paramsMap = method.getParamsMap();  
  35:  paramsMap.put("param","value")  ;   //putting method param value & executing       
  36:  method.execute();  
  37:    
  38:    
  39:  // Get the data from an ADF tree binding for AF:Table or AF:Tree
  40:  DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();  
  41:    
  42:  FacesCtrlHierBinding treeData = (FacesCtrlHierBinding)dcBindings.getControlBinding("tree");  
  43:  Row[] rows = treeData.getAllRowsInRange();  
  44:    
  45:  // Get a attribute value of the current row of iterator  
  46:  DCIteratorBinding iterBind= (DCIteratorBinding)dcBindings.get("testIterator");  
  47:  String attribute = (String)iterBind.getCurrentRow().getAttribute("field1");  
  48:    
  49:  // Get the error  
  50:  String error = iterBind.getError().getMessage();  
  51:    
  52:    
  53:  // refresh the iterator  
  54:  dcBindings.refreshControl();  
  55:  iterBind.executeQuery();  
  56:  iterBind.refresh(DCIteratorBinding.RANGESIZE_UNLIMITED);  
  57:    
  58:  // Get all the rows of a iterator  
  59:  Row[] rows = iterBind.getAllRowsInRange();  
  60:  TestData dataRow = null;  
  61:  for (Row row : rows) {  
  62:    dataRow = (TestData)((DCDataRow)row).getDataProvider();  
  63:  }  
  64:    
  65:  // Get the current row of a iterator , a different way  
  66:  FacesContext ctx = FacesContext.getCurrentInstance();  
  67:  ExpressionFactory ef = ctx.getApplication().getExpressionFactory();  
  68:  ValueExpression ve = ef.createValueExpression(ctx.getELContext(), "#{bindings.testIter.currentRow.dataProvider}", TestHead.class);  
  69:  TestHead test = (TestHead)ve.getValue(ctx.getELContext());  
  70:    
  71:  // Get a session bean  
  72:  FacesContext ctx = FacesContext.getCurrentInstance();  
  73:  ExpressionFactory ef = ctx.getApplication().getExpressionFactory();  
  74:  ValueExpression ve = ef.createValueExpression(ctx.getELContext(), "#{testSessionBean}", TestSession.class);  
  75:  TestSession test = (TestSession)ve.getValue(ctx.getELContext());  
  76:    
  77:  // main jsf page   
  78:  DCBindingContainer dc = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();   
  79:  // taskflow binding   
  80:  DCTaskFlowBinding tf = (DCTaskFlowBinding)dc.findExecutableBinding("dynamicRegion1");  
  81:  // pagedef of a page fragment   
  82:  JUFormBinding form = (JUFormBinding) tf.findExecutableBinding("regions_employee_regionPageDef");  
  83:  // handle to  binding container of the region.  
  84:  DCBindingContainer dcRegion   = form;  
  85:    
  86:    
  87:    
  88:  // return a methodexpression like a control flow case action or ADF pagedef action  
  89:  private MethodExpression getMethodExpression(String name) {  
  90:   Class [] argtypes = new Class[1];  
  91:   argtypes[0] = ActionEvent.class;  
  92:   FacesContext facesCtx = FacesContext.getCurrentInstance();  
  93:   Application app = facesCtx.getApplication();  
  94:   ExpressionFactory elFactory = app.getExpressionFactory();  
  95:   ELContext elContext = facesCtx.getELContext();  
  96:   return elFactory.createMethodExpression(elContext,name,null,argtypes);  
  97:  }  
  98:    
  99:  //  
 100:  RichCommandMenuItem menuPage1 = new RichCommandMenuItem();  
 101:  menuPage1.setId("page1");  
 102:  menuPage1.setText("Page 1");  
 103:  menuPage1.setActionExpression(getMethodExpression("page1"));  
 104:    
 105:  RichCommandButton button = new RichCommandButton();  
 106:  button.setValueExpression("disabled",getValueExpression("#{!bindings."+item+".enabled}"));  
 107:  button.setId(item);  
 108:  button.setText(item);  
 109:  MethodExpression me = getMethodExpression("#{bindings."+item+".execute}");  
 110:  button.addActionListener(new MethodExpressionActionListener(me));  
 111:  footer.getChildren().add(button);  
 112:    
 113:    
 114:  // get a value  
 115:  private ValueExpression getValueExpression(String name) {  
 116:   FacesContext facesCtx = FacesContext.getCurrentInstance();  
 117:   Application app = facesCtx.getApplication();  
 118:   ExpressionFactory elFactory = app.getExpressionFactory();  
 119:   ELContext elContext = facesCtx.getELContext();  
 120:   return  elFactory.createValueExpression(elContext, name, Object.class);  
 121:  }  
 122:  // an example how to use this  
 123:  RichInputText input = new RichInputText();  
 124:  input.setValueExpression("value",getValueExpression("#{bindings."+item+".inputValue}"));  
 125:  input.setValueExpression("label",getValueExpression("#{bindings."+item+".hints.label}"));  
 126:  input.setId(item);  
 127:  panelForm.getChildren().add(input);  
 128:    
 129:    
 130:    
 131:  // catch an exception and show it in the jsf page  
 132:  catch(Exception e) {  
 133:   FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), "");  
 134:   FacesContext.getCurrentInstance().addMessage(null, msg);  
 135:  }  
 136:    
 137:                      
 138:  FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, msgHead , msgDetail);  
 139:  facesContext.addMessage(uiComponent.getClientId(facesContext), msg);                                                                     
 140:    
 141:    
 142:  // reset all the child uicomponents  
 143:  private void resetValueInputItems(AdfFacesContext adfFacesContext,  
 144:                                   UIComponent component){  
 145:     List<UIComponent> items = component.getChildren();  
 146:     for ( UIComponent item : items ) {  
 147:          
 148:         resetValueInputItems(adfFacesContext,item);  
 149:          
 150:         if ( item instanceof RichInputText  ) {  
 151:             RichInputText input = (RichInputText)item;  
 152:             if ( !input.isDisabled() ) {  
 153:                 input.resetValue() ;  
 154:                 adfFacesContext.addPartialTarget(input);  
 155:             };  
 156:         } else if ( item instanceof RichInputDate ) {  
 157:             RichInputDate input = (RichInputDate)item;  
 158:             if ( !input.isDisabled() ) {  
 159:                 input.resetValue() ;  
 160:                 adfFacesContext.addPartialTarget(input);  
 161:             };  
 162:         }  
 163:     }  
 164:  }  
 165:      
 166:  // redirect to a other url  
 167:  ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();  
 168:  HttpServletResponse response = (HttpServletResponse)ectx.getResponse();  
 169:  String url = ectx.getRequestContextPath()+"/adfAuthentication?logout=true&end_url=/faces/start.jspx";  
 170:    
 171:  try {  
 172:    response.sendRedirect(url);  
 173:  } catch (Exception ex) {  
 174:    ex.printStackTrace();  
 175:  }  
 176:    
 177:  // PPR refresh a jsf component  
 178:  AdfFacesContext.getCurrentInstance().addPartialTarget(UIComponent);  
 179:    
 180:    
 181:  // find a jsf component      
 182:  private UIComponent getUIComponent(String name) {  
 183:   FacesContext facesCtx = FacesContext.getCurrentInstance();  
 184:   return facesCtx.getViewRoot().findComponent(name) ;  
 185:  }  
 186:    
 187:    
 188:  // get the adf bc application module  
 189:  private OEServiceImpl getAm(){  
 190:     FacesContext fc = FacesContext.getCurrentInstance();  
 191:     Application app = fc.getApplication();  
 192:     ExpressionFactory elFactory = app.getExpressionFactory();  
 193:     ELContext elContext = fc.getELContext();  
 194:     ValueExpression valueExp =  
 195:     elFactory.createValueExpression(elContext, "#{data.OEServiceDataControl.dataProvider}",  
 196:                                         Object.class);  
 197:     return   (OEServiceImpl)valueExp.getValue(elContext);  
 198:  }  
 199:    
 200:    
 201:  // change the locale  
 202:  Locale newLocale = new Locale(this.language);  
 203:  FacesContext context = FacesContext.getCurrentInstance();  
 204:  context.getViewRoot().setLocale(newLocale);  
 205:    
 206:    
 207:  // get the stacktrace of a not handled exception  
 208:  private ControllerContext cc = ControllerContext.getInstance();  
 209:    
 210:  public String getStacktrace() {  
 211:     if ( cc.getCurrentViewPort().getExceptionData()!=null ) {  
 212:         StringWriter sw = new StringWriter();  
 213:         PrintWriter pw = new PrintWriter(sw);  
 214:         cc.getCurrentViewPort().getExceptionData().printStackTrace(pw);  
 215:         return sw.toString();             
 216:     }  
 217:     return null;  
 218:  }  
 219:    
 220:    
 221:  // get the selected rows from a table component  
 222:  RowKeySet selection = resultTable.getSelectedRowKeys();  
 223:  Object[] keys = selection.toArray();  
 224:  List<Long> receivers = new ArrayList<Long>(keys.length);  
 225:  for ( Object key : keys ) {  
 226:    User user = modelFriends.get((Integer)key);  
 227:  }  
 228:    
 229:  // get  selected Rows of a table 2  
 230:  for (Object facesRowKey : table.getSelectedRowKeys()) {  
 231:   table.setRowKey(facesRowKey);  
 232:   Object o = table.getRowData();  
 233:   JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding)o;  
 234:   Row row = rowData.getRow();  
 235:   Test testRow = (Test)((DCDataRow)row).getDataProvider() ;  
 236:  }  
 
The 2nd Part of 2011 follows from here - Starting with FacesContext class, with this class you can use to find a JSF Component, change the Locale, get the ELContext, Add a message to your view and get the ExternalContext.
   1:  // FacesContext 
   2:  FacesContext facesCtx = FacesContext.getCurrentInstance();  
   3:   
   4:  // find UIComponent
   5:  UIComponent input = facesCtx.getViewRoot().findComponent("f1"); 
   6:   
   7:  // change the locale  
   8:  facesCtx.getViewRoot().setLocale( Locale.ENGLISH);   
   9:   
  10:  // el expression
  11:  Application app = facesCtx.getApplication();  
  12:  ExpressionFactory elFactory = app.getExpressionFactory();  
  13:  ELContext elContext = facesCtx.getELContext();   
  14:  ValueExpression valueExp = elFactory.createValueExpression(elContext,"{xxxx}", Object.class); 
  15:  Object result = valueExp.getValue(elContext); 
  16:   
  17:  // add a message
  18:  FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN,"header","detail");  
  19:  facesCtx.addMessage(input.getClientId(facesCtx), msg);  
  20:   
  21:  // ExternalContext
  22:  ExternalContext ectx = facesCtx.getExternalContext();


The ExternalContext class, with this you can retrieve all the java init & context (web.xml) parameters, the Request & Session parameters and your web application url.
   1:  // ExternalContext
   2:  ExternalContext ectx = facesCtx.getExternalContext();   
   3:   
   4:  // all the java init parameters
   5:  Map<String, Object> initParamsVar = ectx.getInitParameterMap();  
   6:     
   7:  Map<String, String> requestParamsVar = ectx.getRequestParameterMap();
   8:  Map<String, Object> sessionParamsVar = ectx.getSessionMap();
   9:   
  10:  // web application context root
  11:  String contextPath = ectx.getRequestContextPat();


AdfFacesContext class, you can use this class for Partial Page Rendering ( PPR), get the PageFlowScope and ViewScope variables
   1:  // AdfFacesContext
   2:  AdfFacesContext adfFacesCtx = AdfFacesContext.getCurrentInstance();
   3:   
   4:  // PPR
   5:  adfFacesCtx.addPartialTarget(input);  
   6:   
   7:  // get the PageFlowScope Params
   8:  Map<String, Object> scopePageFlowScopeVar= adfFacesCtx.getPageFlowScope(); 
   9:   
  10:  // get the viewScope Params
  11:  Map<String, Object> scopeViewScopeVar= adfFacesCtx.getViewScope();


ADFContext class, with this you can get all the memory scopes variables even the application scope variables, ELContext and the SecurityContext.
   1:  // ADFContext
   2:  ADFContext adfCtx =  ADFContext.getCurrent(); 
   3:   
   4:  // Get the scope variables
   5:  Map<String, Object> applicationVar2   = adfCtx.getApplicationScope();
   6:  Map<String, Object> pageParamsVar2    = adfCtx.getPageFlowScope();  
   7:  Map<String, String> requestParamsVar2 = adfCtx.getRequestScope();
   8:  Map<String, Object> sessionParamsVar2 = adfCtx.getSessionScope(); 
   9:   
  10:  // el expression
  11:  ELContext elContext2 = adfCtx.getELContext();
  12:  ExpressionFactory elFactory2 = adfCtx.getExpressionFactory();
  13:  ValueExpression valueExp2 = elFactory2.createValueExpression(elContext2,"#{xxxx}", Object.class);
  14:  Object result2 = valueExp2.getValue(elContext2); 
  15:   
  16:  // Security
  17:  SecurityContext secCntx = adfCtx.getSecurityContext();


SecurityContext class, retrieve the current user and its roles.
   1:  // Security
   2:  SecurityContext secCntx = adfCtx.getSecurityContext();
   3:  String user             = secCntx.getUserName();  
   4:  String[] roles          = secCntx.getUserRoles();  


BindingContext, BindingContainer and DCBindingContainer class. These classes are well known when you want to retrieve the ADF pagedef objects.
   1:  BindingContext bc           = BindingContext.getCurrent(); 
   2:  BindingContainer bcon       = bc.getCurrentBindingsEntry();
   3:   
   4:  List<AttributeBinding> attr = bcon.getAttributeBindings();
   5:  List<OperationBinding> oper = bcon.getOperationBindings();
   6:  List<ControlBinding>   ctrl = bcon.getControlBindings(); 
   7:   
   8:  DCBindingContainer    dcbcon = (DCBindingContainer) bc.getCurrentBindingsEntry();   
   9:   
  10:  List<AttributeBinding> attr2 = dcbcon.getAttributeBindings();
  11:  List<OperationBinding> oper2 = dcbcon.getOperationBindings();
  12:  List<ControlBinding>   ctrl2 = dcbcon.getControlBindings();
  13:  List                   iters = dcbcon.getIterBindingList();
  14:  List                   exec  = dcbcon.getExecutableBindings();


The last class is ControllerContext, which you can use to retrieve the exceptions
   1:  ControllerContext cc = ControllerContext.getInstance();  
   2:   
   3:  // get the exception
   4:  Exception exp = cc.getCurrentViewPort().getExceptionData();

Saturday, July 7, 2012

Use Of AF:Switcher with ViewScope Variable In JDeveloper 11g

JDeveloper 11.1.1.3
ADF Faces RC.

The af:switcher component is able to show facet component dynamically. It will render the facet matching "FacetName" property. Its a server side component with no client side representation. Refer here for more info http://jdevadf.oracle.com/adf-richclient-demo/docs/tagdoc/af_switcher.html .
The af:setPropertyListener is declartive operation component in ADF for assigning value when certain event fires. Refer more about propertyListener here http://jdevadf.oracle.com/adf-richclient-demo/docs/tagdoc/af_setPropertyListener.html .

  1. Open your adfc-config.xml file for unbounded task flow.
  2. Select view activity & in property inspector, under Page Parameters click + icon.
  3. Write in From Value=First & To Value=#{viewScope.paramVal}. When the view activity/jspx page will run framework will create a viewScope variable "paramVal" if not found & assign the "First" value to it. Your view activity would show warning message stating "Reference Not Found..." in design time. Just ignore it.



  4.    Drag the af:switcher component from component palette. Right click to select 'insert inside
         swithcer' & then "facet". Repeat twice for 2 facet named "First" & "Second" respectively. 
         Drag af:message component inside both facets.
  5.    You can set "DefaultFacet" property to any facet you want, in case, if "FacetName" is not
         defined or returns Null , DefaultFacet property will be used.
  6.    Select af:switcher in Structure window & write FacetName= #{viewScope.paramVal} .Now
         when first time the page will run, First facet would be selected.
  7.    Now, drag 2 command buttons. Under each button drag af:setPropertyListener.
  8.    In the first button's propertyListener write From=First, To= #{viewScope.paramVal}
         Type=action .
  9.    In the 2nd button's propertyListener write From=Second, To= #{viewScope.paramVal},
         Type=action .
10.    Just the optional thing to do is disabling your button after clicking it.Select first button & in
         disabled property write #{viewScope.paramVal == "First"} .
11.    Do same for second button & write #{viewScope.paramVal == "Second"} .




Run the page to test. 

The above functionality can also achieved by viewScope Managed Bean instead of viewScope variable.
Sample Workspace for viewScope variable - Download
Sample Workspace for viewScope bean - Download

Note the viewScope project has java class which is not using as managed bean. This class is 
wired in managed bean project workspace.