Custom Annotation Processing for Web Application

To know about how to declare custom annotations, what are the properties and options please refer to this post, which is very clear and simple.

What I will be discussing here is after you have declared and used your custom annotations, how to process them in run time for any web application.
Our aim is to find all the annotated classes and process their annotations at the time of servlet initialization i.e. in the init() method of the servlet. After getting those annotation attribute values we will be printing them just for this example. Lets build our custom annotation and one class annotated with that.

package com.annotated.classes.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Task {

	String id();

	String name();

	String uri();
}
package com.annotated.classes.example;

@Task(
		id = "Task1", 
		name = "Task1", 
		uri = "#task1"
)
public class Task1 {

}

The first thing we need to learn is how to get the class files from ‘WEB-INF/classes’ folder as well as all the classes from jars residing in ‘WEB-INF/lib’ folder. We are going to use ‘ServletContext’ to get the list of class files. We will be looking for all the class files under a specified package. So lets declare it at the very beginning with some other top level variables.

private String packageName = "com.annotated.classes";
private String packageNamePath = packageName.replace(".", "/");
private String classesPath = "/WEB-INF/classes/" + packageNamePath;
private String jarsPath = "/WEB-INF/lib";

‘WEB-INF/classes’
The ‘getResourcePaths’ method of ‘ServletContext’ gives us a list of resources (.class files and folders) under a specified path. If we encounter a sub folder under the path we need to get resources from that folder also. So its better to have a recursion to traverse the folder structure to get all the .class files.

private Set<String> getClassFiles(String path, ServletContext context, Set<String> finalList) {

	Set<String> resourceSet = context.getResourcePaths(path);
	if (resourceSet != null) {
		for (Iterator<String> iterator = resourceSet.iterator(); iterator.hasNext();) {
			String resourcePath = (String) iterator.next();

			if (resourcePath.endsWith(".class")) {
				finalList.add(resourcePath.substring(resourcePath.indexOf(packageNamePath)));
			} else {
				getClassFiles(resourcePath, context, finalList);
			}
		}
	}
	return finalList;
}

The method will be called like

ServletContext context = servletConfig.getServletContext();
Set<String> classFiles = new HashSet<String>();
classFiles = getClassFiles(classesPath, context, classFiles);

‘WEB-INF/lib’
Here we will be opening each jar we have in our lib folder and scan for the same package declared above and get the list of class files under them.

Set<String> libJars = context.getResourcePaths(jarsPath);
Set<String> allClasses = new HashSet<String>();

if (libJars != null) {
	for (String jar : libJars) {
		JarInputStream jarInputStream = new JarInputStream(context.getResourceAsStream(jar));
		JarEntry jarEntry;

		while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
			if ((jarEntry.getName().startsWith(packageNamePath)) && (jarEntry.getName().endsWith(".class"))) {
				allClasses.add(jarEntry.getName());
			}
		}
	}
}

Now we have all the class files we expect to have annotated with our custom annotation. To find what classes are annotated with our annotation we may use java reflection. But here we will be using Javassist as its much lighter. The tutorial can be found here and download from here.

First we need to add our class paths to the ClassPool object to be able to get the reference of the classes.

ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(CustomAnnotationProcessor.class));
pool.appendClassPath(jarsPath);

The CtClass object from Javassist will give us the reference of the class. It expects the input as the fully qualified class name. We need to do some string manipulation to get the fully qualified class names from the list we got from above. Once we have the CtClass object we can check for its annotations and if present get the instance of the annotation with attribute values.

CtClass cc = pool.get(classFile);
Object[] annotations = cc.getAnnotations();
for (Object annotation : annotations) {
	if (annotation instanceof Task) {
		Task task = (Task) annotation;
		
		System.out.println("Id : " + task.id());
		System.out.println("Name : " + task.name());
		System.out.println("URI : " + task.uri());
	}
}

And with all it together we have

package com.annotated.classes.annotation;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

public class CustomAnnotationProcessor {

	private String packageName = "com.annotated.classes";
	private String packageNamePath = packageName.replace(".", "/");
	private String classesPath = "/WEB-INF/classes/" + packageNamePath;
	private String jarsPath = "/WEB-INF/lib";

