Friday, October 10, 2014

Java Threads : simple introduction

Recently I was asked about the usage of threads in Java :
1- how to create them.
2- the difference between run() and start() methods.

first : how to create them.
I will talk about simply creating one thread at a time then starting it- there are ways to create thread pools then using or creating threads to be run at a later time which I will not mention.
you can create threads by:

a- creating a subclass of the Thread class:
    a1-  creating a subclass of the Thread class
    a2-  overriding the run() method to execute your code that you want to be run inside a different thread. 
    a3- create a new instance of your thread subclass
    a4- call the start() method of the new instance

b- creating a new class that implements Runnable interface
    b1-creating a new class that implements Runnable interface
    b2- provide an implementation for the run() method that will execute your code
    b3- create a new Thread instance and pass it an instance of your subclass that implements the        Runnable interface
    b4- call the start() method of the thread instance.


both will run your code inside a separate thread. But if you extend the Thread class then you fixed Thread as the parent of the class and since in Java you have only one parent class then it will restrict your code.
but if you implement the Runnable interface then you won't face this issue.



another question I was asked was the difference between calling the run() and the start() methods on the thread instances?
- calling run(): 
   1- will call the method and it will execute in the current thread
   2- you can call it multiple times on the same thread without problems.
  ==> the same as calling a method on any class

- calling start():
 1- will start the thread life cycle, it will go from New to RUNNABLE and eventually to 
      TERMINATED, and the run() method will be called which will execute your code
 2- your code will be executed in a different thread.
 3- if you call more than one time you will get an exception every time after the first one

Thursday, October 9, 2014

Lambda Expressions

Just recently  I was reading about JAVA 8 features and I came across Lambda expressions.
it seems that you can use what is known as Lambda expressions to write java code neatly.

from Oracle site:
"One issue with anonymous classes is that if the implementation of your anonymous class is very simple, such as an interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear"

Such Interfaces that have only one method without body are called functional interfaces. these interfaces are the ones that Lambda expressions help you implement are anonymous classes with simpler code.


Example:
package com.ahmadalzamer.lambda;

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

/**
 *
 * @author Ahmad Al-Zamer
 */
public class TestLambdaExpressions {

    public static void main(String[] args) {
        //you can 
        List<String> l = new ArrayList<>();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");

        System.out.println("Using Anonymous Classes:");
        System.out.println("original List:" + l);
        Collections.sort(l, new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (String o1, String o2) -> o1.compareTo(o2));
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions without Explicit data type:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (o1, o2) -> o1.compareTo(o2));
        System.out.println("original List:" + l);

        //Using Lambda expressions:
        System.out.println("\nUsing Lambda Expressions with multi-line body:");
        l.clear();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("a1");
        l.add("b1");
        l.add("c1");
        l.add("a2");
        l.add("c2");
        l.add("b2");
        l.add("a12");
        System.out.println("original List:" + l);
        Collections.sort(l, (o1, o2) -> {
            System.out.println("Comparing o1:"+o1+" to o2:"+o2);
            return o1.compareTo(o2);
        });
        System.out.println("original List:" + l);

    }
}


here you can see how I used Lambda Expressions to create an anonymous class that implements the Comparator interface.After that I used several Lambda expressions to implement the same Comparator.

Expression:(String o1, String o2) -> o1.compareTo(o2)  can be split as:
1) (String o1, String o2) : parameter list of the method defined in the functional interface, here you can either explicitly list the datatype of the parameters or the compiler can be implicitly infer them from the context.
2) -> : arrow token between parameter list and lambda expression body.
3) o1.compareTo(o1) : the body of the lambda expression, which will go inside the method of the functional interface. can be either a one line code - in which case you don't have to worry about the return keyword, the compiler will figure out whether to add it or not based on the interface- or you can use multi-line code block - in this case you are actually writing the body of the method of the function, so you have to add the return keyword if needed-



the ability to write neat code using Lambda expressions is nice to have but for people who are not used to them it will make the code look harder to understand.


Thursday, February 27, 2014

Prevent copy/cut/paste in input fields

one of the requirements  we had for a certain application I've been working on was to prevent users from copying/pasting values from/into an input text field.
In this blog entry, I will show how we achieved the requested behavior.

basically, you can achieve the requested behavior using JavaScript.
include the following code snippet in your page:

