Wednesday, December 2, 2009

How to search in Google ??

Basic Boolean

Whenever you search for more than one keyword at a time, Google will search for all of them. If you search for
XML Java "web Services"
Google will search for all the words. If you want to specify that either word is acceptable, you put an OR between each item
XML OR Java OR "Web Services"
If you want to have definitely one term and one of two or more other terms, you group them with parentheses, like this
XML (Java OR "Web Services")
This query searches for the word “Java” or phrase “Web Services” along with the word “XML.” A stand-in for OR borrowed from the computer programming realm is the | (pipe) character, as in
XML (Java | "Web Services")
If you want to specify that a query item must not appear in your results, use a -.(minus sign or dash).
XML Java -"Web Services"
This will search for pages that contain both the words “XML” and “Java” but not the phrase “Web Services.”

Operators

In addition to the basic AND, OR, and quoted strings, Google offers some rather extensive special syntaxes for honing your searches. Google being a full-text search engine, it indexes entire web pages instead of just titles and descriptions. Additional commands, called special syntaxes, let Google users search specific parts of web pages or specific types of information. Specifying that your query words must appear only in the title or URL of a returned web page is a great way to have your results get very specific without making your keywords themselves too specific.
Here are some of the common keywords that you can add to your query in Google

intitle, allintitle

Restricts your search to the titles of web pages. The variation, allintitle: finds pages wherein all the words specified make up the title of the web page. It’s probably best to avoid the allintitle: variation, because it doesn’t mix well with some of the other syntaxes.
Eg: intitle:"george bush"
allintitle:"money supply" economics

inurl, allinurl

Restricts your search to the URLs of web pages. This syntax tends to work well for finding search and help pages, because they tend to be rather regular in composition. An allinurl: variation finds all the words listed in a URL but doesn’t mix well with some other special syntaxes.
Eg: inurl:help
allinurl:search help

intext, allintext

Searches only body text (i.e., ignores link text, URLs, and titles). There’s an allintext: variation, but again, this doesn’t play well with others. While its uses are limited, it’s perfect for finding query words that might be too common in URLs or link titles.
Eg: intext:"yahoo.com"
allintext:html

inanchor

Searches for text in a page’s link anchors. A link anchor is the descriptive text of a link. For example, the link anchor in the HTML code O’Reilly and Associates is “O’Reilly and Associates.”
Eg: inanchor:"tom peters"

site

Allows you to narrow your search by either a site or a top-level domain. AltaVista, for example, has two syntaxes for this function (host: and domain:), but Google has only the one.
Eg: site:loc.gov
site:thomas.loc.gov
site:edu
site:nc.us
You can also use site: operator to exclude certain domains from a search
Eg: google -site:google.com
This is particularly useful for ego searches. You can find out all those sites which mention your name expect your site.
Eg: bill gates -site:microsoft.com -site:wikipedia.org

link

Returns a list of pages linking to the specified URL. Enter link:www.google.com and you’ll be returned a list of pages that link to Google. Don’t worry about including the http:// bit; you don’t need it, and, indeed, Google appears to ignore it even if you do put it in. link: works just as well with “deep” URLs-http://www.raelity.org/apps/blosxom/ for instance-as with top-level URLs such as raelity.org.
Eg: link:www.google.com

cache

Finds a copy of the page that Google indexed even if that page is no longer available at its original URL or has since changed its content completely. This is particularly useful for pages that change often. If Google returns a result that appears to have little to do with your query, you’re almost sure to find what you’re looking for in the latest cached version of the page at Google.
Eg: cache:www.yahoo.com

filetype

Searches the suffixes or filename extensions. These are usually, but not necessarily, different file types. I like to make this distinction, because searching for filetype:htm and filetype:html will give you different result counts, even though they’re the same file type. You can even search for different page generators, such as ASP, PHP, CGI, and so forth-presuming the site isn’t hiding them behind redirection and proxying. Google indexes several different Microsoft formats, including: PowerPoint (PPT), Excel (XLS), and Word (DOC).
Eg: homeschooling filetype:pdf
"leading economic indicators" filetype:ppt

related

Finds pages that are related to the specified page. Not all pages are related to other pages. This is a good way to find categories of pages; a search for related:google.com would return a variety of search engines, including HotBot, Yahoo!, and Northern Light.
Eg: related:www.yahoo.com
related:www.cnn.com

info