	public void processAnnotations(ServletConfig servletConfig) {

		ServletContext context = servletConfig.getServletContext();
		Set<String> classFiles = new HashSet<String>();
		classFiles = getClassFiles(classesPath, context, classFiles);

		Set<String> libJars = context.getResourcePaths(jarsPath);
		Set<String> allClasses = new HashSet<String>();

		if (!classFiles.isEmpty()) {
			allClasses.addAll(classFiles);
		}

		try {
			// Javassist to get classes from class paths
			ClassPool pool = ClassPool.getDefault();
			pool.insertClassPath(new ClassClassPath(AnnotationProcessor.class));
			pool.appendClassPath(jarsPath);

			// Get classes from Jar files
			if (libJars != null) {
				for (String jar : libJars) {
					JarInputStream jarInputStream = new JarInputStream(context.getResourceAsStream(jar));
					JarEntry jarEntry;

					while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
						if ((jarEntry.getName().startsWith(packageNamePath)) && (jarEntry.getName().endsWith(".class"))) {
							allClasses.add(jarEntry.getName());
						}
					}
				}
			}

			// Read Annotations
			for (String classFile : allClasses) {

				classFile = classFile.replace("/", ".").substring(0, classFile.indexOf(".class"));

				CtClass cc = pool.get(classFile);
				Object[] annotations = cc.getAnnotations();
				for (Object annotation : annotations) {
					if (annotation instanceof Task) {
						Task task = (Task) annotation;

						System.out.println("Id : " + task.id());
						System.out.println("View : " + task.viewClass());
						System.out.println("URI : " + task.uri());
					}
				}
			}
			
		} catch (NotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private Set<String> getClassFiles(String path, ServletContext context, Set<String> finalList) {

		Set<String> resourceSet = context.getResourcePaths(path);
		if (resourceSet != null) {
			for (Iterator<String> iterator = resourceSet.iterator(); iterator.hasNext();) {
				String resourcePath = (String) iterator.next();

				if (resourcePath.endsWith(".class")) {
					finalList.add(resourcePath.substring(resourcePath.indexOf(packageNamePath)));
				} else {
					getClassFiles(resourcePath, context, finalList);
				}
			}
		}
		return finalList;
	}

}

IceFaces Cancel Button with immediate true

Putting ‘immediate=”true”‘ in a cancel button in an icefaces form will pass the validation process. But to get old form values in place we have to do something in our back end.
After searching a whole lot of pages I found two articles to get the solution.

https://cwiki.apache.org/confluence/display/MYFACES/Clear+Input+Components
https://cwiki.apache.org/confluence/display/MYFACES/How+the+immediate+attribute+works

One way to do this is to re render the view to get old form values. But in my case the composite view has so many flags to set particular rendering of the components. So just to refresh the page was not working for me. What I did is to set the backing bean value to its old values and call a clear() method on all my UI components needed to be reset.

public void cancelCustomer(ActionEvent event) {
	Customer customer = orderEditBackingBean.getSelected().getCustomer();

	orderEditBackingBean.getSelected().setCustomerId(customer.getCustomerId());
	orderEditBackingBean.getSelected().setContactName(customer.getCustomerFirst());
	orderEditBackingBean.getSelected().setCompanyName(customer.getCompanyName());
	orderEditBackingBean.getSelected().setContactPhone(customer.getContactPhone());
	orderEditBackingBean.getSelected().setAddress1(customer.getAddress1());
	orderEditBackingBean.getSelected().setAddress2(customer.getAddress2());
	orderEditBackingBean.getSelected().setCity(customer.getCity());
	orderEditBackingBean.getSelected().setState(customer.getStateCode());
	orderEditBackingBean.getSelected().setZip(customer.getZipCode());
	orderEditBackingBean.getSelected().setCorpNode(customer.getCorpNode());
	
    event.getComponent().getParent().getParent().getParent().getChildren().clear();
    
	orderEditBackingBean.getSelected().setCustomerDisable(true);
	orderEditBackingBean.getSelected().setEditButtonVisible(true);
	orderEditBackingBean.getSelected().setSubmitButtonVisible(false);
}

Pentaho Dashboard – Show Message if No Data Available

I do not know how to achieve this in ‘jFreeChartComponent’ or in the CCC (community chart component). My solutions are built with action sequence and that’s where I needed to have this feature.

The concept is simple. After getting the result set from the database through ‘SQLLookupRule’ component, I am checking if the result set length is greater than zero or not. The ‘JavascriptRule’ component is used to determine the length of the result set. And then using the ‘if’ condition I am generating the chart or just a simple string saying ‘No Result Found’.

So my action sequence output will be

<outputs> 
	<image-tag type="string"/>  
	<output type="string"/>
</outputs>

The ‘JavascriptRule’ component to check the result set is simple

<action-definition>
	<component-name>JavascriptRule</component-name>
	<action-type>JavaScript</action-type>
	<action-inputs>
		<queryResult type="result-set" mapping="query_result"/> 
	</action-inputs>
	<action-outputs>
		<noData type="string"/>
	</action-outputs>
	<component-definition>
		<script><![CDATA[noData = "false";
		if(queryResult.getRowCount() == 0){
			noData = "true";
		}]]></script>
	</component-definition>
</action-definition>

So depending upon the result set name my output variable ‘noData’ will be “true” or “false”. And based on the ‘noData’ value I am generating respective output

<actions> 
	<condition><![CDATA[noData == "false"]]></condition>  
	<action-definition> 
		<component-name>ChartComponent</component-name>
		<action-type>Pie Chart</action-type>
		<action-inputs> 
			<chart-data type="result-set" mapping="query_result"/>  
		</action-inputs>
		<action-outputs> 
			<image-tag type="string"/> 
		</action-outputs>
		<component-definition> 
			<chart-attributes> 
			<chart-type>PieChart</chart-type>  
			<title>chartTitle</title>  
			<title-position>top</title-position>  
			<display-labels>false</display-labels>  
			<url-template>javascript:;</url-template>  
			<paramName>label</paramName>  
			<width>350</width>  
			<height>350</height> 
			</chart-attributes> 
		</component-definition> 
	</action-definition>
</actions>
  
<actions>
	<condition><![CDATA[noData == "true"]]></condition>
	<action-definition>
		<component-name>JavascriptRule</component-name>
		<action-type>JavaScript</action-type>
		<action-outputs>
			<output type="string"/>
		</action-outputs>
		<component-definition>
			<script><![CDATA[output = "No Result Found";]]></script>
		</component-definition>
	</action-definition>
</actions>

Pentaho Dashboard – Export Chart Data

To give user an option to export any chart data in csv format is very easy when you use ‘jFreeChartComponent’ to generate the chart. The ‘caption’ option in the chart configuration is used to put a ‘detail’ link beneath every chart. The ‘detail’ link opens up the options to export the chart data and some others.

I didn’t like the  ‘jFreeChartComponent’ because of many reasons. If I do not use mdx queries, I have to expose my normal sql queries in javascript while using ‘jFreeChartComponent’. Also I am not sure how I can make some reusable components while I use ‘jFreeChartComponent’.

So I was looking for a good solution where I can give my dashboard users option to download the chart data in csv format while I generate those chart using action sequences (xaction chartcomponent). I could have used the new Pentaho CCC (community chart component), but my solution was too complex to use CCC’s auto generated code. I searched for a solution in Pentaho’s forums but there was no solutions for this. I started one thread there asking for a suggestion, but nobody could come up with any solution. So then I started thinking for a solution by myself.

It was not possible that the same action sequence will be able to provide me the chart as well as the option to generate csv file from the data. So I broke down the solution into three different parts.

