Thursday, December 23, 2010

Parcelable interface in android

The most efficient way to pass custom objects between android activities in by implementing the Parcelable interface. Two methods describeContents and writeToParcel needs to be overridden


public class MyParcel implements Parcelable{
private String name;
private List emails;

@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}

@Override
public void writeToParcel(Parcel dest, int arg1) {
dest.writeString(name);

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("emails", emails);
dest.writeBundle(bundle);

}
}

In this example MyParcel class has a name and a list of emails which we would like write to a parcel so that other activities can have access to it. As you can see the basic java types have their corresponding write methods to write a user defined class or a list we first create a bundle and then write it to the parcel.

Tuesday, December 21, 2010

Exposing Spring beans as a JMX managed bean

I had a few Spring service beans that I wanted to expose as a JMX bean. I was using annotation to define my Spring beans and the steps are really straight forward to expose these as a JMX managed bean using the support from spring. Spring 2.5 and 3.0 comes shipped with some easy annotations to do this. First you define the spring exporter for managed resource.

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="autodetect" value="true"></property>
<property name="namingStrategy" ref="namingStrategy"></property>
<property name="assembler" ref="assembler"></property>
<property name="beans">
<map>
<entry key="bean:name=myManagedBean" value-ref="myService"/>

</map>
</property>
</bean>
<bean id="attributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="attributeSource"/>
</bean>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="attributeSource"/>
</bean>


The exporter bean needs to have lazy-init flag set to false, this flag when set does not call the init code when the bean is loaded. The attributeSource bean indicates that we are going to use annotation to expose the bean attributes. And finally the namingStrategy bean defines how the managed beans are named and accessible in the jconsole. Once these beans are defined in the spring context now we are ready to code the managed resource.

@Service("myService")
@ManagedResource(objectName = "bean:name=myManagedBean", description = "Asample")
public class MyServiceImpl implements MyService {

private Integer myManagedAttribute;

@ManagedAttribute(description="The bean Attribute")
public void setMyManagedAttribute(Integer val){
this.myManagedAttribute=val;
}
@ManagedAttribute(description="The bean Attribute")
public Integer getMyManagedAttribute(){
return myManagedAttribute;
}
@ManagedOperation(description="the operation that is exposed")
public void myOperation(){
}
}


In the example which is a Spring service we can also make it a managed resources by adding the managedResource annotation the objectName given here should be the same that was given in the exporter bean key. Then every get or set method can be annotated with managedAttribute and other methods can be annotated with managedOperation.

Array Copy using Generics

If you look at the method definition of copy in the collections framework it looks something like this.

public static <T> void copy(List< ? super T > to, List <? extends T> from)


The ? in generics means wild card i.e. In this case any class or interface that is a super class of T for the first parameter or extends T as in the second parameter. An important concept that one should understand in this example is covariance. Arrays in java are covariance i.e. if Integer extends Number then Interger[] also extends Number[]. This is not the case when it comes to generic lists where List<Integer> is not a sub class of List<Number>. With this basic understanding lets simplify the above method definition and see what happens


public static <T> void copy(List<T> to, List <T> from)


Now let us call the method as follows.

List<Object> objs = Arrays.<Object>asList("San","John",1042);
List<Integer> ints = Arrays.<Integer>asList(10,20);
TestClass.<Object>copy(objs, ints); // Call(1)
TestClass.<Integer>copy(objs,ints); // Call (2)
TestClass.<Number>copy(objs,ints); // Call (3)

If the rule of covariance is applied then all three calls are not legal. as List<Integer> is not a subclass of List<Object> if you consider call (1) To make call (1) legal the declaration should be modified to

public static <T> void copy(List<T> to, List <? extends T> from)


With this method declaration call (1) is legal but how about (2) and (3) they are still not legal as List<Object> is not a subclass of List<Integer> for the "to" parameter same concept is applicable for call (3) and because of this we end up having public static <T> void copy(List< ? super T > to, List <? extends T> from) which is the most suitable for all calls. I would recommend reading the Java Generics and Collections by Maurice Naftalin to understand more about Generics in Java.

Wednesday, December 8, 2010

Spring security LDAP authentication

I was experimenting on spring security and found that with spring 2.5 LDAP authentication was a pain. This is what I did to get around the issue.

First my maven POM had these dependencies


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>

<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap</artifactId>
<version>1.2.1</version>
</dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>2.0.4</version>
</dependency>


Your web.xml should have the contextConfigLocation which refers to the location of the spring security config xml file, the spring web context loader and the spring security filter.



<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/context-security.xml
</param-value>
</context-param>
<!-- Spring context loader servlet and listener class need to spring managed beans-->
<listener>
<listener-class> org.springframework.web.context.request.RequestContextListener </listener-class>
</listener>

<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet </servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<!--spring security filter chain -->

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>*.html</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>


The contents of context-security.xml is as follows



<!-- first configure the LDAP url -->

<ldap-server id="appLdapServer" url="ldap://example.com:389/ou=San_Jose,o=ME" />

<!-- configure the LDAP authentication provider here you can specify search filters
which will start the LDAP search from a given node in the tree. you can also specify
users with certain specific attributes so that only those users can have access to your application web page
-->

<ldap-authentication-provider server-ref="appLdapServer"
user-search-filter="(cn={0})" group-role-attribute="ou=Engineering"
user-search-base="ou=Software Eng"/>




Now the http intercept url xml elements need to be written for this we shall have a simple rule which shows pages in folder inbox if the user has been authenticated otherwise the user gets redirected to login or error page in folder auth so make sure you have only unsecure pages in the auth folder.



<http access-denied-page="/auth/denied.html">
<intercept-url
pattern="/**/*.xhtml"
access="ROLE_NONE_GETS_ACCESS" />
<intercept-url
pattern="/auth/*"
access="ROLE_ANONYMOUS" />
<intercept-url
pattern="/inbox/*"
access="IS_AUTHENTICATED_FULLY" />
<intercept-url
pattern="/**"
access="IS_AUTHENTICATED_FULLY" />
<form-login
login-processing-url="/j_spring_security_check.html"
login-page="/auth/login.html"
default-target-url="/inbox/index.html"
authentication-failure-url="/auth/login.html" />
<logout logout-url="/auth/logout.html"
logout-success-url="/" />
<anonymous username="guest" granted-authority="ROLE_ANONYMOUS"/>
</http>



The IS_AUTHENTICATED_FULLY is a spring security access constant which does the trick to all pages inside inbox to be visible if the LDAP authentication is successful