Provides a page of links to more information about a specified URL. Information includes a link to the URL’s cache, a list of pages that link to that URL, pages that are related to that URL, and pages that contain that URL. Note that this information is dependent on whether Google has indexed that URL or not. If Google hasn’t indexed that URL, information will obviously be more limited.
Eg: info:www.oreilly.com
info:www.nytimes.com/technology

define

Will get the definition of the term that you have entered. This syntax can be used to get the definitions of words, phrases, and acronyms
Eg: define:dreaming
This query will get you the definition of the word dreaming

numrange

If you want to search for a range of numbers then you can use two dots (without spaces) to represent a range of numbers
Eg: inventions 1850..1899
This query will get you all the inventions between 1850 and 1899

safesearch

If you include safesearch: in your query, Google will exclude adult-content.
Eg: safesearch:breasts
This will search for information on breasts without returning adult or pornographic sites.

stocks

If you start your query with stocks:, Google will interpret the rest of the query terms as NYSE, NASDAQ, AMEX, or mutual fund stock ticker symbols, and will open a page showing stock information for the symbols you specify.
Eg: stocks:goog
This will show information about Google’s stock. Specify ticker symbols not company names. If you enter an invalid ticker symbol, you’ll be told so and given a link to a page where you can look up a valid ticker symbol.

The Special Syntaxes

Currency Conversion

Google makes it easy to calculate money conversions from one form of currency to another.
Eg: $5 in yenThe above query will let you know that five dollars is worth about 566.599846 yen.
If you’re not sure of the name of a currency, use nationality instead.
Eg: 25 Australian money in Italian money
This may sound awkward but it does the job.
Eg: $5 in indian money
This will let you know that 5 US dollars is worth about 224.477976 Indian rupees
You can even convert units in this fashion.
Eg: $2.85 per gallon in British money per literThis query will tell you that it is about 42 pence per liter and provides an international basis for discussing gas prices at the pump.

Check Airfares

When you google for the names of two major cities, Google automatically offers to search for flights.
Eg: Denver Fort Lauderdale
In the form labeled “Flights from Denver, CO to Fort Lauderdale, FL”, enter a departure and return date and choose whether to search using Expedia, Hotwire or Orbitz. Do not use quotation marks in your initial search. Denver “Fort Lauderdale” will not bring up the flight search form.

Find Song Lyrics

If you are looking for the title or lyrics of a song then you can use Google search phrases and wildcards to find them.
Eg: "Friday I am in love" lyrics
Or use the wildcard operator to get lyrics with certain words in them, like this
"Friday * love" lyrics
This compilation is just a tip of the iceberg of the features available in Google’s search syntax. If you come across any other special syntax, then do let me know so that I can add it.

Fetch only Fresh results
First one is to narrow down your search to only the most recent web pages. This is particularly important, since Google has started serving fresh results.
Alex Chitu from the unofficial Google Operating system blog has found that we can use as_qdr query parameter to search only for fresh pages.
In order to use this you have to add a new parameter as_qdr at the end of the url like below
http://www.google.com/search?q=ipod&as_qdr=d
The as_qdr parameter can take the following possible values.
  • d[number] – past number of days (e.g.: d5)
  • w[number] – past number of weeks (e.g: w5)
  • y[number] – past number of years (e.g: y5)
More explanations by Matt Cutts and also at Life hacker.
Cricket

Being born in India, circket is there in my blood and the same for Sadeesh Duraisamy who works in Google. Thanks to him and now we can keep an eye on the latest circket scores by just typing the word cricket in Google’s search box.
Well, it’s time for me to watch the do-or-die match with South Africa for India in the latest twenty20 tournament. :)


In addition to fetching fresh results and following cricket scores, you can also now also get the current time for any city by just searching in Google.
All you have to do is just type time followed by the city name
Eg: time Chennai
Google Time Query
You can also search by typing the time zone
Eg: time central
Google Time Query
Next time when I have to send a meeting request to my clients (who are in US), I can save a few seconds by doing a Google search rather than changing the timezone in my computer clock to find their current time.

Wednesday, November 25, 2009

Hibernate (annotations) - how to get started??

My experiences and background were similar, and I also had a hard time finding a tutorial that addressed my development preferences (which seem similar to yours):
  • Prefer JPA annotations over XML, only adding Hibernate annotations when the JPA counterparts do not suffice
  • Use Hibernate's SessionFactory / Session to access persistent data rather than JPA EntityManager
  • Use immutable classes wherever possible