  1. One action sequence is generating the result set querying the database (chartData.xaction)
  2. One action sequence is using ‘SubActionComponent’ and getting the result set from (1) and then generating the chart based on the data using ‘ChartComponent’ (chart.xaction)
  3. The other action sequence is again using ‘SubActionComponent’ to get the result set from (1) and then  using ‘JFreeReportComponent’ to generate the csv file. (csvChart.xaction)

So the part of my action sequence generating the chart looks like

<action-definition>
	<component-name>SubActionComponent</component-name>
	<action-type>Render current Data</action-type>
	<action-inputs/>
	<action-outputs>
		<query_result type="result-set" mapping="query_result"/>
	</action-outputs>
	<component-definition>
		<solution><![CDATA[app]]></solution>
		<path><![CDATA[dashboards/SingleChart]]></path>
		<action><![CDATA[currentData.xaction]]></action>
	</component-definition>
</action-definition>

<action-definition>
	<component-name>ChartComponent</component-name>
	<action-type>Pie Chart</action-type>
	<action-inputs>
		<chart-data type="result-set" mapping="query_result"/>
	</action-inputs>
	<action-outputs>
		<image-tag type="string"/>
	</action-outputs>
	<component-definition>
		<chart-attributes>
			<chart-type>PieChart</chart-type>
			<title>chartTitle</title>
			<title-position>top</title-position>
			<display-labels>false</display-labels>
			<url-template>javascript:;</url-template>
			<paramName>label</paramName>
			<width>350</width>
			<height>350</height>
		</chart-attributes>
	</component-definition>
</action-definition>

Like the same way the part of the action sequence  generating the csv looks like

<action-definition>
	<component-name>SubActionComponent</component-name>
	<action-type>Render current Data</action-type>
	<action-inputs/>
	<action-outputs>
		<query_result type="result-set" mapping="query_result"/>
	</action-outputs>
	<component-definition>
		<solution><![CDATA[app]]></solution>
		<path><![CDATA[dashboards/SingleChart]]></path>
		<action><![CDATA[currentData.xaction]]></action>
	</component-definition>
</action-definition>

<action-definition>
	<component-name>JFreeReportComponent</component-name>
	<action-type>Pentaho Report</action-type>
	<action-inputs>
		<data type="result-set" mapping="query_results"/>
	</action-inputs>
	<action-resources>
		<report-definition type="resource"/>
	</action-resources>
	<action-outputs>
		<report type="content"/>
	</action-outputs>
	<component-definition>
		<output-type>csv</output-type>
	</component-definition>
</action-definition>

So as the action sequences are ready I have to call them in my template file. I am here using ‘ExecuteXaction’ component to call the csvChart.xaction, but before that rendering the chart from the template file is very straight forward.

components[components.length] = {
	name : "currentChart",
	type : "XactionComponent",
	solution : solution,
	path : path,
	action : "chart.xaction",
	listeners : [],
	parameters : [],
	htmlObject : "renderedChart",
	executeAtStart : true,
	postExecution: function(){
		Dashboards.fireChange(csvListner, "csvListner");
	}
};

and the ‘ExecuteXaction’ is listening the ‘csvListner’ and fires the event as soon as the chart is loaded.

components[components.length] = {
	name : "chartCsv",
	type : "ExecuteXaction",
	solution : solution,
	path : path,
	action : "csvCchart.xaction",
	listeners : [currentCsvListner],
	parameters : [],
	htmlObject : "downLoadData",
	label: "Download Data",
	executeAtStart : false
};

The ‘ExecuteXaction’ renders a button saying ‘Download Data’ and once clicked the csv download option comes and asks user to save the file.

Facebook Canvas App Authentication – Java

Facebook will stop supporting canvas FBML apps very soon. So this article only talks about iFrame apps build in Java and using OAuth 2.0 protocol. The basic flow of authentication procedure can be found at facebook’s developer section.

When user is logged in Facebook and access to your app, it sends a signed request to the canvas page of the app using POST method. So in your servlet you have to handle the request in doPost method. Check for the presence of Oauth token in the signed request. If that is not present ask for it.

The signed request is a base64url encoded Json object. Now I couldn’t find anywhere a mapping class which can be mapped to the Json object after base64url decoded signed request. So I had to write it by myself.

public class FacebookSignedRequest {