<af:resource type="javascript">
          function eventCancel(evt) {
             AdfPage.PAGE.clearMessages(evt.getSource()._clientId);
              AdfPage.PAGE.addMessage(evt.getSource()._clientId, new AdfFacesMessage(AdfFacesMessage.TYPE_ERROR, "Error" , "context menu is disabled for this field" )) ;
          }

          function cancelCopy(evt) {
              if (((evt.getKeyCode() == AdfKeyStroke.C_KEY)||(evt.getKeyCode() == AdfKeyStroke.X_KEY))&&(evt.getKeyModifiers() & AdfKeyStroke.CTRL_MASK) > 0) {
                 AdfPage.PAGE.clearMessages(evt.getSource()._clientId);
                  AdfPage.PAGE.addMessage(evt.getSource()._clientId, new AdfFacesMessage(AdfFacesMessage.TYPE_ERROR, "Error" , "sorry cannot cut/copy" ));
                  evt.cancel();
              }
              if ((evt.getKeyCode() == AdfKeyStroke.V_KEY)&& (evt.getKeyModifiers() & AdfKeyStroke.CTRL_MASK) > 0) {
                    AdfPage.PAGE.clearMessages(evt.getSource()._clientId);
                  AdfPage.PAGE.addMessage(evt.getSource()._clientId, new AdfFacesMessage(AdfFacesMessage.TYPE_ERROR, "Error" , "sorry cannot paste" ));
                  evt.cancel();
              }
          }
        </af:resource>

then modify your input text field as shown below:
<af:inputText label="Label 1" id="it1" clientComponent="true">
          <af:clientListener type="keyDown" method="cancelCopy"/>
          <af:clientListener type="contextMenu" method="eventCancel"/>
        </af:inputText>

the above shows two client listeners:
1- is called on key down: which calls a function that test to see what the pressed key is and if the pressed key pressed is (X,C,V) and the control key is pressed, then  the edit operation is cancelled and an alert message is shown.
2- when the user right click on the field, the context menu event is cancelled, so no context menu will be shown, thus the user won't be able to use the edit operations.

Edited on 03/03/2014:
sorry, but it seems that the property ._clientId is an internal property of the javascript variable that should not be used by the developers. so, please use: evt.getSource().getId() instead.

Friday, February 14, 2014

Logging DML statements

For a while now, I've been wondering is it possible to know the generated DML statements and their parameter values; since this might be helpful sometimes. And finally I have managed to do this, I will list the steps below.

steps:
1) generate a java class for the targeted entities or use a base entity class.
2) override the buildDMLStatement method and your custom logic, similar to:
protected StringBuffer buildDMLStatement(int i , AttributeDefImpl[] attributeDefImpl ,
                                             AttributeDefImpl[] attributeDefImpl2 ,
                                             AttributeDefImpl[] attributeDefImpl3 , boolean b) {
        StringBuffer buffer =
            super.buildDMLStatement(i , attributeDefImpl , attributeDefImpl2 , attributeDefImpl3 , b) ;
        logger.info("created dml statement  (for object:" + getEntityDef().getName() + getKey() + "):" +
                    buffer.toString()) ;

        return buffer ;
    }

3)override the bindDMLStatement method and add your custom logic, similar to:
protected int bindDMLStatement(int i , PreparedStatement preparedStatement , AttributeDefImpl[] attributeDefImpl ,
                                   AttributeDefImpl[] attributeDefImpl2 , AttributeDefImpl[] attributeDefImpl3 ,
                                   HashMap hashMap , boolean b) throws SQLException {
        String[] attrs = getAttributeNames() ;
        for (String attrName : attrs) {
            if (isAttributeChanged(getAttributeIndexOf(attrName))) {
                logger.info("attribute[" + attrName + "] changed, " + "postedValue:" +
                            getAttribute(getAttributeIndexOf(attrName) , ORIGINAL_VERSION) + ", newValue:" +
                            getAttribute(attrName)) ;
            }
        }
        return super.bindDMLStatement(i , preparedStatement , attributeDefImpl , attributeDefImpl2 ,
                                      attributeDefImpl3 , hashMap , b) ;
    }


You are done now. using the above code- in the base entity class- will log all generated DML statements.

Full class looks like:
package com.ahmad.model ;

import java.sql.PreparedStatement ;
import java.sql.SQLException ;

import java.util.HashMap ;

import java.util.logging.Logger ;

import oracle.jbo.server.AttributeDefImpl ;
import oracle.jbo.server.EntityImpl ;



public class BaseEntity extends EntityImpl {
    public BaseEntity() {
        super() ;
    }
    Logger logger = Logger.getLogger(BaseEntity.class.getName()) ;

    protected int bindDMLStatement(int i , PreparedStatement preparedStatement , AttributeDefImpl[] attributeDefImpl ,
                                   AttributeDefImpl[] attributeDefImpl2 , AttributeDefImpl[] attributeDefImpl3 ,
                                   HashMap hashMap , boolean b) throws SQLException {
        String[] attrs = getAttributeNames() ;
        for (String attrName : attrs) {
            if (isAttributeChanged(getAttributeIndexOf(attrName))) {
                logger.info("attribute[" + attrName + "] changed, " + "postedValue:" +
                            getAttribute(getAttributeIndexOf(attrName) , ORIGINAL_VERSION) + ", newValue:" +
                            getAttribute(attrName)) ;
            }
        }
        return super.bindDMLStatement(i , preparedStatement , attributeDefImpl , attributeDefImpl2 ,
                                      attributeDefImpl3 , hashMap , b) ;
    }

