- Class Under Test:
DateFormatter.java
package sample;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatter {
public static final String DATE_FORMAT = "MM/dd/yyyy";
private DateFormatterHelper helper = null;
public DateFormatter() {
}
public String convertToStandardFormat(String dateString, String format) throws ParseException {
if (dateString == null || dateString.equals(""))
return "";
dateString = dateString == null ? "" : dateString;
DateFormat df = helper.getDateFormat(format);
Date date = df.parse(dateString);
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
return sdf.format(date);
}
public DateFormatterHelper getHelper() {
return helper;
}
public void setHelper(DateFormatterHelper helper) {
this.helper = helper;
}
} - Helper Class and Interface: If you are to mock any class using EasyMock, it is required that you have an interface for the class. If you are following the old design principle "program to an interface, not an implementation", you are good here.
DateFormatterHelper.java
package sample;
import java.text.DateFormat;
public interface DateFormatterHelper {
public DateFormat getDateFormat(String format);
}
DateFormatterHelperImpl.java
package sample;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateFormatterHelperImpl implements DateFormatterHelper {
public DateFormatterHelperImpl() {
}
public DateFormat getDateFormat(String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setCalendar(Calendar.getInstance());
sdf.setLenient(false);
return sdf;
}
public static void main(String args[]) {
DateFormatterHelper helper = new DateFormatterHelperImpl();
try {
System.out.println(helper.getDateFormat("MM/dd/yyyy").parse("11/27/2008"));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} - The test class:
DateFormatterTests.java
package tests;
import static org.junit.Assert.fail;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import sample.DateFormatter;
import sample.DateFormatterHelper;
public class DateFormatterTests {
private DateFormatter formatter = null;
DateFormatterHelper helper = null;
@Before
public void setUp() throws Exception {
helper = EasyMock.createMock(DateFormatterHelper.class);
formatter = new DateFormatter();
formatter.setHelper(helper);
}
@Test
public void testConvertToStandardFormat() {
String formatted = null;
try {
EasyMock.expect(helper.getDateFormat("MM-dd-yyyy")).andReturn(new SimpleDateFormat("MM-dd-yyyy"));
EasyMock.replay(helper);
formatted = formatter.convertToStandardFormat("11-27-2008", "MM-dd-yyyy");
} catch (ParseException e) {
e.printStackTrace();
fail("Exception");
}
Assert.assertEquals(formatted, "11/27/2008");
}
}
Note that in the EasyMock.expect method line, we use the "andReturn" method. This is to define the expected behavior when the method under test is invoked by the testcase. As can be expected, the replay method simply replays the pre-defined behavior when the actual call is made on the mock object.
Wednesday, July 15, 2009
EasyMock for Unit Tests
One of the basic requirements for unit testing is the creation of mock objects. Easy mock is a library that helps to dynamically create mock objects. This way we can avoid much of the tedious work involved in manually coding mock objects. However, EasyMock itself is not the silver bullet, we still have to define expectations in test cases. Using EasyMock also means that you have make certain design changes (if your design follows the usual design principles you may not have to change much. Here's a sample Unit Test using EasyMock. You can download easymock from here.
Tuesday, March 24, 2009
Invoking Web Services through a proxy using JAX-RPC and JAX-WS
Not very often, we face the possibility of invoking Web Services provided by external entities that are outside our network. Some companies solve this by configuring their network to allow some application servers to bypass proxy servers. Whatever be the case, when in development, developers have to to be able to invoke web services through proxies. This post will be describe how to
There's More ...
- Invoking Web Services through a proxy using JAX-RPC
- Invoking Web Services through a proxy using JAX-WS
There's More ...
Invoking Web Services through a proxy using JAX-RPC
- Generate the Web Service Proxy classes using the following ant task.
<taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
<target name="build-client">
<clientgen
wsdl="[path_to_WSDL]"
destDir="./src"
packageName="com.my.client"
type="JAXRPC"/>
</target> - When the client classes are generated the type as JAXRPC, the generated classes will consist of Service, ServiceImpl, PortType and ProtTypeImpl etc files. To invoke the service you have to create the PortType from the Service. When working behind a proxy, you have to instantiate the ServiceImpl by using a constructor that takes in a weblogic.wsee.connection.transport.http.HttpTransportInfo.HttpTransportInfo object as a parameter as shown below.
private HttpTransportInfo getHttpInfo() {
When using SSL, you can use the weblogic.wsee.connection.transport.https.HttpsTransportInfo class which can be created in the same way as above.
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxyServer", 9090));
HttpTransportInfo httpInfo = new HttpTransportInfo();
httpInfo.setProxy(proxy);
httpInfo.setProxyUsername("proxyuser".getBytes());
httpInfo.setProxyPassword("proxypassword".getBytes());
return httpInfo;
}
Invoking Web Services through a proxy using JAX-WS
- When using JAX-WS, you have to change the clientgen task's "type" attribute to JAXWS, as shown below
<taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
Make sure that the "path_to_WSDL" is to a local copy of the WSDL, as the properties which we set in the following steps are after the initialization of the service.
<target name="build-client">
<clientgen
wsdl="[path_to_WSDL]"
destDir="./src"
packageName="com.my.client"
type="JAXWS"/>
</target> - Running clientgen with JAXWS will create classes of the type *Service and *ServiceSoap
- Setting up the client for proxy server involves setting a couple of request paramters: Username and password as shown below.
MyService service = null;
Note that we don't specify the Proxy Server here. JAX-WS sends authentication information for the proxy in request headers.
service = new MyService();
MyServiceSoap port = service.getMyServiceSoap();
BindingProvider bp = (BindingProvider) port;
Binding binding = bp.getBinding();
Map<String, Object> ctx = bp.getRequestContext();
ctx.put(BindingProvider.USERNAME_PROPERTY, "proxyuser");
ctx.put(BindingProvider.PASSWORD_PROPERTY, "proxypassword");
Tuesday, October 21, 2008
RESTful Web Services
Representational State Transfer(REST), a software architecture style used in developing stateless web services. While this style may be used to describe any distributed framework that uses a simple protocol for data transmission and no other additional data transfer rules, the most common use of REST is on on the Web with HTTP being the only protocol used here. In REST each service (called "resource" in REST) is viewed as resource identified by a URL, and the only operations allowed are the HTTP - GET (Read), PUT (Update), POST(Create) and DELETE (Delete). You can find this style similar in SQL, thinking of a resource as equivalent to a Table. The main features and constraints of REST architectural style are:
Given that every resource in a RESTful service is represented by a URL, it is easy to write a client for such a web service. The following is the code for a simple Web Service client for the flickr web services interface.
There's More
- Client-Server: A clear separation concerns is the reason behind this constraint. Separating concerns between the Client and Server helps improve portability in the Client and Scalability of the server components.
- Stateless: All REST resources are required to be stateless. The idea is that the application would be resilient enough to work between server restarts. However, it is not uncommon to see some RESTful web services save states between requests.
- Caching: Caching is allowed, however it is required that "response to a request be implicitly or explicitly labeled as cacheable or non-cacheable"
- As there is no interface definition (like in SOAP), it becomes mandatory for a Client and Server to have a mutual understanding of the messages being transmitted between them.
Given that every resource in a RESTful service is represented by a URL, it is easy to write a client for such a web service. The following is the code for a simple Web Service client for the flickr web services interface.
There's More
package main;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class FlickrClient {
public static void main(String[] args) {
String flickrURL = "http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value&api_key=[yourflickrkey]";
try {
SocketAddress addr = new InetSocketAddress("[proxy]", 9090);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
URL u = new URL("http://api.flickr.com/services/rest/?method=flickr.test.echo&name=value&api_key=[yourflickrkey]");
HttpURLConnection uc = (HttpURLConnection) u.openConnection(proxy);
uc.setRequestProperty("Accept", "*/*");
uc.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
uc.setRequestProperty("Accept-Language", "en-us,en;q=0.5");
uc.setRequestProperty("Keep-Alive", "300");
uc.setRequestProperty("ucection", "keep-alive");
String proxyUser = "[netUserId]";
String proxyPassword = "[netPassword]";
uc.setRequestProperty("Proxy-Authorization", "NTLM " + new sun.misc.BASE64Encoder().encode((proxyUser +
":" + proxyPassword).getBytes()));
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = docBuilder.parse(uc.getInputStream());
System.out.println(doc.getDocumentElement().getTagName());
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- Note that the request URL has a method parameter.
http://api.flickr.com/services/rest/?method=flickr.test.echo
This is is not strictly adhering to the principles of REST, however it is not uncommon. Ideally the URL should behttp://api.flickr.com/services/rest/flickrtestecho
You would make a GET request on this resource.
Friday, October 10, 2008
Tuesday, July 29, 2008
Binary Search Tree in Java with Generics
This post is more about generics than the actual implementation of the binary search tree. I tried to implement some of the suggestions in the developerworks articles titled "Java theory and practice: Going wild with generics". The Binary Search Tree of this example uses the first two suggestions. The rest are equally helpful though.
- A generic factory method that allows you to avoid redundantly specifying type parameters
public static<T extends Comparable<? super T>> BinarySearchTree<T> createTestTree()
Can be used as shown below.BinarySearchTree<Test> tree = BinarySearchTree.createTestTree();
- By using bounded wildcards, we can now construct a tree with both the super and sub-class type objects.
public class BinarySearchTree<T extends Comparable<? super T>>
- The get-put principle
Use an extends wildcard when you only get values out of a structure, use a super wildcard when you only put values into a structure, and don't use a wildcard when you do both.
- Wildcard capture: Use a generic method as a capture helper to workaround compiler's limitations dealing with wildcards. (refer to the article "Java theory and practice: Going wild with generics, Part 1")
package trees;References
import java.util.NoSuchElementException;
public class BinarySearchTree<T extends Comparable<? super T>> {
private Entry<T> root;
public BinarySearchTree() {
root = null;
}
public static<T extends Comparable<? super T>> BinarySearchTree<T> createTestTree() {
return new BinarySearchTree<T>();
}
public void insert(T value) {
root = insert(value, root);
}
public void remove(T value) {
root = remove(value, root);
}
public boolean contains(T value) {
return valueOf(find(value, root)) != null;
}
private T valueOf(Entry<T> entry) {
return entry == null ? null : entry.element;
}
private Entry<T> insert(T value, Entry<T> entry) {
if (entry == null)
entry = new Entry<T>(value);
else if (value.compareTo(entry.element) < 0)
entry.left = insert(value, entry.left);
else if (value.compareTo(entry.element) > 0)
entry.right = insert(value, entry.right);
else
throw new RuntimeException("Duplicate Entry : " + value.toString());
return entry;
}
private Entry<T> remove(T value, Entry<T> entry) {
if (entry == null)
throw new NoSuchElementException("Entry not found : " + value.toString());
if (value.compareTo(entry.element) < 0)
entry.left = remove(value, entry.left);
else if (value.compareTo(entry.element) > 0)
entry.right = remove(value, entry.right);
else {
// Entry found.
if (entry.left != null && entry.right != null) {
// Replace with in-order successor (the left-most child of the right subtree)
entry.element = findMin(entry.right).element;
entry.right = removeInorderSuccessor(entry.right);
// Replace with in-order predecessor (the right-most child of the left subtree)
// entry.element = findMax(entry.left).element;
// entry.left = removeInorderPredecessor(entry.left);
} else
entry = (entry.left != null) ? entry.left : entry.right;
}
return entry;
}
private Entry<T> removeInorderSuccessor(Entry<T> entry) {
if (entry == null)
throw new NoSuchElementException();
else if (entry.left != null) {
entry.left = removeInorderSuccessor(entry.left);
return entry;
} else
return entry.right;
}
private Entry<T> removeInorderPredecessor(Entry<T> entry) {
if (entry == null)
throw new NoSuchElementException();
else if (entry.right != null) {
entry.right = removeInorderPredecessor(entry.right);
return entry;
} else
return entry.left;
}
private Entry<T> findMin(Entry<T> entry) {
if (entry != null)
while (entry.left != null)
entry = entry.left;
return entry;
}
private Entry<T> findMax(Entry<T> entry) {
if (entry != null)
while (entry.right != null)
entry = entry.right;
return entry;
}
private Entry<T> find(T value, Entry<T> entry) {
while (entry != null) {
if (value.compareTo(entry.element) < 0)
entry = entry.left;
else if (value.compareTo(entry.element) > 0)
entry = entry.right;
else
return entry;
}
return null;
}
private void printInOrder(Entry<T> entry) {
if (entry != null) {
printInOrder(entry.left);
System.out.println(entry.element);
printInOrder(entry.right);
}
}
public void printInOrder() {
printInOrder(root);
}
private static class Entry<T extends Comparable<? super T>> {
T element;
Entry<T> left;
Entry<T> right;
Entry(T theElement) {
element = theElement;
left = right = null;
}
}
private static class Test implements Comparable<Test> {
private String value;
public Test(String value) {
this.value = value;
}
public String toString() {
return value;
}
@Override
public int compareTo(Test o) {
return this.value.compareTo(o.toString());
}
}
private static class Test1 extends Test {
public Test1(String value) {
super(value);
}
}
public static void main(String[] args) {
BinarySearchTree<Test> tree = BinarySearchTree.createTestTree();
int size = 20;
for (int i = 0; i <= size; i++) {
tree.insert(new Test1(String.valueOf(i)));
}
tree.insert(new Test1("100"));
tree.remove(new Test1("10"));
tree.remove(new Test1(String.valueOf(15)));
tree.remove(new Test1(String.valueOf(20)));
tree.printInOrder();
System.out.println("Contains (10) : " + tree.contains(new Test1("10")));
System.out.println("Contains (11) : " + tree.contains(new Test1(String.valueOf(11))));
}
}
Monday, July 28, 2008
Cricular Linked List in Java
Had to implement a circular linked list recently. Here's my take, suggestions are welcome. The list can be parameterized for any type which has a meaningful equals method defined. The main method shows a sample usage of the Circular linked list with the String type. Only add, remove and size method are implemented.
There's more ...
There's more ...
package algo;
import java.util.NoSuchElementException;
public class CircularLinkedList<E> {
private Entry<E> head;
// Last element of the list. tail.next = head
private Entry<E> tail;
private int size = 0;
/**
* Class to hold the individual elements.
* @param <E>
*/
private static class Entry<E> {
E element;
Entry<E> next;
Entry(E element, Entry<E> next) {
this.element = element;
this.next = next;
}
Entry(E element) {
this.element = element;
}
}
public CircularLinkedList() {
head = null;
}
/**
* Remove obj from the circular linked list and return the removed object
* @param obj
* @return
*/
public E remove(E obj) {
if (head == null || tail == null)
throw new NoSuchElementException();
Entry<E> current = head, temp = head, found = null;
if (obj.equals(head.element)) {
if (head.next == head) {
found = head;
head = null;
tail = null;
size--;
return found.element;
} else {
found = head;
temp = tail;
}
} else {
current = head.next;
while (current != head) {
if (current.element.equals(obj)) {
found = current;
break;
}
temp = current;
current = current.next;
}
}
if (found == null) {
throw new NoSuchElementException(obj.toString());
}
E result = found.element;
temp.next = found.next;
found.next = null;
found.element = null;
size--;
return result;
}
/**
* Add obj to the circular linked list.
* @param obj
*/
public void add(E obj) {
Entry e = new Entry(obj);
if (head == null) {
size++;
head = e;
head.next = head;
tail = head;
return;
}
size++;
e.next = head;
head = e;
tail.next = head;
}
/**
* Size of the list.
* @return
*/
public int size() {
return size;
}
public static void main(String[] args) {
CircularLinkedList<String> list = new CircularLinkedList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
System.out.println(list.remove("Three"));
System.out.println(list.remove("Two"));
System.out.println(list.remove("One"));
System.out.println(list.remove("Four"));
System.out.println(list.remove("Four"));
}
}
Monday, July 14, 2008
Detecting Code Smells With Eclipse and CheckStyle
In a new article "Automation for the people: Continual refactoring" as a part of the "Automation for the people" series, Paul Duvall discusses the use of static code analysis tools to identify code smells and suggested refactorings. The article shows how to
There's MoreThe following is a short list of static code analysis tools available for JavaThis post describes how to identify common code smells using CheckStyle and Eclipse. Checkstyle has a useful eclipse plugin. Installing the plugin is simple. In Eclipse Ganymede,
- Reduce conditional complexity code smells by measuring cyclomatic complexity using CheckStyle and providing refactorings such as Replace Conditional with Polymorphism
- Remove duplicated code code smells by assessing code duplication using CheckStyle and providing refactorings such as Pull Up Method
- Thin large class code smells by counting source lines of code using PMD (or JavaNCSS) and providing refactorings such as Extract Method
- Wipe out too many imports code smells by determining a class's efferent coupling using CheckStyle (or JDepend) and providing refactorings such as Move Method
- Go to Help->Software Updates->Software Updates->Available Software
- Click on Add Site, and add http://eclipse-cs.sourceforge.net/update to the sites list
- Select the new site and click Install
Conditional complexity | Metrics->Cyclomatic Complexity |
|
Duplicated code | Duplicates->Strict Duplicate Code |
|
Long method | Size Violations->Maximum Method Length |
|
Subscribe to:
Posts (Atom)
Popular Posts
-
This post will describe how to create and deploy a Java Web Application war to Heroku using Heroku CLI. You will need a basic understanding ...
-
In a previous post, I described how to use Quartz scheduler for scheduling . In this post, I describe the configuration changes required for...
-
The previous post described how to implement a JMS messaging client using Spring JMS . This post will describe how to implement the Message ...
-
JUnit 4 introduces a completely different API to the older versions. JUnit 4 uses Java 5 annotations to describe tests instead of using in...
-
New posts with iText 5.5.12 Following are two new posts for PDF Merge with iText 5.5.12 Merge PDF files using iText 5 Merge and Paginate PDF...
-
Previously, I wrote a post describing the use of Apache Axis to create and consume Web Services from Java . In this post, I will describe ho...
-
In this post we will see how to do an offline install Jenkins and required plugins on a Red Hat Enterprise Linux Server release 7.3. This is...
-
I came know of this quite recently. I find it quite useful. Apart from being able share your bookmarks across browsers, you can now share th...
-
In the past, I had a few posts on how to implement pagination using displaytag( 1 , 2 ). That solution is feasible only with small result se...
-
Acegi Security provides a comprehensive security solution for J2EE-based enterprise software applications, built using the Spring Framework...