	private String algorithm;
	private Long expires;
	private Long issued_at;
	private String oauth_token;
	private Long user_id;
	private FacebookSignedRequestUser user;
	
	public String getAlgorithm() {
		return algorithm;
	}
	
	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}
	
	public Long getExpires() {
		return expires;
	}
	
	public void setExpires(Long expires) {
		this.expires = expires;
	}
	
	public Long getIssued_at() {
		return issued_at;
	}
	
	public void setIssued_at(Long issued_at) {
		this.issued_at = issued_at;
	}
	
	public String getOauth_token() {
		return oauth_token;
	}
	
	public void setOauth_token(String oauth_token) {
		this.oauth_token = oauth_token;
	}
	
	public Long getUser_id() {
		return user_id;
	}
	
	public void setUser_id(Long user_id) {
		this.user_id = user_id;
	}

	public FacebookSignedRequestUser getUser() {
		return user;
	}

	public void setUser(FacebookSignedRequestUser user) {
		this.user = user;
	}
	
	public static class FacebookSignedRequestUser {

		private String country;
		private String locale;
		private FacebookSignedRequestUserAge age;
		
		public String getCountry() {
			return country;
		}

		public void setCountry(String country) {
			this.country = country;
		}

		public String getLocale() {
			return locale;
		}