    protected StringBuffer buildDMLStatement(int i , AttributeDefImpl[] attributeDefImpl ,
                                             AttributeDefImpl[] attributeDefImpl2 ,
                                             AttributeDefImpl[] attributeDefImpl3 , boolean b) {
        StringBuffer buffer =
            super.buildDMLStatement(i , attributeDefImpl , attributeDefImpl2 , attributeDefImpl3 , b) ;
        logger.info("created dml statement  (for object:" + getEntityDef().getName() + getKey() + "):" +
                    buffer.toString()) ;

        return buffer ;
    }

    protected boolean isAttributeChanged(int i) { //it seems this method is used to determine if the attribute is chnaged or not, so that it will be included in the generated dml
        return super.isAttributeChanged(i) ;
    }

}



Update on: 17 February,2014:
found out that you can achieve a similar result by using your own class that extends DBTransactionImpl2 class and overriding the createPreparedStatement method to log the passed string. But if you want to have more control about which Entities' DMLs you want to log, then use the first approach.

Thursday, February 13, 2014

Backing Bean - auto bind

in JSF you can choose to bind the JSF page components to java objects in a backing bean, so that you can access the components programatically.
in JDeveloper 11g Release 2, you can choose to set a backing bean that will be used as the backing bean for a JSF page and any components added to the page will be added to the bean automatically.

steps:
  1. open the page.
  2. from the toolbar menu open the design menu.
  3. click page properties.
  4. in the page properties dialog window, switch to the component binding tab.
in the opened tab you can:
  1. switch on/off auto binding.
  2. choose the bean to be used as the component binding.



Monday, January 27, 2014

Cancelling ADF Action from ActionListener

Sometimes we are faced with a requirement that requires the use of both action and action listener attributes of the command components of ADF.
 It seems that a lot of people advice to use the ActionListener to do some validation on the page level, then if it's okay let the code proceed with the code representing the business requirements in the Action.

but how are we supposed to stop the processing of the current event, so that the action is not invoked?
I will list three different code sample to achieve this.
1)using the setAction of the component:
if (some validation logic here) {
message("Valid");
Class[] parms = new Class[] { };
MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{ClassName.MethodName}", parms);
((RichCommandButton)actionEvent.getSource()).setAction(mb);
} else {
message("Invalid");
((RichCommandButton)actionEvent.getSource()).setAction(null);
}

Note: MethodBinding is a deprecated class, use the code in example 2.
2)using the setActionExpression of the component:
if (some validation logic here) {
message("Valid");
Class[] parms = new Class[] { ActionEvent.class };
FacesContext fctx1 = FacesContext.getCurrentInstance();
ELContext elctx = fctx1.getELContext();
Application app = fctx1.getApplication();
ExpressionFactory exprFactory = app.getExpressionFactory();
javax.el.MethodExpression expr = exprFactory.createMethodExpression(elctx, "#{ClassName.MethodName}", parms);
((RichCommandButton)actionEvent.getSource()).setActionExpression(expr);
} else {
message("Invalid");
((RichCommandButton)actionEvent.getSource()).setActionExpression(null);
}
3)or simply use the javax.faces.event.AbortProcessingException
if (some validation logic here) {
message("Valid");
} else {
message("Invalid");
throw new AbortProcessingException("Invalid");
} 
from the java doc:
public class AbortProcessingException
extends FacesException 
An exception that may be thrown by event listeners to terminate the processing of the current event.

Monday, January 6, 2014

J2EE security - multiple stores

description:
we had a requirement as the following:
1- user names, roles and role memberships are stored in LDAP server.
2- some role memberships are almost static and don's change.3- some role memberships can be changed any time at runtime.

since the customer policies regarding changes in the LDAP were pretty strict, any changes will take some time before they take effect, which will cause problems regarding point 3 above.
so, they requested that some role memberships are to be stored in the application database, so that they can be changed quickly through screens of the application.

solution:
in the security configuration of the weblogic, add two providers. One provider that will lookup  the roles from the database while the other will use the LDAP.

steps:
1- login in to the weblogic console and go to the security realms config screens

2-  click the providers tab, authentication sub-tab, click new button
3- insert any name you want, then choose the type, you can either choose sql or readonly sql authenticator
if you choose SqlAuthenticator, then you can use the weblogic console to edit the username, roles and memberships.
4- after adding the authenticator, you will notice that it's at the bottom of the table, now click reorder
we need to reorder to tell the weblogic to use this authenticator first, then go through the others.
4- after reordering, we are going to configure the authenticator
in the above picture, we will choose optional, which will instruct the weblogic to use this authenticator and if it succeeds then add the roles to the user session, then go through the other authenticators. and if it fails it will not prevent the users from logging in.


in the above picture, we will configure the provider type specific info,
use plain text for password, and give it the data source name, the one display in the weblogic console not the JNDI String, to use to access the database.
for the scripts needed to configure the default tables used be the sqlauthenticator, see https://community.oracle.com/message/10531498