I read most of Java Persistence with Hibernate, and it took a long time to separate this use case from all the other options that it presents (XML configuration in Hibernate/JPA format, xdoclet "annotations", etc...).
It would have made so much more sense to me if the available documentation would take a stand and actively push me in this direction instead of giving me a bunch of options and wondering where to go. Lacking that, I learned the following lessons by converting the standard Hibernate Tutorial over to annotations.

Configuration

  • Keep hibernate.cfg.xml to the bare minimum (see below).
  • Define database column / table names explicitly with the JPA annotations so you get exactly the schema you want. You can double-check it by using SchemaExport.create(true, false). Note that you may not get the exact schema you expect if Hibernate tries to update the schema on an existing database (for example, you can't add a NOT NULL constraint to a column that already contains null values).
  • Create the SessionFactory's Configuration using AnnotationConfiguration.addAnnotatedClass().addAnnotatedClass()...
Here's my copy of hibernate.cfg.xml. It only sets properties, and explicitly avoids any mapping configuration.


    
            
        org.hsqldb.jdbcDriver
        jdbc:hsqldb:hsql://localhost
            sa
            
            1
            org.hibernate.dialect.HSQLDialect

            
            update
            thread
            org.hibernate.cache.NoCacheProvider
            false
    




Scope

  • Begin/commit/rollback transactions outside each Manager / DAO class. I have no idea why the tutorial's EventManager starts/commits its own transactions, as the book identifies this as being an anti-pattern. For the servlet in the tutorial, this can be done by making a Filter that starts the transaction, invokes the rest of the FilterChain, and then commits/rolls back the transaction.
  • Similarly, make the SessionFactory outside and pass it in to each Manager / DAO class, which then calls SessionFactory.getCurrentSession() any time it needs to access data. When it comes time to unit test your DAO classes, make your own SessionFactory that connects to an in-memory database (such as "jdbc:hsqldb:mem:test") and pass it into the DAO being tested.
For example, some snippets from my version of EventManager:

public final class EventManager {

private final SessionFactory sessionFactory;

/** Default constructor for use with JSPs */
public EventManager() {

        this.sessionFactory = HibernateUtil.getSessionFactory();
}

/** @param Nonnull access to sessions with the data store */
public EventManager(SessionFactory sessionFactory) {

        this.sessionFactory = sessionFactory;
}

    /** @return Nonnull events; empty if none exist */
public List getEvents() {

        final Session db = this.sessionFactory.getCurrentSession();
        return db.createCriteria(Event.class).list();
}

/**
 * Creates and stores an Event for which no people are yet registered.
 * @param title Nonnull; see {@link Event}
 * @param date Nonnull; see {@link Event}
 * @return Nonnull event that was created
 */
public Event createEvent(String title, Date date) {

        final Event event = new Event(title, date, new HashSet ());
        this.sessionFactory.getCurrentSession().save(event);
        return event;
}

/**
 * Registers the specified person for the specified event.
 * @param personId ID of an existing person
 * @param eventId ID of an existing event
 */
public void register(long personId, long eventId) {

        final Session db = this.sessionFactory.getCurrentSession();
        final Person person = (Person) db.load(Person.class, personId);
        final Event event = (Event) db.load(Event.class, eventId);
        person.addEvent(event);
        event.register(person);
}

...other query / update methods...
}


Data classes

  • Fields are private
  • Getter methods return defensive copies since Hibernate can access the fields directly
  • Don't add setter methods unless you really have to.
  • When it is necessary to update some field in the class, do it in a way that preserves encapsulation. It's much safer to call something like event.addPerson(person) instead of event.getPeople().add(person)
For example, I find this implementation of Event much simpler to understand as long as you remember that Hibernate accesses fields directly when it needs to.


@Entity(name="EVENT")
public final class Event {

private @Id @GeneratedValue @Column(name="EVENT_ID") Long id; //Nullable

/* Business key properties (assumed to always be present) */
private @Column(name="TITLE", nullable=false) String title;

@Column(name="DATE", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
private Date date;

/* Relationships to other objects */
@ManyToMany
@JoinTable(
name = "EVENT_PERSON",
joinColumns = {@JoinColumn(name="EVENT_ID_FK", nullable=false)},
inverseJoinColumns = {@JoinColumn(name="PERSON_ID_FK", nullable=false)})
private Set<Person> registrants; //Nonnull

public Event() { /* Required for framework use */ }

/**
* @param title Non-empty name of the event
* @param date Nonnull date at which the event takes place
* @param participants Nonnull people participating in this event
*/
public Event(String title, Date date, Set<Person> participants) {

this.title = title;
this.date = new Date(date.getTime());
this.registrants = new HashSet<Person> (participants);
}

/* Query methods */

/** @return Nullable ID used for persistence */
public Long getId() {

return this.id;
}

public String getTitle() {

return this.title;
}

public Date getDate() {

return new Date(this.date.getTime());
}

/** @return Nonnull people registered for this event, if any. */
public Set<Person> getRegistrants() {

return new HashSet<Person> (this.registrants);
}

/* Update methods */

public void register(Person person) {

this.registrants.add(person);
}
}
Hope that helps!

How to use Hibernate @Any annotations?

For example let's assume three different applications which manage a media library - the first application manages books borrowing, the second one DVDs, and the third VHSs. The applications have nothing in common. Now we want to develop a new application that manages all three media types and reuses the exiting Book, DVD, and VHS entities. Since Book, DVD, and VHS classes came from different applications they don't have any ancestor entity - the common ancestor is java.lang.Object. Still we would like to have one Borrow entity which can refer to any of the possible media type.
To solve this type of references we can use the any mapping. this mapping always includes more than one column: one column includes the type of the entity the current mapped property refers to and the other includes the identity of the entity, for example if we refer to a book it the first column will include a marker for the Book entity type and the second one will include the id of the specific book.
@Entity
@Table(name = "BORROW")
public class Borrow{

@Id
@GeneratedValue
private Long id;

@Any(metaColumn = @Column(name = "ITEM_TYPE"))
@AnyMetaDef(idType = "long", metaType = "string",
metaValues = {
@MetaValue(targetEntity = Book.class, value = "B"),
@MetaValue(targetEntity = VHS.class, value = "V"),
@MetaValue(targetEntity = DVD.class, value = "D")
})
@JoinColumn(name="ITEM_ID")
private Object item;

.......
public Object getItem() {
return item;
}

public void setItem(Object item) {
this.item = item;
}

}

Tuesday, September 15, 2009

what is java memory leakage?

In java all the object are freed automatically by Garbage Collector when object are not in use. but some situation Garbage Collector unable free an object. because when an object reference is stored in anther object Garbage Collector can't free that object.

example:

Vector store = new Vector();
String notGarbageCollectedObject =new String("StringObject");
store.add(notGarbageCollecteObject);

until you will remove ( store.remove(notGarbageCollectedObject )) the String object reference (notGarbageCollectedObject ) from vector Garbage Collector not deallocates that object. this causes memory leakage.

There are three main behaviors in java application when there is a memory leakage.

  1. If your application is leaking memory overtime, eventually you are going to get

java.lang.OutOfMemoryError exception.

  1. Application heap usage will grow continuously( not application size)

  2. Application will terminate automatically.


RSS value is different to heap space.

Java heap is the heap size allocated to JVM applications which takes care of the new objects being created. If the objects being created exceed the heap size, it will throw an error saying memoryOutofBound. Default heap size is 63mb. It can be modified using command -Xms32m -Xmx512m (minimum 32mb maximum 512mb).


Java uses shared libraries, thread space and other resources to execute. RSS is the amount of resident memory which can change without the application using more or less memory (it how much has been put into physical memory).


find heap size using following java API.

Runtime runtime = Runtime.getRuntime();

long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();

System.out.println("allocated memory: " +( allocatedMemory / 1024)/1024+"MB"); System.out.println("max memory: " + (maxMemory /1024)/1024+"MB"); System.out.println("total free memory: " + ((freeMemory + (maxMemory - allocatedMemory)) / 1024)/1024+"MB");

Output:

free memory: 39MB
allocated memory: 81MB
max memory: 508MB
total free memory: 466MB .



how to find java memory leakage?

by using memory profiler you can find memory leakage

links for memory profiler

JMP: (Java Memory Profiler) free memory profiler from Khelekore http://www.khelekore.org/jmp/

JProfiler
http://www.ej-technologies.com/products/jprofiler/overview.html

YourKit
http://www.yourkit.com/

HpJMeter
http://h20392.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=HPUXJAVAHOME

java 1.6 it self has tool find memory usage .

Getting PermGen information

The permanent generation is the area of heap that holds all the reflective data of the virtual machine
itself, such as class and method objects.
Configuring the size of the permanent generation can be important for applications that dynamically
generate and load a very large number of classes. If an application loads “too many” classes then it is possible it will abort with an OutOfMemoryError.
The specific error will look like :
“Exception in thread XXXX java.lang.OutOfMemoryError: PermGen space”

In 1 terminal start an application.
I am just using the jfc Notepad application here, since it is pretty passive and doesn't interfere with the screen while I am trying to write this.

bash-3.00$ ./java -jar ../demo/jfc/Notepad/Notepad.jar

Get the pid in this case 2239
bash-3.00$ ./jps
3131 Jps
2239 Notepad.jar
22305
10792 Main

Now in another terminal try running this

bash-3.00$ ./jmap -permstat 2239
Attaching to process ID 2239, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 14.0-b10
finding class loader instances ..Finding object size using Printezis bits and skipping over...
Finding object size using Printezis bits and skipping over...
Finding object size using Printezis bits and skipping over...
done.
computing per loader stat ..done.
please wait.. computing liveness.....done.

class_loader classes bytes parent_loader alive? type




1596 7131080 null live
0xe6e91088 1 1152 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe65142c8 6 17968 0xe6424958 dead sun/reflect/misc/MethodUtil@0xb7d67248
0xe6426528 0 0 0xe6424958 live java/util/ResourceBundle$RBClassLoader@0x b796ec78
0xe6e8a128 1 1152 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe656d8a0 1 1184 0xe65142c8 dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe693cd20 1 1792 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe641e710 1 8080 null live sun/misc/Launcher$ExtClassLoader@0xb79214 78
0xe6e8ee40 1 1152 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe6555668 1 1752 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe6e8cd78 1 1768 null dead sun/reflect/DelegatingClassLoader@0xb7847 8d0
0xe6424958 87 810144 0xe641e710 live sun/misc/Launcher$AppClassLoader@0xb7964f d0



total = 12 1697 7977224 N/A alive=4, dead=8 N/A


Typically, we get the output in this form.
For each class loader object, the following details are printed:
1. The address of the class loader object – at the snapshot when the utility was run.
2. The number of classes loaded (defined by this loader with the method(java.lang.ClassLoader.defineClass).
3. The approximate number of bytes consumed by meta-data for all classes loaded by this class loader.
4. The address of the parent class loader (if any).
5. A “live” or “dead” indication – indicates whether the loader object will be garbage collected in the future.
6. The class name of this class loader.

Monday, September 14, 2009

Classic Microsoft commercials and videos

Everybody is now familiar with the Bill Gates and Jerry Seinfeld Vista commercials as well as the I’m a PC commercials that Microsoft began using as retaliation to Apple’s Hello, I’m a Mac series of commercials. However, Microsoft’s advertising campaigns have a long history. In this blog post, I’ll take a look back at some of Microsoft’s classic Windows commercials. I’ll also toss in a host of other Microsoft-related videos for your entertainment pleasure.



Steve Ballmer sells Windows 1.0


In 1986, Steve Ballmer, in true Billy Mays form, pitched Windows 1.0 in a classic infomercial format. Of course, this spoof was created for internal use at Microsoft and never really aired on TV; however, it is incredibly funny.



Windows 95 - Start Me Up


The launch of Windows 95 was a spectacular, worldwide extravaganza that featured all sorts of promotional campaigns and events. But the coup d’état was getting the Rolling Stones to allow Microsoft to license the hit song “Start Me Up” as the Windows 95 theme song in order to highlight the new Start button. This song was edited down a bit and featured in this advertisement.



Windows 98 - Where do you want to go today?


While the release of Windows 98 wasn’t as an amazing event as the one for Windows 95, Microsoft did have a very interesting commercial that featured a fast-moving collage of images and video highlighting Windows 98 and a host of other Microsoft products.



Windows ME - So many possibilities



While as a whole, Windows ME was a flop, the operating system did introduce a ton of new features that were eventually perfected in Windows XP. Even so, the promotional video for Windows ME was actually really cool!



Windows 2000 - It’s a window


This one is really out there, on the farm that is…. In this European commercial for Windows 2000, a farmer in a suit crashes his tractor into the side of a barn.



Windows XP - You can fly


In this commercial for Windows XP, the new operating system allows people to literally fly while using the speedy new version of Windows.



Windows Vista - Wow!


This commercial extolled the virtues of Windows Vista with an interesting collage of people’s one-word reaction to witnessing amazing things, including seeing the new operating system for the first time.




Bill Gates praising Apple computers


In the early 80s, a young Bill Gates, obviously intent on positioning Microsoft in the right spot just in case the Apple Macintosh beat out the IBM PC for the dominant spot in the emerging personal computer market, praises the Apple Macintosh as a machine that really captures people’s imagination.



Bill Gates in Doom


On October 30, 1995, at Microsoft’s Judgment Day trade show, the company was promoting Windows 95 with the new DirectX API as the ultimate gaming platform. In order to promote the Windows 95 gaming platform, Microsoft created a promotional video that featured Bill Gates inside the game Doom, which at the time was extremely innovative and very popular. In addition to blowing away alien monsters, a shotgun-toting Gates, complete with trench coat, discussed the problems with DOS gaming and highlighted the capabilities that the new DirectX API was bringing to gaming in Windows.



As a side note, Microsoft did continue to focus on the DirectX API as a gaming platform and eventually created a gaming console that was initially called the DirectX Box and, later, simply the Xbox.


Windows 98’s public Blue Screen of Death


In this classic video, Bill Gates and Chris Capossela, a Microsoft presenter at the 1998 Comdex show, are demonstrating Windows 98’s ease of use and enhanced support for Plug and Play, when all of a sudden the system encountered a Blue Screen Of Death, leaving both men speechless for several moments before the event becomes humorous. (Editor’s note: I was there, and it was very funny.)




Bill Gates helps Napoleon Dynamite


In 2005, at the Professional Developers Conference, Bill Gates began his keynote speech by introducing a video he described as being about a recent recruiting trip. It turns out to be a spoof in which he dreams about helping Napoleon Dynamite upgrade computers with Office 2003. Bill and Jon Heder, the actor who plays Napoleon Dynamite, are actually quite a good duo in this little video.



Bill Gates’s last day


At the 2008 Consumer Electronics Show, in his keynote speech, Bill Gates formally announced his retirement from day-to-day duties at Microsoft. To commemorate the occasion, Microsoft put together a star-studded comedy video making fun of what would Bill do in retirement.











Monday, September 7, 2009

Testing SimpleFormController with Spring MVC

In this article, I will show how one can develop “test-first” using Spring-webMVC and spring-test. I therefore assume you know the basics of spring-mvc. My example will be around some Person management system. First, assume we have a Person object :


  1. public class Person {
  2. private Long id;
  3. private String firstName;
  4. private String lastName;
  5. public Person(String firstName, String lastName) {
  6. this.firstName = firstName;
  7. this.lastName = lastName;
  8. }
  9. public Long getId() {
  10. return id;
  11. }
  12. private void setId(Long id) {
  13. this.id = id;
  14. }
  15. public String getFirstName() {
  16. return firstName;
  17. }
  18. public void setFirstName(String firstName) {
  19. this.firstName = firstName;
  20. }
  21. public String getLastName() {
  22. return lastName;
  23. }
  24. public void setLastName(String lastName) {
  25. this.lastName = lastName;
  26. }
  27. }

And a service interface allowing basic CRUD operations for a person :


  1. public interface PersonService {
  2. public List read(Person p);
  3. public void save(Person p);
  4. public void delete(Person p);
  5. }

We want a web interface that allow the user to save a new Person or to modify an existing person. For this I’ll use a SimpleFormController. It will be responsible for presenting the form, calling the person’s service save(Person), and forwarding the user to a success page (when the person has correctly been saved).


This controller will be configured in a context file like this :


  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beans
  4. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  5. <bean name="/editPerson" class="myProject.web.EditPersonController">
  6. <property name="commandClass" value="myProject.Person"/>
  7. <property name="formView" value="personForm"/>
  8. <property name="successView" value="personSaved"/>
  9. </bean>
  10. </beans>

To have our test being able to load a context, we’ll use the jUnit’s @RunWith annotation, and to make our test load our specific context we’ll use the Spring’s @ContextConfiguration annotation. For more details on Spring’s test API, see the chapter 13 of the Spring framework documentation.


  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations={"/myProject/EditPersonControllerTest-context.xml"})
  3. public class EditPersonControllerTest {
  4. <strong>@Autowired</strong>
  5. <strong>EditPersonController controller;</strong>
  6. /**
  7. * Tests the creation of a new Person.
  8. **/
  9. @Test
  10. public void testCreate() {
  11. }
  12. }

The @Autowired annotation will do “by-type” bean injection. This means that since our context contains a single bean of type myProject.web.EditPersonController, that bean (the one we named “/editPerson”) will be injected in field “controller” at runtime, before the test methods are called. But for now, the test just doesn’t compile because we haven’t created the EditPersonController class. Let’s create this controller :


  1. import org.springframework.web.servlet.mvc.SimpleFormController;
  2. public class EditPersonController extends SimpleFormController {
  3. }

It does nothing for the moment, except allowing the test to compile.

To test this newly created controller, we need a HttpServletRequest and a HttpServletResponse object. These objects will be passed to the controller’s handleRequest method. Our test is, of course, not using a servlet engine that is able to create these objects for us, so we have to mock them. Here comes the use of the Spring’s MockHttpServletRequest and MockHttpServletResponse classes. With these objects, we can easily simulate a HTTP request that will be forwarded to our controller. We can then verify if a “GET” HTTP call will make our controller send the person form :


  1. /**
  2. * Tests the creation of a new Person.
  3. **/
  4. @Test
  5. public void testCreate() {
  6. MockHttpServletRequest request = new MockHttpServletRequest();
  7. request.setMethod("GET");
  8. ModelAndView mv = controller.handleRequest(request, new MockHttpServletResponse());
  9. assertEquals(controller.getFormView(), mv.getViewName());
  10. }

The ModelAndView object is used to determine which view the controller chose to send to the user.

Instead of doing :

assertEquals(controller.getFormView(), mv.getViewName());

We could have done :

import static org.springframework.test.web.ModelAndViewAssert.*;

[...]


assertViewName(mv, controller.getFormView());

[...]


Now the user is provided a form with two input fields. One for the “firstname” and one for the “lastname”. He fills those fields and submit the form. The controller is then called with the “fistname” and “lastname” posted by the user. It must normally save the person and return the “successView” which we named “personSaved” (see the XML context defined previously). Let’s now add this behavior to our test :


  1. import static org.springframework.test.web.ModelAndViewAssert.*;
  2. ...
  3. /**
  4. * Tests the creation of a new Person.
  5. **/
  6. @Test
  7. public void testCreate() {
  8. MockHttpServletRequest request = new MockHttpServletRequest();
  9. request.setMethod("GET");
  10. ModelAndView mv = controller.handleRequest(request, new MockHttpServletResponse());
  11. assertEquals(controller.getFormView(), mv.getViewName());
  12. request = new MockHttpServletRequest();
  13. request.setMethod("POST");
  14. request.setParameter("firstName", "Richard");
  15. request.setParameter("lastname", "Barabé");
  16. mv = controller.handleRequest(request, new MockHttpServletResponse());
  17. assertViewName(mv, controller.getSuccessView());
  18. }

So far we’ve tested that while creating a new Person, the user first asks the Person form (with an HTTP GET call), then submits that form (with an HTTP POST call that details person’s information) and is redirected to a success page when finished. We can say we tested the navigation part of the “create new Person” use case.


But, did the controller really saved the Person ? In other words : Did the controller called the PersonService’s save(Person p) method ? To test this, I will use EasyMock to mock a PersonService, tell EasyMock I want this PersonService’s save(Person p) method to be called once with the correct person, and then I will pass that PersonService mock to the controller. Once done, my test will know if the controller really called the PersonService adequately. Here is the code of the test :


  1. import static org.easymock.EasyMock.*;
  2. ...
  3. /**
  4. * Tests the creation of a new Person.
  5. **/
  6. @Test
  7. public void testCreate() {
  8. MockHttpServletRequest request = new MockHttpServletRequest();
  9. request.setMethod("GET");
  10. ModelAndView mv = controller.handleRequest(request, new MockHttpServletResponse());
  11. assertEquals("personForm", mv.getViewName());
  12. request = new MockHttpServletRequest();
  13. request.setMethod("POST");
  14. request.setParameter("firstName", "Richard");
  15. request.setParameter("lastname", "Barabé");
  16. // Create the service's imitation
  17. PersonService serviceMock = createMock(PersonService.class);
  18. controller.setPersonService(serviceMock);
  19. // The save method should be called with "Richard Barabé"
  20. serviceMock.save(new Person("Richard", "Barabé"));
  21. // The save method should be called only once
  22. expectLastCall().once();
  23. // Finished telling easymock how my service should be used.
  24. replay(serviceMock);
  25. mv = controller.handleRequest(request, new MockHttpServletResponse());
  26. assertViewName(mv, "personSaved");
  27. // Verify that the service have been used as we expect
  28. // (method save called once with "Richard Barabé")
  29. verify(serviceMock);
  30. }

For this to compile, I need to add a PersonService field and its getter/setter in the controller :


  1. import org.springframework.web.servlet.mvc.SimpleFormController;
  2. import myProject.PersonService;
  3. public class EditPersonController extends SimpleFormController {
  4. private PersonService service;
  5. public void setPersonService(PersonService service) {
  6. this.service = service
  7. }
  8. public PersonService getPersonService() {
  9. return this.service;
  10. }
  11. }

Now the test asserts the service has been called correctly. As we run it, we can see it fails with the following message :


java.lang.AssertionError:
Expectation failure on verify:
save(myProject.Person@1f2cea2): expected: 1, actual: 0
at org.easymock.internal.MocksControl.verify(MocksControl.java:82)
at org.easymock.EasyMock.verify(EasyMock.java:1410)
...

This just means our controller didn’t call the service’s save method as expected. Let’s make our controller do it’s job by adding the expected call :


  1. import org.springframework.web.servlet.mvc.SimpleFormController;
  2. import myProject.PersonService;
  3. public class EditPersonController extends SimpleFormController {
  4. private PersonService service;
  5. protected doSubmitAction(Object o) {
  6. this.service.save((Person) o)
  7. }
  8. public void setPersonService(PersonService service) {
  9. this.service = service
  10. }
  11. public PersonService getPersonService() {
  12. return this.service;
  13. }
  14. }

Running the test now should succeed. But, unfortunately, the bar is red again. For time consideration, I’ll leave aside the investigation and go right to the solution : we did not override the equals and hashcode methods of the Person class. Our controller that received the form submission did create a new Person, setting its first and last name. It then passed this new object to the doFormSubmitAction(Object) that called our mock passing the new person. But we told EasyMock we expected our service to be called with another Person object. Default implementation of the equals method in object makes the following statement false :

(new Person(”Richard”,”Barabé”)).equals(new Person(”Richard”,”Barabé”))

So let’s implement those hashCode and equals methods (I use Eclipse to generate this “boiler plate” code) :


  1. public class Person {
  2. private Long id;
  3. private String firstName;
  4. private String lastName;
  5. public Person(String firstName, String lastName) {
  6. this.firstName = firstName;
  7. this.lastName = lastName;
  8. }
  9. public Long getId() {
  10. return id;
  11. }
  12. private void setId(Long id) {
  13. this.id = id;
  14. }
  15. public String getFirstName() {
  16. return firstName;
  17. }
  18. public void setFirstName(String firstName) {
  19. this.firstName = firstName;
  20. }
  21. public String getLastName() {
  22. return lastName;
  23. }
  24. public void setLastName(String lastName) {
  25. this.lastName = lastName;
  26. }
  27. @Override
  28. public int hashCode() {
  29. final int prime = 31;
  30. int result = 1;
  31. result = prime * result
  32. + ((firstName == null) ? 0 : firstName.hashCode());
  33. result = prime * result
  34. + ((lastName == null) ? 0 : lastName.hashCode());
  35. return result;
  36. }
  37. @Override
  38. public boolean equals(Object obj) {
  39. if (this == obj)
  40. return true;
  41. if (obj == null)
  42. return false;
  43. if (getClass() != obj.getClass())
  44. return false;
  45. final Person other = (Person) obj;
  46. if (firstName == null) {
  47. if (other.firstName != null)
  48. return false;
  49. } else if (!firstName.equals(other.firstName))
  50. return false;
  51. if (lastName == null) {
  52. if (other.lastName != null)
  53. return false;
  54. } else if (!lastName.equals(other.lastName))
  55. return false;
  56. return true;
  57. }
  58. }

Now the code behaves correctly when we have two persons with the same fistName and lastName. And that green bar is back again.


There we are, we have successfully developped and tested our controller. This article is to be continued, and next time we’ll go over the Validator and View implementation.