		public void setLocale(String locale) {
			this.locale = locale;
		}

		public FacebookSignedRequestUserAge getAge() {
			return age;
		}

		public void setAge(FacebookSignedRequestUserAge age) {
			this.age = age;
		}

		public static class FacebookSignedRequestUserAge{
			private int min;
			private int max;

			public int getMin() {
				return min;
			}

			public void setMin(int min) {
				this.min = min;
			}

			public int getMax() {
				return max;
			}

			public void setMax(int max) {
				this.max = max;
			}
		}
	}
}

Now I write a Facebook util class which works as a configuration set up for Facebook app

public class FacebookAuthService {

	private static final String apiKey = "APP_KEY";
	private static final String appSecret = "APP_SECRET";
	private static final String appId = "APP_ID";
	
	private static final String redirect_uri = "https://apps.facebook.com/YOUR_APP_PATH";
	
	private static final String[] perms = new String[] {"publish_stream", "email"};
	
	public static String getAPIKey() {
		return apiKey;
	}

	public static String getSecret() {
		return appSecret;
	}

	public static String getLoginRedirectURL() {
		return "https://graph.facebook.com/oauth/authorize?client_id=" + appId
				+ "&display=page&redirect_uri=" + redirect_uri + "&scope="
				+ StringUtils.join(perms);
	}

	public static String getAuthURL(String authCode) {
		return "https://graph.facebook.com/oauth/access_token?client_id="
				+ appId + "&redirect_uri=" + redirect_uri + "&client_secret="
				+ appSecret + "&code=" + authCode;
	}
	
	public static String getAuthURL() {
		return "https://www.facebook.com/dialog/oauth?client_id="
				+ appId + "&redirect_uri=" + redirect_uri + "&scope="
				+ StringUtils.join(perms);
	}
	
	public static FacebookSignedRequest getFacebookSignedRequest(String signedRequest) throws Exception{
		
		String payLoad = signedRequest.split("[.]", 2)[1];
		payLoad = payLoad.replace("-", "+").replace("_", "/").trim();
		
		String jsonString = new String(Base64.decodeBase64(payLoad));
		return new ObjectMapper().readValue(jsonString, FacebookSignedRequest.class);
	}
}

I’ve used Jackson to map Json to Object here. But any other API can be used too.

Now in my entry servlet (my canvas URL) I check for it in the doPost method like

String signedRequest = (String) request.getParameter("signed_request");

FacebookSignedRequest facebookSignedRequest = FacebookAuthService.getFacebookSignedRequest(signedRequest);
PrintWriter writer = response.getWriter();
if (facebookSignedRequest.getOauth_token() == null) {
	response.setContentType("text/html");
	writer.print("<script> top.location.href='"	+ FacebookAuthService.getAuthURL() + "'</script>");
	writer.close();
} else {
	request.setAttribute("accessToken",	facebookSignedRequest.getOauth_token());
	RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher("/YOUR_NEXT_PATH");
	requestDispatcher.forward(request, response);
}

So, if the Oauth token is not present in the signed request the servlet redirects user to get the app permission. Once user allows the app the servlet gets the Oauth token in the signed request and pass it to the next page of the app.

REST Template Using Apache HttpClient

Calling REST web services using Spring’s RestTemplate has been already covered in the other post. Here is a template which can be used out side of Spring. A generalize REST template using Apache’s HttpClient API.

package com.your.package.name;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;

public class RestClient {
	public static final int HTTP_OK = 200;
	public static final String SERVER_URL = "BASE URL OF THE REST SERVER";

	public static String doGet(final String url) throws HttpException,
			IOException, URISyntaxException {

		final HttpClient httpClient = new DefaultHttpClient();
		HttpConnectionParams
				.setConnectionTimeout(httpClient.getParams(), 10000);
		HttpGet httpget = new HttpGet(SERVER_URL + url);
		HttpResponse response = httpClient.execute(httpget);
		HttpEntity entity = response.getEntity();
		InputStream instream = entity.getContent();
		return read(instream);
	}

	public static String doPost(final String url, final String POSTText)
			throws URISyntaxException, HttpException, IOException {

		final HttpClient httpClient = new DefaultHttpClient();
		HttpConnectionParams
				.setConnectionTimeout(httpClient.getParams(), 10000);

		HttpPost httpPost = new HttpPost(SERVER_URL + url);
		StringEntity entity = new StringEntity(POSTText, "UTF-8");
		BasicHeader basicHeader = new BasicHeader(HTTP.CONTENT_TYPE,
				"application/json");
		httpPost.getParams().setBooleanParameter(
				"http.protocol.expect-continue", false);
		entity.setContentType(basicHeader);
		httpPost.setEntity(entity);
		HttpResponse response = httpClient.execute(httpPost);
		InputStream instream = response.getEntity().getContent();
		return read(instream);
	}

	public static boolean doPut(final String url, final String PUTText)
			throws URISyntaxException, HttpException, IOException {
		final HttpClient httpClient = new DefaultHttpClient();
		HttpConnectionParams
				.setConnectionTimeout(httpClient.getParams(), 10000);

		HttpPut httpPut = new HttpPut(SERVER_URL + url);
		httpPut.addHeader("Accept", "application/json");
		httpPut.addHeader("Content-Type", "application/json");
		StringEntity entity = new StringEntity(PUTText, "UTF-8");
		entity.setContentType("application/json");
		httpPut.setEntity(entity);
		HttpResponse response = httpClient.execute(httpPut);
		int statusCode = response.getStatusLine().getStatusCode();
		return statusCode == HTTP_OK ? true : false;
	}

	public static boolean doDelete(final String url) throws HttpException,
			IOException, URISyntaxException {
		final HttpClient httpClient = new DefaultHttpClient();
		HttpConnectionParams
				.setConnectionTimeout(httpClient.getParams(), 10000);

		HttpDelete httpDelete = new HttpDelete(SERVER_URL + url);
		httpDelete.addHeader("Accept",
				"text/html, image/jpeg, *; q=.2, */*; q=.2");
		HttpResponse response = httpClient.execute(httpDelete);
		int statusCode = response.getStatusLine().getStatusCode();
		return statusCode == HTTP_OK ? true : false;
	}

	private static String read(InputStream in) throws IOException {
		StringBuilder sb = new StringBuilder();
		BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
		for (String line = r.readLine(); line != null; line = r.readLine()) {
			sb.append(line);
		}
		in.close();
		return sb.toString();
	}
}

And it can be used like

RestClient.doDelete("/registration/" + userToken);
RestClient.doGet("/me/profile?ct=" + userToken);

Extract Text from HTML using NekoHTML and Dom4j

Consider the link http://www.cdw.com/shop/search/results.aspx?wclss=C3&enkwrd=laptop&searchscope=ALL.
Lets extract the total search result and title of each item to keep the example simple enough. We will be using XPath to find each element in the HTML page.
Here is the code

package com.asc.dyutiman.html;

import java.io.IOException;
import java.util.List;

import org.cyberneko.html.parsers.DOMParser;
import org.dom4j.Node;
import org.dom4j.io.DOMReader;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class Parse {
	
	public static void main(String[] args){
		
		String url = "http://www.cdw.com/shop/search/results.aspx?wclss=C3&enkwrd=laptop&searchscope=ALL";
		try {
			DOMParser parser = new DOMParser();
			parser.parse(url);
			
			Document document = parser.getDocument();
			DOMReader reader = new DOMReader();
			org.dom4j.Document doc = reader.read(document);
			
			Node totalResultNode = doc.selectSingleNode("//SPAN[@id='lblShowingResultsTop']/B[3]");
			
			@SuppressWarnings("unchecked")
			List<Node> itemList =  doc.selectNodes("//DIV[@class = 'searchrow']");

			System.out.println("Showing " + itemList.size() + " out of " + totalResultNode.getText());
			for(Node itemNode : itemList){
				Node itemTitle = itemNode.selectSingleNode("DIV[@class = 'searchrow-description']/A");
				System.out.println(itemTitle.getText());
			}
		} catch (SAXException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}
}

Remember to use uppercase for any HTML tag.