Posts Tagged ‘Eclipse’

What is GWT?

  • Google Web Toolkit (GWT) is a development toolkit to create RICH Internet Application(RIA).
  • GWT provides developers option to write client side application in JAVA.
  • GWT compiles the code written in JAVA to JavaScript code.
  • Application written in GWT is cross-browser compliant. GWT automatically generates javascript code suitable for each browser.
  • GWT is open source, completely free, and used by thousands of developers around the world. It is licensed under the Apache License version 2.0.

Overall, GWT is a framework to build large scale and high performance web appliation while keeping them as easy-to-maintain.

Why to use GWT?

  • Being Java based, you can use JAVA IDEs like Eclipse to develop GWT applcation. Developers can use code auto-complete/refactoring/navigation/project management and all features of IDEs.
  • GWT provides full debugging capability. Developers can debug the client side application just as an Java Application.
  • GWT provides easy integration with Junit and Maven.
  • Again being Java based, GWT has a low learning curve for Java Developers.
  • GWT generates optimized javascript code, produces browser’s specific javascript code by self.
  • GWT provides Widgets library provides most of tasks required in an application.
  • GWT is extensible and custom widget can be created to cater to application needs.

On top of everything, GWT applications can run on all major browsers and smart phones including Android and iOS based phones/tablets.

Disadvantages of GWT

Though GWT comes with lots of plus points but same time we should consider the following points:

  • Not indexable : Web pages generated by GWT would not be indexed by search engines because these applications are generated dynamically.
  • Not degradable: If your application user disables Javascript then user will just see the basic page and nothing more.
  • Not designer’s friendly: GWT is not suitable for web designers who prefer using plain HTML with placeholders for inserting dynamic content at later point in time.

The GWT Components

The GWT framework can be divided into following three major parts:

  • GWT Java to JavaScript compiler : This is the most important part of GWT which makes it a powerful tool for building RIAs. The GWT compiler is used to translate all the application code written in Java into JavaScript.
  • JRE Emulation library : Google Web Toolkit includes a library that emulates a subset of the Java runtime library. The list includes java.lang, java.lang.annotation, java.math, java.io, java.sql, java.util and java.util.logging
  • GWT UI building library : This part of GWT consists of many subparts which includes the actual UI components, RPC support, History management, and much more.

GWT also provides a GWT Hosted Web Browser which lets you run and execute your GWT applications in hosted mode, where your code runs as Java in the Java Virtual Machine without compiling to JavaScript.

 

JavaServer Faces(JSF) 2. 0, is usually an MVC web framework which usually concentrate on simplifies constructing User interfaces (comes with 100+ ready USER INTERFACE tags) for Java web app as well as create reusable USER INTERFACE component simple to put into practice. Not like JSF 1.x back button, every little thing is expressed inside faces-config. xml, together with JSF 2. 0, you might be allowed to make use of annotation to be able to state navigating, manage bean or maybe CDI bean, which can make ones development much easier as well as faster.

In this particular short tutorial, it offers a superior quite a few comprehensive good examples as well as explanations in applying JavaServer Faces(JSF) 2. 0 framework.

Some quick start examples for JSF 2.0

Quick Start JSF 2.0

Managed Bean

 

 

العربية: Android logo

A layout defines the visual structure for a user interface, such as the UI for an activity or app widget. You can declare a layout in two ways:

  • Declare UI elements in XML. Android provides a straightforward XML vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts.
  • Instantiate layout elements at runtime. Your application can create View and ViewGroup objects (and manipulate their properties) programmatically.

The Android framework gives you the flexibility to use either or both of these methods for declaring and managing your application’s UI. For example, you could declare your application’s default layouts in XML, including the screen elements that will appear in them and their properties. You could then add code in your application that would modify the state of the screen objects, including those declared in XML, at run time.

  • The ADT Plugin for Eclipse offers a layout preview of your XML — with the XML file opened, select the Layout tab.
  • You should also try the Hierarchy Viewer tool, for debugging layouts — it reveals layout property values, draws wireframes with padding/margin indicators, and full rendered views while you debug on the emulator or device.
  • The layoutopt tool lets you quickly analyze your layouts and hierarchies for inefficiencies or other problems.

The advantage to declaring your UI in XML is that it enables you to better separate the presentation of your application from the code that controls its behavior. Your UI descriptions are external to your application code, which means that you can modify or adapt it without having to modify your source code and recompile. For example, you can create XML layouts for different screen orientations, different device screen sizes, and different languages. Additionally, declaring the layout in XML makes it easier to visualize the structure of your UI, so it’s easier to debug problems. As such, this document focuses on teaching you how to declare your layout in XML. If you’re interested in instantiating View objects at runtime, refer to the ViewGroup and View class references.

In general, the XML vocabulary for declaring UI elements closely follows the structure and naming of the classes and methods, where element names correspond to class names and attribute names correspond to methods. In fact, the correspondence is often so direct that you can guess what XML attribute corresponds to a class method, or guess what class corresponds to a given xml element. However, note that not all vocabulary is identical. In some cases, there are slight naming differences. For example, the EditText element has a text attribute that corresponds to EditText.setText().

Tip: Learn more about different layout types in Common Layout Objects. There are also a collection of tutorials on building various layouts in the Hello Views tutorial guide.

Write the XML


Using Android’s XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create web pages in HTML — with a series of nested elements.

Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you’ve defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. For example, here’s an XML layout that uses a vertical LinearLayout to hold a TextView and a Button:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent" 
              android:orientation="vertical" >
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="Hello, I am a TextView" />
    <Button android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, I am a Button" />
</LinearLayout>

After you’ve declared your layout in XML, save the file with the .xml extension, in your Android project’s res/layout/ directory, so it will properly compile.

More information about the syntax for a layout XML file is available in the Layout Resources document.

Load the XML Resource


When you compile your application, each XML layout file is compiled into a View resource. You should load the layout resource from your application code, in your Activity.onCreate() callback implementation. Do so by calling setContentView(), passing it the reference to your layout resource in the form of: R.layout.layout_file_name For example, if your XML layout is saved as main_layout.xml, you would load it for your Activity like so:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

The onCreate() callback method in your Activity is called by the Android framework when your Activity is launched (see the discussion about lifecycles, in the Activities document).

Attributes


Every View and ViewGroup object supports their own variety of XML attributes. Some attributes are specific to a View object (for example, TextView supports the textSize attribute), but these attributes are also inherited by any View objects that may extend this class. Some are common to all View objects, because they are inherited from the root View class (like the id attribute). And, other attributes are considered “layout parameters,” which are attributes that describe certain layout orientations of the View object, as defined by that object’s parent ViewGroup object.

ID

Any View object may have an integer ID associated with it, to uniquely identify the View within the tree. When the application is compiled, this ID is referenced as an integer, but the ID is typically assigned in the layout XML file as a string, in the id attribute. This is an XML attribute common to all View objects (defined by the View class) and you will use it very often. The syntax for an ID, inside an XML tag is:

android:id="@+id/my_button"

The at-symbol (@) at the beginning of the string indicates that the XML parser should parse and expand the rest of the ID string and identify it as an ID resource. The plus-symbol (+) means that this is a new resource name that must be created and added to our resources (in the R.java file). There are a number of other ID resources that are offered by the Android framework. When referencing an Android resource ID, you do not need the plus-symbol, but must add the android package namespace, like so:

android:id="@android:id/empty"

With the android package namespace in place, we’re now referencing an ID from the android.R resources class, rather than the local resources class.

In order to create views and reference them from the application, a common pattern is to:

  1. Define a view/widget in the layout file and assign it a unique ID:
    <Button android:id="@+id/my_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/my_button_text"/>
  2. Then create an instance of the view object and capture it from the layout (typically in the onCreate() method):
    Button myButton = (Button) findViewById(R.id.my_button);

Defining IDs for view objects is important when creating a RelativeLayout. In a relative layout, sibling views can define their layout relative to another sibling view, which is referenced by the unique ID.

An ID need not be unique throughout the entire tree, but it should be unique within the part of the tree you are searching (which may often be the entire tree, so it’s best to be completely unique when possible).

Layout Parameters

XML layout attributes named layout_something define layout parameters for the View that are appropriate for the ViewGroup in which it resides.

Every ViewGroup class implements a nested class that extends ViewGroup.LayoutParams. This subclass contains property types that define the size and position for each child view, as appropriate for the view group. As you can see in figure 1, the parent view group defines layout parameters for each child view (including the child view group).

Figure 1. Visualization of a view hierarchy with layout parameters associated with each view.

Note that every LayoutParams subclass has its own syntax for setting values. Each child element must define LayoutParams that are appropriate for its parent, though it may also define different LayoutParams for its own children.

All view groups include a width and height (layout_width and layout_height), and each view is required to define them. Many LayoutParams also include optional margins and borders.

 

You can specify width and height with exact measurements, though you probably won’t want to do this often. More often, you will use one of these constants to set the width or height:

  • wrap_content tells your view to size itself to the dimensions required by its content
  • fill_parent (renamed match_parent in API Level 8) tells your view to become as big as its parent view group will allow.

In general, specifying a layout width and height using absolute units such as pixels is not recommended. Instead, using relative measurements such as density-independent pixel units (dp), wrap_content, or fill_parent, is a better approach, because it helps ensure that your application will display properly across a variety of device screen sizes. The accepted measurement types are defined in the Available Resources document.

Layout Position


The geometry of a view is that of a rectangle. A view has a location, expressed as a pair of left and top coordinates, and two dimensions, expressed as a width and a height. The unit for location and dimensions is the pixel.

It is possible to retrieve the location of a view by invoking the methods getLeft() and getTop(). The former returns the left, or X, coordinate of the rectangle representing the view. The latter returns the top, or Y, coordinate of the rectangle representing the view. These methods both return the location of the view relative to its parent. For instance, when getLeft() returns 20, that means the view is located 20 pixels to the right of the left edge of its direct parent.

In addition, several convenience methods are offered to avoid unnecessary computations, namely getRight() and getBottom(). These methods return the coordinates of the right and bottom edges of the rectangle representing the view. For instance, calling getRight() is similar to the following computation: getLeft() + getWidth().

Size, Padding and Margins


The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values.

The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent. The measured dimensions can be obtained by calling getMeasuredWidth() and getMeasuredHeight().

The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by calling getWidth() and getHeight().

To measure its dimensions, a view takes into account its padding. The padding is expressed in pixels for the left, top, right and bottom parts of the view. Padding can be used to offset the content of the view by a specific amount of pixels. For instance, a left padding of 2 will push the view’s content by 2 pixels to the right of the left edge. Padding can be set using the setPadding(int, int, int, int) method and queried by calling getPaddingLeft(), getPaddingTop(), getPaddingRight() and getPaddingBottom().

Even though a view can define a padding, it does not provide any support for margins. However, view groups provide such a support. Refer to ViewGroup and ViewGroup.MarginLayoutParams for further information.

For more information about dimensions, see Dimension Values.

Common Layouts


Each subclass of the ViewGroup class provides a unique way to display the views you nest within it. Below are some of the more common layout types that are built into the Android platform.

Note: Although you can nest one or more layouts within another layout to acheive your UI design, you should strive to keep your layout hierarchy as shallow as possible. Your layout draws faster if it has fewer nested layouts (a wide view hierarchy is better than a deep view hierarchy).

Linear Layout

A layout that organizes its children into a single horizontal or vertical row. It creates a scrollbar if the length of the window exceeds the length of the screen.

Relative Layout

Enables you to specify the location of child objects relative to each other (child A to the left of child B) or to the parent (aligned to the top of the parent).

Web View

Displays web pages.

Building Layouts with an Adapter


When the content for your layout is dynamic or not pre-determined, you can use a layout that subclasses AdapterView to populate the layout with views at runtime. A subclass of the AdapterView class uses an Adapter to bind data to its layout. The Adapter behaves as a middle-man between the data source and the AdapterView layout—the Adapter retreives the data (from a source such as an array or a database query) and converts each entry into a view that can be added into the AdapterView layout.

Common layouts backed by an adapter include:

List View

Displays a scrolling single column list.

Grid View

Displays a scrolling grid of columns and rows.

Filling an adapter view with data

You can populate an AdapterView such as ListView or GridView by binding the AdapterView instance to an Adapter, which retrieves data from an external source and creates a View that represents each data entry.

Android provides several subclasses of Adapter that are useful for retrieving different kinds of data and building views for an AdapterView. The two most common adapters are:

ArrayAdapter
Use this adapter when your data source is an array. By default, ArrayAdapter creates a view for each array item by calling toString() on each item and placing the contents in a TextView.For example, if you have an array of strings you want to display in a ListView, initialize a new ArrayAdapter using a constructor to specify the layout for each string and the string array:

ArrayAdapter adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, myStringArray);

The arguments for this constructor are:

  • Your app Context
  • The layout that contains a TextView for each string in the array
  • The string array

Then simply call setAdapter() on your ListView:

ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

To customize the appearance of each item you can override the toString() method for the objects in your array. Or, to create a view for each item that’s something other than a TextView (for example, if you want an ImageView for each array item), extend the ArrayAdapter class and override getView() to return the type of view you want for each item.

SimpleCursorAdapter
Use this adapter when your data comes from a Cursor. When using SimpleCursorAdapter, you must specify a layout to use for each row in the Cursor and which columns in the Cursor should be inserted into which views of the layout. For example, if you want to create a list of people’s names and phone numbers, you can perform a query that returns a Cursor containing a row for each person and columns for the names and numbers. You then create a string array specifying which columns from the Cursor you want in the layout for each result and an integer array specifying the corresponding views that each column should be placed:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, 
                        ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

When you instantiate the SimpleCursorAdapter, pass the layout to use for each result, the Cursor containing the results, and these two arrays:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, 
        R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView.setAdapter(adapter);

The SimpleCursorAdapter then creates a view for each row in the Cursor using the provided layout by inserting each fromColumns item into the corresponding toViews view.

.

If, during the course of your application’s life, you change the underlying data that is read by your adapter, you should call notifyDataSetChanged(). This will notify the attached view that the data has been changed and it should refresh itself.

Handling click events

You can respond to click events on each item in an AdapterView by implementing the AdapterView.OnItemClickListener interface. For example:

// Create a message handling object as an anonymous class.
private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
        // Do something in response to the click
    }
};

listView.setOnItemClickListener(mMessageClickedHandler);
Enhanced by Zemanta

Working with BLOB / CLOB data types in database is sometime a trivial taspring-hibernate-blob-mysql-tutorialsk. I found particularly when working with Hibernate 3 to store and retrieve BLOB objects we need certain things to be taken care of. Let us see a tutorial where we will using Spring 3 MVC and Hibernate 3 to store and retrieve blob objects in database.

Our Goal

Our goal is to create a Document Manager application in Spring 3 MVC and Hibernate. Following is the functionality.

  1. A form is displayed on main page with fields such as Document name, description and browse button to select document from file system.
  2. User can select any document from local drive and upload the same using Save document functionality.
  3. All the documents saved are added in a database table.
  4. List of all the documents present in database is displayed on the main page.
  5. Each document in the list have two buttons: Delete and Download.
  6. Any document can be downloaded by clicking on download button.
  7. Any document can be deleted by clicking on delete button.

Here is the final screen shot of Document manager application.
document-manager-hibernate-spring-blob

Step 1: Create Database Table

For Document Manager application, we will use MySQL database. Create a table documents in MySQL database docdb. This is very preliminary example and thus we have minimum columns to represent a document. Feel free to extend this example and create a more complex application.

CREATE DATABASE `docdb`;

USE `docdb`;

CREATE TABLE `documents` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  `description` text NOT NULL,
  `filename` varchar(200) NOT NULL,
  `content` mediumblob NOT NULL, /* for ORACLE enter BLOB*/
  `content_type` varchar(255) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

Step 2: Create Maven Project in Eclipse

The document manager application will use Maven for build and dependency management. For this we will use the Maven Dynamic Web Project in Eclipse as the base architecture of our application.

Or directly download the below source code:
Maven Dynamic Web Project (6.7 KB)

Once you have imported / created the Maven web project in Eclipse. Copy following content into Maven’s pom.xml file. These are the dependencies we will use in our Document manager application.
File: /pom.xml

<!--?xml version="1.0" encoding="UTF-8"?>
  4.0.0
  MavenWeb
  MavenWeb
  war
  0.0.1-SNAPSHOT

        maven-compiler-plugin

          1.5
          1.5

        maven-war-plugin
        2.0

      javax.servlet
      servlet-api
      2.5

      org.springframework
      spring-beans
      ${org.springframework.version}

      org.springframework
      spring-jdbc
      ${org.springframework.version}

      org.springframework
      spring-web
      ${org.springframework.version}

      org.springframework
      spring-webmvc
      ${org.springframework.version}

      org.springframework
      spring-orm
      ${org.springframework.version}

      taglibs
      standard
      1.1.2

      javax.servlet
      jstl
      1.1.2

      org.hibernate
      hibernate-entitymanager
      3.3.2.ga

      mysql
      mysql-connector-java
      5.1.10

      commons-dbcp
      commons-dbcp
      20030825.184428

      commons-pool
      commons-pool
      1.5.4

      commons-fileupload
      commons-fileupload
      1.2.1

      commons-io
      commons-io
      1.3

    3.0.2.RELEASE
    UTF-8

document-manager-project-structure
Unzip the source code to your hard drive and import the project in Eclipse. Once the project is imported in Eclipse, we will create package structure for Java source. First rename the project to DocumentManager and create following packages under src/main/java folder.

  1. net.viralpatel.docmanager.controller – This package will contain Spring Controller classes for Document Manager application.
  2. net.viralpatel.docmanager.model – This package will contain form object for Document manager application. Document model will be a simple POJO class with different attributes such as document name, description, filename etc.
  3. net.viralpatel.docmanager.dao – This is the DAO layer of Document manager application. It consists of DocumentDao class which will use Hibernate API to interact with database.
  4. The src/main/resources folder will have hibernate configuration file: hibernate.cfg.xml.
  5. The WEB-INF folder will have jsp/documents.jsp file to render document list and add form and jdbc.properties file containing database connection configuration. Also it contains spring-servlet.xml which will define all the Controller class and web.xml which contain spring configuration.

Entity class – The Hibernate model class

Let us start with the coding of Document manager application. First we will create a model object or hibernate POJO class to store document information. Also this class will be an Entity class and will be linked with DOCUMENTS table in database.

Create a java class Document.java under net.viralpatel.docmanager.model package and copy following code into it.
File: /src/main/java/net/viralpatel/docmanager/model/Document.java

package net.viralpatel.docmanager.model;

import java.sql.Blob;
import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;

@Entity
@Table(name="documents")
public class Document {

	@Id
	@GeneratedValue
	@Column(name="id")
	private Integer id;

	@Column(name="name")
	private String name;

	@Column(name="description")
	private String description;

	@Column(name="filename")
	private String filename;

	@Column(name="content")
	@Lob
	private Blob content;

	@Column(name="content_type")
	private String contentType;

	@Column(name="created")
	private Date created;

	//Getter and Setter methods
}

The first thing you’ll notice is that the import statements import from javax.persistence rather than a Hibernate or Spring package. Using Hibernate with Spring, the standard JPA annotations work just as well and that’s what I’m using here.

  • First we’ve annotated the class with @Entity which tells Hibernate that this class represents an object that we can persist.
  • The @Table(name = "documents") annotation tells Hibernate which table to map properties in this class to documents table. The first property in this class on line 20 is our object ID which will be unique for all events persisted. This is why we’ve annotated it with @Id.
  • The @GeneratedValue annotation says that this value will be determined by the datasource, not by the code.
  • The @Column(name = "filename") annotation is used to map this property to the FILENAME column in the DOCUMENTS table.

The Data Access (DAO) Layer

The DAO layer of Document Manager application consist of a class DocumentDAO. Ideal solution will be to create an interface (DocumentDAO) and its corresponding implementation class DocumentDAOImpl. But for sake of simplicity we will create just normal DAO class DocumentDAO.java.

File: src/main/java/net/viralpatel/docmanager/dao/DocumentDAO.java

package net.viralpatel.docmanager.dao;

import java.util.List;

import net.viralpatel.docmanager.model.Document;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class DocumentDAO {

	@Autowired
	private SessionFactory sessionFactory;

	@Transactional
	public void save(Document document) {
		Session session = sessionFactory.getCurrentSession();
		session.save(document);
	}

	@Transactional
	public List<Document> list() {
		Session session = sessionFactory.getCurrentSession();
		List<Document> documents = null;
		try {
			documents = (List<Document>)session.createQuery("from Document").list();

		} catch (HibernateException e) {
			e.printStackTrace();
		}
		return documents;
	}

	@Transactional
	public Document get(Integer id) {
		Session session = sessionFactory.getCurrentSession();
		return (Document)session.get(Document.class, id);
	}

	@Transactional
	public void remove(Integer id) {
		Session session = sessionFactory.getCurrentSession();

		Document document = (Document)session.get(Document.class, id);

		session.delete(document);
	}
}

Methods:

  • list() Method – This method gets the list of all documents stored in documents table and return a List of Document objects.
  • save() Method – This method is used to store a new document (including BLOB) into database.
  • get() Method – This method returns Document entry for a given ID from database. Used in download functionality to download a stored document from database.
  • remove() Method – This method is used to delete a document with specific ID from database.

Note that we have used two Spring annotations @Repository and @Autowired. Classes marked with annotations are candidates for auto-detection by Spring when using annotation-based configuration and classpath scanning. The @Component annotation is the main stereotype that indicates that an annotated class is a “component”.

The @Repository annotation is yet another stereotype that was introduced in Spring 2.0. This annotation is used to indicate that a class functions as a repository and needs to have exception translation applied transparently on it. The benefit of exception translation is that the service layer only has to deal with exceptions from Spring’s DataAccessException hierarchy, even when using plain JPA in the DAO classes.

Another annotation used in DocumentDAO is @Autowired. This is used to autowire the dependency of the DocumentDAO on the SessionFactory.

Also note that we have used @Transactional annotation on each method. Ideally the DAO layer is access from a Service layer and transaction management needs to be specified at Service layer. But again for sake of simplicity we will not include service layer in our example and directly call the DAO layer from Spring Controller. Again, feel free to change this implementation and add your own service layer in between.

For more information about A layered application with Services in Spring MVC and Hibernate read this tutorial.
Spring MVC Hibernate Maven example

Adding Spring MVC Support to Webapplication

Let us add Spring MVC support to our web application.
Update the web.xml file and add servlet mapping for org.springframework.web.servlet.DispatcherServlet. Also note that we have mapped url / with springServlet so all the request are handled by spring.

File: /src/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>DocumentManager</display-name>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>*.html</url-pattern>
	</servlet-mapping>
</web-app>

Once the web.xml is configured, let us add spring-servlet.xml and jdbc.properties files in /src/main/webapp/WEB-INF folder.

File: /src/main/webapp/WEB-INF/jdbc.properties

jdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/docdb
jdbc.username=root
jdbc.password=password

The jdbc.properties file contains database connection information such as database url, username, password, driver class. You may want to edit the driverclass and dialect to other DB if you are not using MySQL.

File: /src/main/webapp/WEB-INF/spring-servlet.xml

<?xml  version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:lang="http://www.springframework.org/schema/lang"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

	<context:annotation-config />
	<context:component-scan base-package="net.viralpatel.docmanager" />

	<bean id="jspViewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
		p:location="/WEB-INF/jdbc.properties" />

	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
		p:driverClassName="${jdbc.driverClassName}"
		p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
		p:password="${jdbc.password}" />

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>
		<property name="configurationClass">
			<value>org.hibernate.cfg.AnnotationConfiguration</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${jdbc.dialect}</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.connection.SetBigStringTryClob">true</prop>
				<prop key="hibernate.jdbc.batch_size">0</prop>
			</props>
		</property>
	</bean>
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

		<!-- one of the properties available; the maximum file size in bytes -->
		<property name="maxUploadSize" value="10000000" />
	</bean>
	<tx:annotation-driven />

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
</beans>

The spring-servlet.xml file contains different spring mappings such as transaction manager, hibernate session factory bean, data source etc.

  • jspViewResolver bean – This bean defined view resolver for spring mvc. For this bean we also set prefix as “/WEB-INF/jsp/” and suffix as “.jsp”. Thus spring automatically resolves the JSP from WEB-INF/jsp folder and assigned suffix .jsp to it.
  • propertyConfigurer bean – This bean is used to load database property file jdbc.properties. The database connection details are stored in this file which is used in hibernate connection settings.
  • dataSource bean – This is the java datasource used to connect to document manager database. We provide jdbc driver class, username, password etc in configuration.
  • sessionFactory bean – This is Hibernate configuration where we define different hibernate settings. hibernate.cfg.xml is set a config file which contains entity class mappings. Also note that in sessionFactory we have specified few hibernate properties such as hibernate.connection.SetBigStringTryClob and hibernate.jdbc.batch_size. These are used to configure BLOB / CLOB settings in hibernate.
  • multipartResolver bean – We use Spring MVCs CommonsMultipartResolver. This resolver will resolve multipart form data such as file uploads from the request and make available File object to spring controller. Note that we have specified property maxUploadSize with value 10000000. This is the maximum limit of filesize which can be uploaded in our example.
  • transactionManager bean – We use hibernate transaction manager to manage the transactions of our document manager application.

File: /src/main/resources/hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <mapping />
    </session-factory>

</hibernate-configuration>

The Controller – Spring MVC controller class

We are almost done with our application. Just add following Spring controller class DocumentController.java to net.viralpatel.docmanager.controller package.

File: /src/main/java/net/viralpatel/docmanager/controller/DocumentController.java

package net.viralpatel.docmanager.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import net.viralpatel.docmanager.dao.DocumentDAO;
import net.viralpatel.docmanager.model.Document;

import org.apache.commons.io.IOUtils;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class DocumentController {

	@Autowired
	private DocumentDAO documentDao;

	@RequestMapping("/index")
	public String index(Map<String, Object> map) {
		try {
			map.put("document", new Document());
			map.put("documentList", documentDao.list());
		}catch(Exception e) {
			e.printStackTrace();
		}

		return "documents";
	}

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public String save(
			@ModelAttribute("document") Document document,
			@RequestParam("file") MultipartFile file) {

		System.out.println("Name:" + document.getName());
		System.out.println("Desc:" + document.getDescription());
		System.out.println("File:" + file.getName());
		System.out.println("ContentType:" + file.getContentType());

		try {
			Blob blob = Hibernate.createBlob(file.getInputStream());

			document.setFilename(file.getOriginalFilename());
			document.setContent(blob);
			document.setContentType(file.getContentType());
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			documentDao.save(document);
		} catch(Exception e) {
			e.printStackTrace();
		}

		return "redirect:/index.html";
	}

	@RequestMapping("/download/{documentId}")
	public String download(@PathVariable("documentId")
			Integer documentId, HttpServletResponse response) {

		Document doc = documentDao.get(documentId);
		try {
			response.setHeader("Content-Disposition", "inline;filename="" +doc.getFilename()+ """);
			OutputStream out = response.getOutputStream();
			response.setContentType(doc.getContentType());
			IOUtils.copy(doc.getContent().getBinaryStream(), out);
			out.flush();
			out.close();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return null;
	}

	@RequestMapping("/remove/{documentId}")
	public String remove(@PathVariable("documentId")
			Integer documentId) {

		documentDao.remove(documentId);

		return "redirect:/index.html";
	}
}

The spring controller defines four methods to manipulate document manager application.

  • index method – This method uses list() method of DocumentDAO to fetch the list of all documents from database. Note that we have mapped request “/index” to this method. Thus Spring will automatically calls this method whenever it encounters this url in request.
  • save method – This method adds a new document to document list. The document details are fetched in Document object using @ModelAttribute annotation. Also note that the request “/save” is mapped with this method. The request method should also be POST. Once the document is added in document list, we redirect to /index.html page which in turn calls index() method to display document list to user. One more thing to note here is @RequestParam. We are mapping MultipartFile object using @RequestParam(“file”) annotation. Spring automatically detects “file” data from request and map it with MultipartFile object. This object is later converted to BLOB object and set in the Document content.

    Related: Forms in Spring MVC

  • download method – This method is used to download a selected testcase. Note that we are fetching the document content from database using DAO class and thn set the Data stream in Response. Also note that we are using response.setHeader() method to set "Content-Disposition". This will raise a Save As dialog box in browser whenever user tries to download a document.
  • remove method – This methods removes a document from the document list. Similar to save() this method also redirects user to /index.html page once the document is removed. One thing to note in this method is the way we have mapped request url using @RequestMapping annotation. The url “/remove/{documentId}” is mapped thus whenever user send a request /remove/12.html, the remove method will try to delete document with ID:12.

Finally add following JSP file to WEB-INF/jsp folder.
File: /src/main/webapp/WEB-INF/jsp/documents.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
	<title>Document Manager - viralpatel.net</title>
</head>
<body>

<h2>Document Manager</h2>

<h3>Add new document</h3>
<form:form method="post" action="save.html" commandName="document" enctype="multipart/form-data">
	<form:errors path="*" cssClass="error"/>
	<table>
	<tr>
		<td><form:label path="name">Name</form:label></td>
		<td><form:input path="name" /></td> 
	</tr>
	<tr>
		<td><form:label path="description">Description</form:label></td>
		<td><form:textarea path="description" /></td>
	</tr>
	<tr>
		<td><form:label path="content">Document</form:label></td>
		<td><input type="file" name="file" id="file"></input></td>
	</tr>
	<tr>
		<td colspan="2">
			<input type="submit" value="Add Document"/>
		</td>
	</tr>
</table>	
</form:form>

<br/>
<h3>Document List</h3>
<c:if  test="${!empty documentList}">
<table>
<tr>
	<th>Name</th>
	<th>Description</th>
	<th>&nbsp;</th>
</tr>
<c:forEach items="${documentList}" var="document">
	<tr>
		<td width="100px">${document.name}</td>
		<td width="250px">${document.description}</td>
		<td width="20px">
			<a href="${pageContext.request.contextPath}/download/${document.id}.html"><img 
				src="${pageContext.request.contextPath}/img/save_icon.gif" border="0" 
				title="Download this document"/></a> 

			<a href="${pageContext.request.contextPath}/remove/${document.id}.html"
				onclick="return confirm('Are you sure you want to delete this document?')"><img 
				src="${pageContext.request.contextPath}/img/delete_icon.gif" border="0" 
				title="Delete this document"/></a> 
		</td>
	</tr>
</c:forEach>
</table>
</c:if>
</body>
</html>

Download Source code

Click here to download full source code of Document manager application (16 KB)

Enhanced by Zemanta

Image representing Windows as depicted in Crun...

Environmental variables are used by the operating system to save settings (default values, locations of resources) to be used by Windows or by processes launched by users.
There are two types of environmental variables:

  • user variables that are specific to a particular Windows user account;
  • system variables are always visible, regardless of the used user account.

 

Even if these variables are usually defined and initialized automatically when you install the system or other applications, there are situations in which the user must manually define them to put at the disposal of applications.
The considered scenario is to set environment variables to enable the compilation and execution of Java applications from the command line (command prompt) or by using an IDE like Eclipse. By installing the Java SDK, system variables about the location of executables (compiler, java virtual machine) are not defined or initialized automatically.
Testing is done by opening command prompt (Start -> cmd) and trying to launch the compiler with the command

C:\Users\Catalin>javac.exe

If there is no system variable to indicate where to look for the this executable, the system will give an error like:

'javac' is not recognized as an internal or external command,
operable program or batch file.

The solution to this problem is given by setting the system variables: JAVA_HOME, PATH and CLASSPATH:

  1. Open the Control Panel -> System or Security –> System; the same thing can be done by right-clicking on MyComputer and choosing Properties
System window in Windows 7System window in Windows 7

2.   Choose Advanced System Settings option

System properties window in WindowsSystem properties window in Windows

3.   Choose the Environment Variables option

Environment variables in WindowsEnvironment variables in Windows

4.   In the System variables section it is selected New

5.   Define the variable name, JAVA_HOME and its value C:\Program Files\Java\jdk1.6.0_16 (for this example JDK version 1.6.0 was installed in C:\Program Files\Java\jdk1.6.0_16 folder; if needed, modify this value to reflect the real situation)

6. Insert a new system variable named, CLASSPATH and its value %JAVA_HOME%\jre\lib

New system variableNew system variable

7. For PATH, if it already exists, select it and choose the Edit option; in the editor add the value;%JAVA_HOME%\bin (the new values are separated by a semicolon from the existing ones)

Testing the system variables is done by opening a new command prompt window (Start -> cmd) and trying to launch the compiler with the command:

C:\Users\Catalin>javac
Usage: javac
where possible options include:
  -g                         Generate all debugging info
...

or, by using next commands

C:\Users\Catalin>echo %CLASSPATH%
C:\Program Files\Java\jdk1.6.0_16\jre\lib

C:\Users\Catalin>echo %JAVA_HOME%
C:\Program Files\Java\jdk1.6.0_16

C:\Users\Catalin>echo %PATH%

8. Restart the computer in order to make your system aware of these changes (thanks to Ike for reminding me)

 

Today we will create a Spring MVC based application that uses Freemarker FTL as view instead of JSP. This would give you a good insight in Spring MVC + Freemarker integration. The application is similar to previous tutorial’s User app, where a list of users will be displayed and also we can add new user.

The application is very simple:

  1. There is a table that displays user info like firstname, lastname.
  2. New user can be added via Add User form.

Below is the wireframe of our final freemarker based spring mvc 3 app.
freemarker-servlet-wireframe

So lets get started.

Things We Need

Before we starts with our Spring MVC 3 + FreeMarker example, we will need few tools.

  1. JDK 1.6 or above (download)
  2. Tomcat 6.x or above or any other container (Glassfish, JBoss, Websphere, Weblogic etc) (download)
  3. Eclipse 3.4.x or above (download)
  4. Spring MVC 3.1.2 or above (download)
  5. Freemarker JAR v2.3.15 or above(download)

Let us start with our Spring MVC based Freemarker application.

Step 1: Getting Started

Open Eclipse and goto File -> New -> Project and select Dynamic Web Project in the New Project wizard screen.

dynamic web project in eclipse

After selecting Dynamic Web Project, press Next.

eclipse dynamic web project

Write the name of the project. For example Freemarker_SpringMVC_example. Once this is done, select the target runtime environment (e.g. Apache Tomcat v6.0). This is to run the project inside Eclipse environment. After this press Finish.

Once the project is created, you can see its structure in Project Explorer. This is how the project structure would look like when we finish the tutorial and add all source code.

springmvc-freemarker-ftl-project-structure

Till this step, our basic Eclipse web project is ready. We will now add Spring MVC and Freemarker support to this project.

Step 2: Adding Spring MVC Support

First copy all required Spring MVC and supporting JAR files in WebContent > WEB-INF > lib folder. Create this folder if it does not exists. Don’t worry if you do not have these JARs. You can download the complete source code with JAR files at the end of this tutorial.

Next we change web.xml (deployment descriptor) and add Spring MVC support to it. If you do not know why we do this, I strongly recommends you to go through Spring 3 MVC Tutorial series.

Related: Spring 3 MVC hello world example

Update the web.xml with following code:

File: /WebContent/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">
        
  <display-name>Freemarker_SpringMVC_example</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

The above code in web.xml will map DispatcherServlet with url pattern *.html. One thing to note here is the name of servlet in <servlet-name> tag in web.xml. Once the DispatcherServlet is initialized, it will look for a file name [servlet-name]-servlet.xml in WEB-INF folder of web application. In this example, the framework will look for file called spring-servlet.xml.

Create a new file spring-servlet.xml under /WebContent/WEB-INF/ folder. This is the spring configuration. Copy following code into it.
File: /WebContent/WEB-INF/spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    <!-- freemarker config -->
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
      <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
    </bean>
    
    <!--
      View resolvers can also be configured with ResourceBundles or XML files. If you need
      different view resolving based on Locale, you have to use the resource bundle resolver.
    -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
      <property name="cache" value="true"/>
      <property name="prefix" value=""/>
      <property name="suffix" value=".ftl"/>
    </bean>
    <context:component-scan
        base-package="net.viralpatel" />
         
</beans>

In the above xml configuration file, we have defined a tag <context:component-scan>. This will allow Spring to load all the components from package net.viralpatel and all its child packages. This will load our UserController class. Also we have defined a bean viewResolver. We uses org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver as view resolver. Also notice how we defined bean freemarkerConfig. This defines Freemarker configuration, in our case just one property templateLoaderPath; the path where we will store all our .ftl template files.

Thus the bean viewResolver will resolve the freemarker template view. Note that in our UserController class, we have return a view name “index”. This will be resolved to path /WEB-INF/ftl/index.ftl by FreeMarkerViewResolver.

Step 3: Create Spring MVC Controller

File: /src/net/viralpatel/UserController.java

package net.viralpatel;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class UserController {
    /**
     * Static list of users to simulate Database
     */
    private static List<User> userList = new ArrayList<User>();
    //Initialize the list with some data for index screen
    static {
        userList.add(new User("Bill", "Gates"));
        userList.add(new User("Steve", "Jobs"));
        userList.add(new User("Larry", "Page"));
        userList.add(new User("Sergey", "Brin"));
        userList.add(new User("Larry", "Ellison"));
    }
    /**
     * Saves the static list of users in model and renders it
     * via freemarker template.
     *
     * @param model
     * @return The index view (FTL)
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(@ModelAttribute("model") ModelMap model) {
        model.addAttribute("userList", userList);
        return "index";
    }
    /**
     * Add a new user into static user lists and display the
     * same into FTL via redirect
     *
     * @param user
     * @return Redirect to /index page to display user list
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("user") User user) {
        if (null != user && null != user.getFirstname()
                && null != user.getLastname() && !user.getFirstname().isEmpty()
                && !user.getLastname().isEmpty()) {
            synchronized (userList) {
                userList.add(user);
            }
        }
        return "redirect:index.html";
    }
}

The UserController is a simple Spring 3 MVC controller that handles request/response. We have created a private static List userList which stores the user entries. Note that in ideal example you would like to read data from database. But for sake of simplicity we will stick to static List :)

There are two methods index() and add(), both mapped via @RequestMapping annotation. The index() method will simply store the users list in model object and render “index” view (index.ftl). And the add() method gets the user details from html form and add it inside static List. Once the add() has added user, it simply redirects the request to /index.html which will render the user list.

Apart from the above UserController class, we will also need a bean class User which holds the user information like firstname, lastname etc.

File: /src/net/viralpatel/User.java

package net.viralpatel;
public class User {
    private String firstname;
    private String lastname;
    public User() {
    }
    public User(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
    //Add Getter and Setter methods
}

Now add Freemarker view in your project.

Step 4: Create Freemarker Template Files

Create a new file index.ftl under folder /WebContent/WEB-INF/ftl/. Copy following content into it.

File: /WebContent/WEB-INF/ftl/index.ftl

<html>
<head><title>ViralPatel.net - FreeMarker Spring MVC Hello World</title>
<body>
<div id="header">
<H2>
    <a href="http://viralpatel.net"><img height="37" width="236" border="0px" src="http://viralpatel.net/blogs/wp-content/themes/vp/images/logo.png" align="left"/></a>
    FreeMarker Spring MVC Hello World
</H2>
</div>
<div id="content">
    
  <fieldset>
    <legend>Add User</legend>
  <form name="user" action="add.html" method="post">
    Firstname: <input type="text" name="firstname" /> <br/>
    Lastname: <input type="text" name="lastname" />   <br/>
    <input type="submit" value="   Save   " />
  </form>
  </fieldset>
  <br/>
  <table class="datatable">
    <tr>
        <th>Firstname</th>  <th>Lastname</th>
    </tr>
    <#list model["userList"] as user>
    <tr>
        <td>${user.firstname}</td> <td>${user.lastname}</td>
    </tr>
    </#list>
  </table>
</div
</body>
</html

This is a simple FTL template file. We just iterate model[“userList”] list in a loop and prints user’s firstname and lastname in table.

That’s All Folks

You may want to run the application see the result. I assume you have already configured Tomcat in eclipse. All you need to do:
Open Server view from Windows > Show View > Server. Right click in this view and select New > Server and add your server details.

To run the project, right click on Project name from Project Explorer and select Run as > Run on Server (Shortcut: Alt+Shift+X, R)

URL: http://localhost:8080/Freemarker_SpringMVC_example/index.html
freemarker-springmvc-ftl-example

Download Source Code

Freemarker_SpringMVC_example.zip (4.4 MB)

Reference : viralpatel.net

 

The official online color is: #A4C639 . 한국어: 공...

I think it’s very often we want to explore the existing projects source code but again sometime it may not be  available. Personally I love to dig on existing project to know how people write their codes.

Suddenly I thought, if there is any apk to java source decompiler, it would be a nice thing.  You probably know, android runs on dalvik virtual machine, so when we compile android java code, its compile to dex( dalvik executable). So I search a lot to find a way how to convert dex to jar ,and I know already how to decompile jar file to java source code.

At last I found the way out.

Here is the way-

You will need-

  1. Eclipse IDE
  2. Java Runtime (of course)
  3. JDGUI or JD Eclipse plugin   [url for eclipse Plugin http://java.decompiler.free.fr/jd-eclipse/update(or visit http://java.decompiler.free.fr/?q=jdeclipse ) ]
  4. DexToJar (get them from here: http://code.google.com/p/dex2jar/)

And now follow the steps

Step 1:  Create a java project, name it DexToJava.

Create a java project

Step 2: Create a folder and name it libs. Paste all jars file in the libs folder after extracting dex2jar-0.0.9.8.tar.gz . Go to build path. Add all the jars in the build path.

Step 3: You are almost done.  Get an apk file and paste it in your project. For me it is facebook.apk.

Step 4: right click on project and select run as.  Set main class: com.googlecode.dex2jar.v3.Main

Step 5: Set Argument facebook.apk and now click on apply and run it.

Step 6: after completing the job, you will find on console:

Step 7: now refresh the project, and you will find facebook_dex2jar.jar. And you know already how to get java source from jar. Use JD-GUI.

From jar file extracting  code ….. use http://java.decompiler.free.fr/?q=jdgui

That all.

I think you enjoy it.

1. What is Eclipse?

Most people know Eclipse as an integrated development environment (IDE) for Java. Today it is the leading development environment for Java with a marketshare of approx. 65%.

Eclipse is created by an Open Source community and is used in several different areas, e.g. as a development environment for Java or Android applications. Eclipse roots go back to 2001.

The Eclipse project is governed by the Eclip

Español: la imagen de eclipse

se Foundation. The Eclipse Foundation is a non-profit, member supported corporation that hosts the Eclipse projects and helps to cultivate both an open source community and an ecosystem of complementary products and services.

The Eclipse IDE can be extended with additional software components. Eclipse calls these software components “plug-ins”. Several Open Source projects and companies have extended the Eclipse IDE.

It is also possible to use Eclipse as a basis for creating general purpose applications (Eclipse RCP).

2. Getting started

2.1. Java

Eclipse requires an installed Java Runtime. I recommend to use Java 7 (also known as Java 1.7) or Java 6.

Java comes in two flavors, the Java Runtime Environment (JRE) and the Java Development Kit (JDK). The JRE contains only the necessary functionality to start Java programs, while the JDK contains in addition the development tools.

Eclipse contains its own development tools, e.g. Java compiler. Therefore for this tutorial it is sufficient to use the JRE.

The JDK is required if you compile Java source code outside Eclipse and for advanced development scenarios. For example if you use automatic builds or if you develop web development. These scenarios are not covered in this tutorial.

Java might already be installed on your machine. You can test this by opening a console (if you are using Windows: Win+R, enter “cmd” and press Enter) and by typing in the following command:

				
java -version

If Java is correctly installed you should see some information about your Java installation. If the command line return the information that the program could not be found, you have to install Java. A Google search for “How to install Java on …” should result in helpful links. Replace “…” with your operating system, e.g. Windows, Ubuntu, Mac OS X, etc.

2.2. Install Eclipse

To install Eclipse download the package “Eclipse IDE for Java Developers” from the website http://www.eclipse.org/downloads and unpack it to a local directory.

The download is a “zip” file. Most operating system can extract zip files in their file browser, e.g. Windows7 via right mouse click on the file and selecting “Extract all…”. If in doubt, search via Google for “How to unzip a file on …”, again replacing “…” with your operating system.

Use a directory path which does not contain spaces in its name, as Eclipse sometimes has problems with that.

After unpacking the download, Eclipse is ready to be used; no additional installation procedure is required.

2.3. Start Eclipse

To start Eclipse double-click on the file eclipse.exe (Microsoft Windows) or eclipse (Linux / Mac) in the directory where you unpacked Eclipse. The system will prompt you for a workspace. The workspace is the place where you store your Java projects (more on workspaces later). Select an empty directory and press Ok.

Selecting the Workspace

Eclipse will start and show the Welcome page. Close the welcome page by pressing the “X” beside “Welcome”.

Closing the Eclipse welcome screen

3. Eclipse UI Overview

Eclipse provides Perspectives, Views and Editors. Views and Editors are grouped into Perspectives. All projects are located in a workspace.

3.1. Workspace

3.1.1. What is the workspace?

The workspace is the physical location (file path) you are working in. You can choose the workspace during startup of Eclipse or via the menu ( File → Switch Workspace → Others) . All your projects, source files, images and other artifacts will be stored and saved in your workspace.

3.1.2. Workspace related startup parameters

Eclipse allows that certain behavior is configured via startup parameters. The following parameters are relevant for the Workspace.

Table 1. Workspace Startup Parameterse

Parameter Description
-data workspace_path Predefine the Eclipse workspace.
-showLocation Configures Eclipse so that is shows the current workspace directory in the title of Eclipse.

For example if you want to start Eclipse under Microsoft Windows with the workspace “c:\temp” you can use the following command from the command line.

					
c:\eclipse.exe -data "c:\temp"

Depending on your platform you may have to put the path name into double quotes.

3.2. Parts

Parts are user interface components which allow to navigate and modify data. Parts are typically divided into Views and Editors.

Eclipse application with a few parts

The distinction into Views and Editors is primarily not based on technical differences, but on a different concept of using and arranging these Parts.

A View is typically used to work on a set of data, which might be hierarchical structured. If data is changed via the View, this change is typically directly applied to the underlying data structure. A View sometimes allows us to open an Editor for a selected set of the data.

An example for a View is the Java Package Explorer, which allow you browse the files of Eclipse Projects. If you choose to change data in the Package Explorer, e.g. if you rename a file, the file name is directly changed on the filesystem.

Editors are typically used to modify a single data element, e.g. a file or a data object. To apply the changes done in an editor to the data structure, the user have to explicitly select a “Save” command, e.g. Menu entry.

Editors were traditionally placed in a certain area, called the “editor area”. Until Eclipse 4 this was a hard limitation, it was not possible to move an Editor out of this area; Eclipse 4 allows to place Editors at any position in a Perspective.

For example the Java Editor is used to modify Java source files. Changes to the source file are applied, once the user selects the “Save” command.

3.3. Perspective

A Perspective is a visual container for a set of Parts.

You can change the layout and content within a Perspective by opening or closing Parts and by re-arranging them.

As of Eclipse 4.x Perspectives are optional elements for Eclipse based applications. The Eclipse IDE uses Perspectives to arrange Parts for different development tasks.

3.4. Eclipse IDE Perspectives

The Eclipse IDE ships with several default Perspectives.

For Java development you usually use the Java Perspective, but Eclipse has much more predefined Perspectives, e.g. Debug, Git Repositories, CVS Repositories.

Eclipse allows you to switch to another perspective via the menu Window → Open Perspective → Other.

A common problem is that you mis-configured your Perspective, e.g. by closing a View. You can reset a Perspective to its original state via the menu Window → Reset Perspective.

3.5. Java Perspective and Package Explorer

The default Perspective for Java development can be opened via Window → Open Perspective → Java.

On the left hand side, this perspective shows the “Package Explorer” View, which allows to browse your Java projects and to select the components you want to work on via double-click.

For example to open a Java source file, open the tree under src, select the corresponding .java file and double-click it. This will open the file in an Editor.

The following picture shows the Eclipse IDE in its standard Java perspective. The “Package Explorer” is on the left. In the middle you have the open Editor for a Java source file. If several Editors would be open, they would be stacked in the same place and you could switch between them by clicking on the next Editor. All editors share the same part of the Eclipse IDE; this part is called the “editor area”.

To the right and below the editor area you find more Views which were considered useful by the developer of the perspective. For example the “Console” view shows the output of System.out statements in your code.

Eclipse Java Perspective

3.6. Linking the package explorer with the code editor

The Package Explorer allows displaying the associated file from the currently selected editor. For example if you working on Foo.java and you change in the editor to Var.java then the corresponding file will be selected in the “Package explorer” View.

To activate this behavior, press the button “Link with Editor” in the “Package explorer” View.

Synchronize the project explorer with the current selected editor

3.7. Problems view

Sooner or later you will run into problems with your code or your project setup. To view the problems in your project you can use the “Problems” View which is part of the standard Java Perspective. If it is closed you can open it via Windows → Show View → Problems.

Opening the problems view

You can configure the content of the “Problems” View. For example, to display the problems from the currently selected project, select “Configure Contents” and set the Scope to “On any element in the same project”.

Configuring the problems view
Configuring the problems view

4. Create your first Java program

The following describes how to create a minimal Java program using Eclipse. It is tradition in the programming world to create a small program which writes “Hello World” to the console. We will adapt this tradition and will write “Hello Eclipse!” to the console.

4.1. Create project

Select from the menu File → New → Java project. Enter de.vogella.eclipse.ide.first as the project name. Select the flag “Create separate folders for sources and class files”.

New Java Project Wizard

Press finish to create the project. A new project is created and displayed as a folder. Open the de.vogella.eclipse.ide.first folder and explore the content of this folder.

4.2. Create package

Create a new package. A good convention is to use the same name for the top package and the project. Create therefore the package de.vogella.eclipse.ide.first.

Select the folder src, right click on it and select New → Package.

Right mouse click to create a package
Create a package Dialog

4.3. Create Java class

We will now create a Java class. Right click on your package and select New → Class.

Create a new class selection

Enter MyFirstClass as the class name and select the flag “public static void main (String[] args)”.

Create a new class selection

This creates a new file and opens an Editor to edit the source code of this file. Write the following code.

				
package de.vogella.eclipse.ide.first;

public class MyFirstClass {

	public static void main(String[] args) {
		System.out.println("Hello Eclipse!");
	}

}

4.4. Run your project in Eclipse

Now run your code. Right click on your Java class and select Run-as → Java application.

Run project

Finished! You should see the output in the console.

Result of the running application

4.5. Prepare to run program outside Eclipse (create jar file)

To run your Java program outside of Eclipse you need to export it as a jar file. A jar file is the standard distribution format for Java applications.

Select your project, right click on it and select Export.

Export wizard for Java project

Select JAR file, select next. Select your project and maintain the export destination and a name for the jar file. I named it myprogram.jar.

Export wizard for Java project, Part II
Export wizard for Java project, Part III

Press finish. This creates a jar file in your selected output directory.

4.6. Run your program outside Eclipse

Open a command shell, e.g. under Microsoft Windows select Start → Run and type cmd and press enter. This should open a console.

Switch to your output directory, by typing cd path. For example if your jar is located in c:\temp type cd c:\temp.

To run this program you need to include the jar file in your classpath. The classpath defines what Java classes are available to the Java runtime. You can add a jar file to the classpath with the -jar option.

				
java -classpath myprogram.jar de.vogella.eclipse.ide.first.MyFirstClass

If you type the command from above and are in the correct directory you should see the “Hello Eclipse!” output on the console.

Running application outside Eclipse

Congratulations! You created your first Java project, a package, a Java class and you ran this program inside and outside Eclipse.

5. Content Assist, Quick Fix and Class Navigation

5.1. Content assist

The content assistant allows you to get input help in an editor. It can be invoked by pressing CTRL+Space

For example type syso in the editor of a Java source file and then press CTRL+Space. This will replace syso with System.out.println("").

If you have a reference to an object, for example the object person of the type Person and need to see it’s methods, type person. and press CTRL+Space.

Content Assists

5.2. Quick Fix

Whenever Eclipse detects a problem, it will underline the problematic text in the editor. Select the underlined text and press CTRL+1 to see proposals how to solve this problem.

For example type myBoolean = true; If myBoolean is not yet defined, Eclipse will highlight it as an error. Select the variable and press CTRL+1, Eclipse will suggest creating a field or local variable.

Using Quickfix Example

Quick Fix is extremely powerful. It allows you to create new local variables and fields as well as new methods and new classes. I can put try-catch statements around your exceptions. It can assign a statement to a variable and much more.

6. Opening a class

You can navigate between the classes in your project via the “Package Explorer” View.

In addition you can open any class via positioning the cursor on the class in an editor and pressing F3. Alternatively, you can press CTRL+Shift+T. This will show a dialog in which you can enter the class name to open it.

Opening a class

7. Generating code

Eclipse has several possibilities to generate code for you. This can save significant time during development.

For example Eclipse can override methods from superclasses and generate the toString(), hashcode() and equals() methods. It can also generate getter and setter methods for attributes of your Java class.

You can find these options in the Source menu.

Code generation

To test the source generation, create the following class in your de.vogella.eclipse.ide.first project.

			
package de.vogella.eclipse.ide.first;

public class Person {
	private String firstName;
	private String lastName;

}

Select Source → Generate Constructor from Fields, mark both fields and press “Ok”.

Generating

Select Source → Generate Getter and Setter, select again both your fields and press the “Ok” button.

Select Source → Generate toString(), mark again both fields and press “Ok”.

You created the following class:

			
package de.vogella.eclipse.ide.first;

public class Person {
	private String firstName;
	private String lastName;

	public Person(String firstName, String lastName) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return "Person [firstName=" + firstName + ", lastName=" + lastName
				+ "]";
	}

}

8. Refactoring

Refactoring is the process of restructuring the code without changing his behavior. For example renaming a Java class or method is a refactoring activity.

Eclipse supports simple refactoring activities, for example renaming or moving. For example you can select your class, right click on it and select Refactor → Rename to rename your class or method. Eclipse will make sure that all calls in your Workspace to your your class or method will also be renamed.

The following shows a screenshot for calling the “Rename” refactoring on a class.

Renaming a class

For the next examples change the code of “MyFirstClass.java” to the following.

			
package de.vogella.eclipse.ide.first;

public class MyFirstClass {

	public static void main(String[] args) {
		System.out.println("Hello Eclipse!");
		int sum = 0;
		for (int i = 0; i <= 100; i++) {
			sum += i;
		}
		System.out.println(sum);
	}
}

Another useful refactoring is to mark code and create a method from the selected code. For this mark the coding of the “for” loop, right click and select Refactoring → Extract Method. Use “calculateSum” as name of the new method.

Extract Method refactoring

The resulting class should look like the following.

			
package de.vogella.eclipse.ide.first;

public class MyFirstClass {

	public static void main(String[] args) {
		System.out.println("Hello Eclipse!");
		int sum = 0;
		sum = calculateSum(sum);
		System.out.println(sum);
	}

	private static int calculateSum(int sum) {
		for (int i = 0; i <= 100; i++) {
			sum += i;
		}
		return sum;
	}
}

You can also extract strings and create constants from them. Mark for this example “Hello Eclipse!”, right click on it and select Refactor → Extract Constant. Name your new constant “HELLO”.

Extract Constants

The resulting class should look like the following.

			
package de.vogella.eclipse.ide.first;

public class MyFirstClass {

	private static final String HELLO = "Hello Eclipse!";

	public static void main(String[] args) {
		System.out.println(HELLO);
		int sum = 0;
		sum = calculateSum(sum);
		System.out.println(sum);
	}

	private static int calculateSum(int sum) {
		for (int i = 0; i <= 100; i++) {
			sum += i;
		}
		return sum;
	}
}

Eclipse has much more refactorings, in most cases you should get an idea of the performed action by the naming of the refactoring operation.

9. Eclipse Shortcuts

Eclipse provides a lot of shortcuts to work efficiently with the IDE. For a list of the most important Eclipse shortcuts please see Eclipse Shortcuts

10. Using jars (libraries)

10.1. Adding a library (.jar ) to your project

The following describes how to add Java libraries to your project. Java libraries are distributed via “jar” files. It assumes that you have a jar file available; if not feel free to skip this step.

Create a new Java project de.vogella.eclipse.ide.jars. Then, create a new folder called lib, by right clicking on your project and selecting New → Folder.

Creating a new folder

From the menu select File → Import → General → File System. Select your jar and select the folder lib as target. Alternatively, just copy and paste your jar file into the “lib” folder.

Right click on your project and select Properties. Under Java Build Path → Libraries select the button “Add JARs”.

The following example shows how the result would look like, if the junit-4.4.jar had been added to the project.

Adding a jar to the current project

Afterwards you can use the classes contained in the jar file in your Java source code.

10.2. Attach source code to a Java library

As said earlier you can open any class via positioning the cursor on the class in an editor and pressing F3. Alternatively, you can press CTRL+Shift+T. This will show a dialog in which you can enter the class name to open it.

If the source code is not available, the editor will show the decompiled byte-code of that class.

This happens if you open a class from Java library and the source for this .jar file is not available. The same happens if you open a class from the standard Java library without attaching the source code to it.

To browse the source of a type contained in a library (i.e. .jar file), you can attach a source archive or source folder to that library. Afterwards the editor will show the source instead of the byte-code.

In addition setting the source attachment allows debugging this source code.

The Source Attachment dialog can be reached in the Java Build Path page of a project. To open this page, right click on a project → Properties → Java Build Path. On the “Libraries” tab, expand the library’s node, select the “Source attachment” attribute and press Edit.

In the Location path field, enter the path of an archive or a folder containing the source.

The following shows this for the standard Java library. If you have the Java Development Kit (JDK) installed, you should find the source in the JDK installation folder. The file is typically called “src.zip”.

Maintaining the location of the source attachment to an jar

10.3. Add the Javadoc for a jar

It is also possible to add Javadoc to a library which you use.

Download the Javadoc of the jar and put it somewhere in your filesystem.

Open the Java Build Path page of a project via Right click on a project → Properties → Java Build Path. On the “Libraries” tab expand the library’s node, select the “Javadoc location” attribute and press Edit.

Enter the location to the file which contains the Javadoc.

Maintain the location to the Javadoc file for a jar file

11. Updates and Installation of Plugins

11.1. Eclipse Update Manager

Eclipse contains an Update Manager which allows you to install and update software components. Installable software components are called features and consists of plug-ins.

To update your Eclipse installation, select Help → Check for Updates. The system will search for updates for the already installed software components. If it finds updated components, it will ask you to approve the update.

To install a new functionality, select Help → Install New Software

Selecting an update site in the update manager

From the “Work with” list, select an URL from which you would like to install.

To add a new update site, press “Add” and enter the new URL as well as a name for the new update site.

Sometimes you have to uncheck “Group items by category” because not all available plug-ins are categorized. If they are not categorized, they will not be displayed, unless the grouping is disabled.

11.2. Manual installation of plug-ins (dropins folder)

If you’re using a plug-in for which no Update Site is available, you can use the “dropins” folder in your Eclipse installation directory.

Plug-ins are typically distributed as .jar files. To add a plug-in to your Eclipse installation, put the plug-in .jar file into the Eclipse “dropins” folder and restart Eclipse. Eclipse should detect the new plug-in and install it for you.

11.3.  Eclipse Marketplace

Eclipse also contains a client which allows installing software components from the Eclipse Marketplace. The advantage of this client is that you can search for components, discover popular extensions and see descriptions and ratings.

Compared to the update manager you don’t have to know the URL for the update site.

To open the Eclipse Marketplace select Help → Eclipse Marketplace.

Showing the Eclipse Marketplace Client

You can use the “Find” box to search for components. Pressing “Install” will start the installation process.

11.4. Share plug-in

Eclipse 4.2 also allow to export a description file which for selected Eclipse components. Other users can import this description file into their Eclipse installation and install these components from the file.

This way Eclipse installation can be kept in sync with each other.

To export a description file, select File → Export → Install → Installed Software Items to File and select the components which should be included into your description file.

Exporting a description file for p2

To install selected components of this file in another Eclipse Installation, open it with File → Import → Install → Install Software Items from File and follow the wizard.

11.5.  Restart required?

After an update or an installation of a new software component Eclipse to restart Eclipse. In general, it is a good idea to restart Eclipse in this situation, otherwise some components might not work corrrectly.

12. Efficiency Settings

12.1. Eclipse Preferences

The behavior of the Eclipse IDE can be controlled via the Preference Settings. Select Window → Preferences to open the preference settings dialog. You can use the filter box to search for specific settings.

12.2. Automatic placement of semicolon

Eclipse can make typing more efficient by placing semicolons at the correct position in your source code.

In the Preference setting select Java → Editor → Typing. In the section “Automatically insert at correct position”, enable the “Semicolons” checkbox.

You can now type a semicolon in the middle of your code and Eclipse will position it at the end of the current statement.

Type Assists which allow setting the semicolon to the right position

12.3. Imports and Source code formating

Eclipse can format your source code and organize your import statements automatically during a save operation. This is useful as the “Save” shortcut ( CTRL+S ) is easy to reach.

You can find this setting under Java → Editor → Save Actions.

Save Actions

Import statements will only be automatically imported, if Eclipse finds only one valid import. If Eclipse determines more than one valid import, it will not add import statements automatically.

12.4. Filter import statements

The “Organize imports” Save Action or the ““Organize Imports” shortcut ( CTRL+Shift+) ) allows to import the packages which are required. If there are several alternatives, Eclipse suggests all available packages and the user has to select the right one.

To following shows the available packages for the List class in the “Organize Imports” dialog.

Dialog for selecting the correct import statement

This is annoying, if you never use certain packages. You can exclude these packages via Windows → Preferences → Java → Appearance → Type Filters

Press “Add packages” to add a specific package or “Add” to use wildcards. The following will exclude all AWT packages from import.

Filtering packages from the Eclipse import

12.5. Templates

If you have to frequently type the same code / part of the document, you can create templates which can be activated via autocomplete (Ctrl + Space).

For example, assume that you are frequently creating public void name(){} methods. You could define a template which creates the method body for you.

To create a template for this, select the menu Window → Preferences → Java → Editor → Templates.

Maintaining code templates

Press New. Create the template shown in the following screenshot.

Creating a new code template

${cursor} indicates that the cursor should be placed at this position after applying the template.

In this example the name “npm” is your keyword.

Now every time you type “npm” in the Java editor and press CTRL+Space the system will allow you to replace your keyword with your template.

Using code templates

12.6. Configuring the editors for a file extension

The Editors which are available to open a file can be configured via Window → Preferences → General → Editors → File Associations

.

The “Default” button in this preference dialog allows to set the default editor for a certain file extension, e.g. this is the editor which will be used per default if you open a new file with this extension.

The other configured Editors can be selected, if you right mouse click on a file and select “Open-With”. Eclipse will remember the last Editor you used to open a file and use this Editor again the next time you open the file.

12.7. Code Templates

Eclipse generates lots of source code automatically. For example, in several cases comments are added to the source code.

Select Window → Preferences → Java → Code Style → Code Templates to change the code generation templates.

In the code tree you have the templates. Select for example Code → Method Body and press “Edit” to edit this template and to remove the “todo” comment.

Removing the todos from the Java code templates

12.8. Export / Import Preferences

You can export your preference settings from one workspace via File → Export → General → Preferences.

Similarly you can import them again into another workspace.

12.9. Task Management

You can use // TODO comments in your code to add task reminders.

This indicates a task for Eclipse. You find those in the Task View of Eclipse. Via double-clicking on the task you can navigate to the corresponding code.

You can open this View via Window → Show View → Tasks.

For example, add a TODO to your MyFirstClass class to see it in the Tasks View.

				
package de.vogella.eclipse.ide.first;

public class MyFirstClass {	private static final String HELLO = "Hello Eclipse!";	public static void main(String[] args) {
		// TODO Provide user interface
		System.out.println(HELLO);
		int sum = 0;
		sum = calculateSum(sum);
		System.out.println(sum);
	}	private static int calculateSum(int sum) {
		for (int i = 0; i <= 100; i++) {
			sum += i;
		}
		return sum;
	}
}

Close the editor for the MyFirstClass class. If you now double-click on the tasks, the Java editor opens again and the TODO comment is selected.

12.10. Working Sets

You will create more and more projects in your development career. Therefore the data in your workspace grows and it is hard to find the right information.

You can use working sets to organize your displayed projects / data. To set up your working set select the Package Explorer → open the drop-down menu → Select Working Set…

Showing the working set

Press “New” on the following dialog to create a working set.

Creating new working sets

On the next dialog select “Resource”, press Next and select the projects you would like to see and give it a name.

Creating new working sets
Creating new working sets

You can now easily display only the files you want to see.

Filtering resources for the working set

13. Eclipse Help and Community

13.1. Eclipse Bugs

Eclipse has a public bug tracker based on Bugzilla. This bugtracker can be found under https://bugs.eclipse.org/bugs/. Here you can search for existing bugs and review them.

To participate actively in the Eclipse bugtracker you need to create a new account. This can be done by pressing the “Open a New Account” link.

Once you have an user you can login to the Eclipse bugtracker. This allows you to comment on existing bugs and report new ones.

13.2. Online documentations

The Eclipse help system is available from within your Eclipse installation as well as online.

With your running Eclipse IDE you can access the online help via Help → Help Contents. This will start a new window which shows you the help topics for your currently installed components.

Starting the Eclipse help

Online you find the online help under http://www.eclipse.org/documentation/. The online help is version dependent and contains the help for all Eclipse projects included in the selected release.

13.3. Asking (and answering) questions

Due to the complexity and extensibility of Eclipse you will need additional resources to help you resolve your specific problems. Fortunately the web contains several resources which can help you with your Eclipse problems.

Currently the best places to ask questions are the Eclipse forums, which can be found under http://eclipse.org/forums and Stackoverflow, which can be found under http://stackoverflow.com.

The Eclipse forums offer several topic specific forums in which you can post and answer questions. To post questions in the Eclipse forums you need a valid user in the Eclipse bugtracker. The advantage of the Eclipse forums is that, depending on the topic, Eclipse committer are also active there and might directly answer your question.

Stackoverflow also requires a user and its community is also very active. Stackoverflow does not have separate forums specific questions. In Stackoverflow you tag your questions with the relevant keyword, e.g. “Eclipse” and people interested in these keyword search for them or subscribe to them.

Both places are excellent places to ask questions. If you ask a question it is in general good advice to be polite and to give a good error description as this motivates people to give you high quality answers.

13.4. Webresources

The Eclipse homepage also contains a list of relevant resources about Eclipse and Eclipse programming. You find these resources under http://www.eclipse.org/resources/.

14. Thank you

Android Robot. Français : le logo d'android 日本...

In this tutorial, you will learn how to use Eclipse to create an Android JUnit Test Project, create automated unit tests and run them under a variety of conditions.

Before You Begin

The authors are assuming the reader has some basic knowledge of Android and have all of the tools such as Eclipse and the Android SDK installed and working. The examples given here are engineered to show how the Android JUnit framework can be used to test Android applications. Specifically, this tutorial will show you how to test aspects of an Activity and identify program errors. These errors are determined, but not addressed, as part of this tutorial.

Note: The code for the SimpleCalc application is available on Google Code as well as from the above link.

Step 1: Review the SimpleCalc Application

First, let’s take a few moments to look over the SimpleCalc application. It’s a very simple application with just one screen. The screen has two simple functions: it allows the user to input two values, adds or multiplies these values together and displays the result as shown below.

Junit Testing The SimpleCalc application

Step 2: Review the SimpleCalc Screen Layout

The SimpleCalc application has just one screen, so we have only one layout resource file called /res/layout/main.xml.

Here is a listing of the main.xml layout resource:
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
  3.     android:orientation=”vertical” android:layout_width=”fill_parent”
  4.     android:layout_height=”fill_parent”>
  5.     <TextView android:layout_width=”fill_parent”
  6.         android:layout_height=”wrap_content” android:text=”@string/hello”
  7.         android:gravity=”center_horizontal” android:textSize=”48px”
  8.         android:padding=”12px” />
  9.     <EditText android:layout_height=”wrap_content” android:id=”@+id/value1″
  10.         android:hint=”@string/hint1″ android:inputType=”numberDecimal”
  11.         android:layout_width=”fill_parent” android:textSize=”48px”></EditText>
  12.     <EditText android:layout_height=”wrap_content” android:id=”@+id/value2″
  13.         android:hint=”@string/hint2″ android:inputType=”numberDecimal”
  14.         android:layout_width=”fill_parent” android:textSize=”48px”></EditText>
  15.     <FrameLayout android:id=”@+id/FrameLayout01″
  16.         android:layout_width=”wrap_content” android:layout_height=”wrap_content”
  17.         android:padding=”12px” android:background=”#ff0000″>
  18.         <LinearLayout android:id=”@+id/LinearLayout02″
  19.             android:layout_width=”wrap_content” android:layout_height=”wrap_content”
  20.             android:orientation=”horizontal” android:background=”#000000″
  21.             android:padding=”4px”>
  22.             <TextView android:layout_width=”wrap_content”
  23.                 android:layout_height=”wrap_content” android:text=”@string/resultLabel”
  24.                 android:textSize=”48px” android:id=”@+id/resultLabel”></TextView>
  25.             <TextView android:layout_width=”wrap_content”
  26.                 android:layout_height=”wrap_content” android:id=”@+id/result”
  27.                 android:textSize=”48px” android:textStyle=”bold”
  28.                 android:layout_marginLeft=”16px”></TextView>
  29.         </LinearLayout>
  30.     </FrameLayout>
  31.     <LinearLayout android:id=”@+id/LinearLayout03″
  32.         android:layout_height=”wrap_content” android:layout_width=”fill_parent”>
  33.         <Button android:layout_height=”wrap_content” android:id=”@+id/addValues”
  34.             android:text=”@string/add” android:textSize=”32px”
  35.             android:layout_width=”wrap_content”></Button>
  36.         <Button android:layout_height=”wrap_content” android:id=”@+id/multiplyValues”
  37.             android:text=”@string/multiply” android:textSize=”32px”
  38.             android:layout_width=”wrap_content”></Button>
  39.     </LinearLayout>
  40. </LinearLayout>

This layout is fairly straightforward. The entire content of the screen is stored within a LinearLayout, allowing the controls to display one after another vertically. Within this parent layout, we have the following controls:

  • A TextView control displaying the header “Unit Testing Sample.”
  • Two EditText controls to collect user input in the form of two numbers.
  • A FrameLayout control which contains a horizontal LinearLayout with the result label TextView and resulting sum or product TextView. The FrameLayout displays a red border around these controls, highlighting the result.
  • Finally, another horizontal LinearLayout with two child controls: a Button control for addition and a Button control for multiplication.

This layout is designed to look right in the Android Layout Designer when the Nexus One option (which has a screen size of 800×480) is chosen in both portrait and landscape modes. You’ll soon see that this is not a bullet-proof way of designing layouts. As with the code you’ll see in the next step, it isn’t designed to work perfectly.

Step 3: Review the SimpleCalc Activity

The SimpleCalc application has just one screen, so we have only one Activity as well: MainActivity.java. The MainActivity.java class controls the behavior of the one screen, whose user interface is dictated by the main.xml layout.

Here is a listing of the MainActivity.java class:

  1. package com.mamlambo.article.simplecalc;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.EditText;
  9. import android.widget.TextView;
  10. public class MainActivity extends Activity {
  11.    /** Called when the activity is first created. */
  12.    @Override
  13.    public void onCreate(Bundle savedInstanceState) {
  14.        final String LOG_TAG = “MainScreen”;
  15.        super.onCreate(savedInstanceState);
  16.        setContentView(R.layout.main);
  17.        final EditText value1 = (EditText) findViewById(R.id.value1);
  18.        final EditText value2 = (EditText) findViewById(R.id.value2);
  19.        final TextView result = (TextView) findViewById(R.id.result);
  20.        Button addButton = (Button) findViewById(R.id.addValues);
  21.        addButton.setOnClickListener(new OnClickListener() {
  22.            public void onClick(View v) {
  23.                try {
  24.                    int val1 = Integer.parseInt(value1.getText().toString());
  25.                    int val2 = Integer.parseInt(value2.getText().toString());
  26.                    Integer answer = val1 + val2;
  27.                    result.setText(answer.toString());
  28.                } catch (Exception e) {
  29.                    Log.e(LOG_TAG, “Failed to add numbers”, e);
  30.                }
  31.            }
  32.        });
  33.        Button multiplyButton = (Button) findViewById(R.id.multiplyValues);
  34.        multiplyButton.setOnClickListener(new OnClickListener() {
  35.            public void onClick(View v) {
  36.                try {
  37.                    int val1 = Integer.parseInt(value1.getText().toString());
  38.                    int val2 = Integer.parseInt(value2.getText().toString());
  39.                    Integer answer = val1 * val2;
  40.                    result.setText(answer.toString());
  41.                } catch (Exception e) {
  42.                    Log.e(LOG_TAG, “Failed to multiply numbers”, e);
  43.                }
  44.            }
  45.        });
  46.    }
  47. }
As you can see, the Java for this class is quite straightforward. It simply implements onClick() handlers for both the addition and multiplication Button controls.

When a Button is pressed, the Activity retrieves the values stored in the two EditText controls, calculates the result, and displays it in the TextView control called R.id.result.

Note: There are bugs in this code! These bugs have been designed specifically to illustrate unit testing.

Step 4: Creating an Android Test Project

You can add a test project to any Android project in two ways. You can add a test project while creating a new Android project with the Android Project Wizard or you can add a test project to an existing Android project. (The steps are basically the same.)

For this example, we have an existing project. To add a test project to the SimpleCalc project in Eclipse, take the following steps:

From the Project Explorer, choose the Android project you wish to add a test project to. Right-click on the project and choose Android Tools->New Test Project…

Junit Testing, Creating a Test Project

Step 5: Configuring the Android Test Project

Now you need to configure the test project settings, including the test project name, file location, Android project to test and build target (SDK version).

For this example, we can use the following settings:

  • Test project names generally end in “Test”, so let’s name this test project SimpleCalcTest
  • The project location can be wherever you normally store source files on your hard drive.
  • Choose the Android project to test: SimpleCalc
  • The appropriate build target will be selected automatically once you select the project to test. In this case, since the Android project is built for Android 2.1 + Google APIs (API Level 7), it makes sense to use the same build target for the test project.
  • It makes sense to name the test project accordingly: SimpleCalcTest, with the appropriate package name suffix simplecalc.test.
Configuring the project test

Hit Finish.

Step 6: Review the SimpleCalcTest Project

The SimpleCalcTest project is an Android project. You will notice that it has all the normal things you’d expect of an Android project, including a Manifest file and resources.

Junit Testing SimpleCalcTest Project Files

Step 7: Determine Unit Tests for the SimpleCalc Application

Now that you have a test project configured for the SimpleCalc application, it makes sense to determine some reasonable unit tests for the application.

Many software methodologies these days work compatibly with unit testing. Unit tests can greatly increase the stability and quality of your application and reduce testing costs. Unit tests come in many forms.

Unit tests can:

  • Improve testing coverage
  • Test application assumptions
  • Validate application functionality

Unit tests can be used to test core functionality, such as whether or not the SimpleCalc math is being performed correctly. They can also be used to verify if the user interface is displaying correctly. Now let’s look at some specific test cases.

Step 8: Create Your First Test Case

To create your first test case, right-click on the simplecalc.test package and choose New->JUnit Test Case.

Configuring test case settings.

Step 9: Configure Your First Test Case

Now you need to configure the test case settings.

For this example, we can use the following settings:

  • Both JUnit 3 and 4 are supported. We’ll use the default JUnit 3 here.
  • The source folder should be the location of the SimpleCalcTest project files.
  • The package should be the package name of the SimpleCalcTest project.
  • In this case, we will name the test case MathValidation.
  • For the SuperClass, choose “android.test.ActivityInstrumentationTestCase2.” This is the test case you use for testing activities.
  • Check the boxes to add method stubs for setUp() and constructor.
junit Testing, Configuring test case settings.

Hit Finish. (You can safely ignore the warning saying, “Superclass does not exist.”)

Step 10: Review the MathValidation Test Case

The MathValidation.java test case source file is then created.

The lifecycle of a test case is basically this: construction, setUp(), tests run, tearDown(), and destruction. The setUp() method is used to do any general initialization used by all of specific tests. Each test to be run in the test case is implemented as its own method, where the method name begins with “test”. The tearDown() method is then used to uninitialize any resources acquired by the setUp() method.

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. public class MathValidation extends
  4.        ActivityInstrumentationTestCase2<MainActivity> {
  5.    public MathValidation(String name) {
  6.        super(name);
  7.    }
  8.    protected void setUp() throws Exception {
  9.        super.setUp();
  10.    }
  11. }

Now it’s time to implement the MathValidation Test Case

Step 11: Modify the MathValidation Class Constructor

First, modify the MathValidation class constructor. This constructor ties configures the internals of the Android test superclass we’re using.

  1. public MathValidation() {
  2.        super(“com.mamlambo.article.simplecalc”, MainActivity.class);
  3. }

Step 12: Implement the MathValidation setUp() method

Now you need to gather the data required for validating the SimpleCalc math calculations. Begin by implementing the setUp() method. You can retrieve the Activity being tested using the getActivity() method as follows:

  1. MainActivity mainActivity = getActivity();

Next, you need to retrieve an instance of the TextView control called R.id.result. This is the control that will hold the resulting sum or product from the math calculations used by the application.

The full updated code listing (MathValidation.java) with these modifications is shown below:

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. import android.widget.TextView;
  4. import com.mamlambo.article.simplecalc.MainActivity;
  5. import com.mamlambo.article.simplecalc.R;
  6. public class MathValidation extends ActivityInstrumentationTestCase2<MainActivity> {
  7.    private TextView result;
  8.    public MathValidation() {
  9.        super (“com.mamlambo.article.simplecalc”, MainActivity.class);
  10.    }
  11.    @Override
  12.    protected void setUp() throws Exception {
  13.        super.setUp();
  14.        MainActivity mainActivity = getActivity();
  15.        result = (TextView) mainActivity.findViewById(R.id.result);
  16.    }
  17. }

Step 13: Consider Tests for the SimpleCalc Application

Now that everything is set up, what tests do you want to perform? Let’s begin by checking the math used by the SimpleCalc application. Specifically, let’s check that the numbers are retrieved correctly, as well as added and multiplied correctly. Did we set the right types for our number values? Are we retrieving and performing mathematical calculations using the correct types?

To answer these questions, we must add some testing code to the MathValidation class. Each specific test will have it’s own method beginning with “test” – the “test” method name prefix is case sensitive! This naming scheme is how JUnit determines what methods to run.

Step 14: Implement a Method to Test SimpleCalc’s Addition

Let’s begin by testing the addition calculation of SimpleCalc. To do this, add a method called testAddValues() to the MathValidation class.

This test will enter two numbers (24 and 74) into the screen and press Enter, which acts as a click on the first Button control which is in focus. Then it will retrieve the sum displayed by the application in the result TextView control and test to see if the result is the expected one (98).

To supply the EditText controls with two numbers to sum, use the sendKeys() method. This method mimics how keys are sent to Android applications. If you use the setText() method of the EditText control to set the text in each control, then you are bypassing the validation of the numeric entry that user’s would encounter. This method of providing key strokes assumes that the focus starts on the first control and that using the Enter key goes to the next one (you’ll see that the enter key is sent at the end of each number). If neither of those assumptions is true, the test will also fail. This is not a bad thing, but it might be failing for the wrong reasons (e.g. focus or layout issues, rather than math issues).

Finally, you use the assertTrue() method to compare the actual result displayed on the screen to the expected result. ). We compare against a string, since the result is displayed as a string. This way, we can also make sure we don’t duplicate any math or type errors in the application logic within the test framework.
Here is the full listing of the testAddValues() method:

  1. private static final String NUMBER_24 = “2 4 ENTER “;
  2. private static final String NUMBER_74 = “7 4 ENTER “;
  3. private static final String ADD_RESULT = “98”;
  4. public void testAddValues() {
  5.    sendKeys(NUMBER_24);
  6.    // now on value2 entry
  7.    sendKeys(NUMBER_74);
  8.    // now on Add button
  9.    sendKeys(“ENTER”);
  10.    // get result
  11.    String mathResult = result.getText().toString();
  12.    assertTrue(“Add result should be 98”, mathResult.equals(ADD_RESULT));
  13. }

Congratulations! You’ve created your first test!

Step 15: Enhancing the Tests for Addition

Now let’s add a few more tests to make sure all different types of numbers can be added, resulting in the display of the proper sum.

Because the activity is launched for each test, you do not need to clear the values or anything like that between tests. You also do not need to change the focus within the form, since it begins at value1. Therefore, you can simplify tests by concatenating key presses together in a single sendKeys() method call, like such:

  1. sendKeys(NUMBER_24 + NUMBER_74 + “ENTER”);

For example, here is the code for the testAddDecimalValues() method, which tests the addition of a decimal value 5.5 with the number 74, which should result in 79.5:

  1. public void testAddDecimalValues() {
  2.        sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + “ENTER”);
  3.        String mathResult = result.getText().toString();
  4.        assertTrue(“Add result should be ” + ADD_DECIMAL_RESULT + ” but was “
  5.                + mathResult, mathResult.equals(ADD_DECIMAL_RESULT));
  6.  }

Similarly, you can perform a test of adding a negative number -22 to the number 74, which should result in a sum of 52. This test is implemented in the testSubtractValues() method, as follows:

  1. public void testAddDecimalValues() {
  2.        sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + “ENTER”);
  3.        String mathResult = result.getText().toString();
  4.        assertTrue(“Add result should be ” + ADD_DECIMAL_RESULT + ” but was “
  5.                + mathResult, mathResult.equals(ADD_DECIMAL_RESULT));
  6.    }

Step 16: Implement a Method to Test SimpleCalc’s Multiplication

It should be quite straightforward to implement a similar test for SimpleCalc’s multiplication called testMuliplyValues().

The only tricky part is that the Multiply Button control is not in focus when we’re done entering the numbers (instead, the Add Button is).
You might think to just call the requestFocus() method on the multiply button. Unfortunately, this won’t work because requestFocus() has to be run on the UI thread in Android. Running methods on the UI Thread can be done as part of a test case, but it’s done asynchronously so you can’t guarantee when it will be complete.

Instead, we’ll again use the sendKeys() method. Since we defined the Multiply Button to always display to the right of the Add Button, we can just send the “DPAD_RIGHT” key followed by “ENTER” to click the Multiply Button.

  1. public void testMultiplyValues() {
  2.    sendKeys(NUMBER_24+NUMBER_74+ ” DPAD_RIGHT ENTER”);
  3.    String mathResult = result.getText().toString();
  4.    assertTrue(“Multiply result should be ” + MULTIPLY_RESULT + ” but was “
  5.            + mathResult, mathResult.equals(MULTIPLY_RESULT));
  6. }

As an exercise, you might try adding more multiplication tests with various sizes of numbers. Try to engineer a test that might fail with the existing code. Can you guess if each test will be successful or not? (Hint: Look at the type of the variable that the string is being converted to.)

Step 17: Running Unit Tests with the Android Emulator or Device

Unit test frameworks such as the one you’re building are Android applications like any other. They must be installed on the emulator or device you wish to test, along with the application to be tested (in this case, SimpleCalc).

To run the unit tests you have created so far from Eclipse, choose the Debug drop down, then Debug As, then Android JUnit Test. Make sure the file you just created is the active file (shown in the window) as that is the test case that will be launched.

junit testing, Debugging JUnit Test

Step 18: Examining the Test Results

The tests may take some time to complete, especially if the emulator was not already running. When the tests have completed, you should see results similar to those shown here:

Junit Testing Examining the Test Results

You’ll notice that all four of the tests you’ve just created run. Two of them are successful, while two of them have failed. Do you know why they’ve failed? (Fixing these calculation bugs is left as a learning exercise for the reader.)

Besides successful tests and failed tests, errors are also shown. A failure is when a tested for assertion fails. An error, on the other hand, is a thrown exception. Errors can either be untested for edge cases or simply mistakes in the testing code. If you have errors, check your testing code carefully to make sure it is working correctly.

Step 19: Create a Test Case for Screen Display Testing

Unit tests need not be limited to validating core functionality such as the addition and multiplication of values. Tests can also validate whether or not a screen layout is displayed properly.

For example, you might want to validate that all of the layout controls display properly on all target screens. The SimpleCalc’s screen was designed in the layout designer in Eclipse for an 800×480 screen in either landscape or portrait mode, but will it work on other screen sizes and devices? Were we then too specific in our design? Automated testing can tell us the answer to this question very quickly.

To create another test case, right-click on the SimpleCalc.Test package and choose New->JUnit Test Case. Call this new test LayoutTests. Configure this test case much as you did the MathValidation class in Step 8.

Junit testing, Create a Test Case for Screen Display Testing.

Hit Finish.

Step 20: Review and Update the LayoutTests Test Case

The LayoutTests.java test case source file is then created. Modify the class to look like the code listing below, modifying the constructor, retrieving the Button controls and the layout as a whole:

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. import android.view.View;
  4. import android.widget.Button;
  5. import com.mamlambo.article.simplecalc.MainActivity;
  6. import com.mamlambo.article.simplecalc.R;
  7. public class LayoutTests extends ActivityInstrumentationTestCase2<MainActivity> {
  8.    private Button addValues;
  9.    private Button multiplyValues;
  10.    private View mainLayout;
  11.    public LayoutTests() {
  12.        super(“com.mamlambo.article.simplecalc”, MainActivity.class);
  13.    }
  14.    protected void setUp() throws Exception {
  15.        super.setUp();
  16.        MainActivity mainActivity = getActivity();
  17.        addValues = (Button) mainActivity.findViewById(R.id.addValues);
  18.        multiplyValues = (Button) mainActivity
  19.                .findViewById(R.id.multiplyValues);
  20.        mainLayout = (View) mainActivity.findViewById(R.id.mainLayout);
  21.    }
  22. }
Now let’s implement some specific tests for LayoutTests.

Step 20: Consider Layout Tests for the SimpleCalc Application
Now that everything is set up, what tests do you want to perform? One common bug in application design is for controls not to display properly in all screen sizes and orientations. Therefore, it makes sense to try to build a test case to verify the location of certain controls. You can then add other checks to make sure other View controls display and behave appropriately.

Step 21: Implement a Method to Test Button Display

Let’s begin by testing that the Add Button control of the SimpleCalc screen is visible. To do this, add a method called testAddButtonOnScreen() to the LayoutTests class.

This test checks to see if the Add Button control is displayed within the visible rectangle representing the overall screen size.

To implement the testAddButtonOnScreen() method, you must first determine the screen size. There are a number of ways to do this. One simple way is to retrieve the View that represents the entire screen layout and use the getWidth() and getHeight() methods. Doing this also takes in to account any screen real estate being used by other items, such as the title bar or information bar that are often at the top of an Android screen.

Determining whether or not the Add Button control is drawn within those bounds is as simple as comparing the layout bounds to the bounds of the drawing rectangle for the Add Button control.

Here is the full listing of the testAddButtonOnScreen() method:

  1. public void testAddButtonOnScreen() {
  2.    int fullWidth = mainLayout.getWidth();
  3.    int fullHeight = mainLayout.getHeight();
  4.    int[] mainLayoutLocation = new int[2];
  5.    mainLayout.getLocationOnScreen(mainLayoutLocation);
  6.    int[] viewLocation = new int[2];
  7.    addValues.getLocationOnScreen(viewLocation);
  8.    Rect outRect = new Rect();
  9.    addValues.getDrawingRect(outRect);
  10.    assertTrue(“Add button off the right of the screen”, fullWidth
  11.            + mainLayoutLocation[0] > outRect.width() + viewLocation[0]);
  12.    assertTrue(“Add button off the bottom of the screen”, fullHeight
  13.            + mainLayoutLocation[1] > outRect.height() + viewLocation[1]);
  14. }

At this point, you can see how you could also test the display of the Multiply Button, or the Result text, or any other control on the SimpleCalc screen.

Step 22: Running the LayoutTests Test Case

In order for layout testing to provide useful results, we can’t just run the test once. Instead, the tests must be run on multiple emulator configurations and screen orientations. This is different from the logic tests of above where a messy layout or a layout that doesn’t match the design pattern doesn’t necessarily impede functionality.

For example, if you create emulator configurations (using AVDs) for the following configurations, the LayoutTests test case will yield the following results:

  1. 480×800, portrait mode (will pass)
  2. 800×480, landscape mode (will fail)
  3. 320×480, portrait mode (will fail)
  4. 480×320, landscape (will fail)
  5. 480×854, portrait mode (will pass)
  6. 854×480, landscape mode (will fail)

 Can you figure out why it fails in all landscape modes, but draws fine in the creator for the landscape mode (#2 above)?

Can you figure out why it fails in all landscape modes, but draws fine in the creator for the landscape mode (#2 above)?

Hint: What’s shown on the screen when the application actually runs (see the figure below)?

JUnit Testing Sample

Step 23: Where to Go From Here

Now that you have some tests in place—some of which pass and some of which fail—you can imagine how unit testing can improve the quality of your application.

The more thorough you are with your unit testing coverage, the better. You’ve seen how unit testing can uncover bugs in code and layout designs. The next step would be to identify the failure points and fix those bugs. Once you’ve fixed the bugs, you should re-run the unit tests to ensure that they pass in all test cases.

Conclusion

In this tutorial, you learned how to create unit tests using the Android JUnit framework for your Android projects. You also learned how to create different kinds of unit tests to test a variety of application features, including underlying program functions as well as display characteristics.

English: GPS navigation solution running on a ...

Image via Wikipedia

English: Screenshot of Android Froyo 2.2 runni...

Image via Wikipedia

Google Map Maker

Image via Wikipedia

Android Location API and Google Maps

This tutorial describes the usage of the Android Location API, the usage of Google Maps and the Geolocation API. It is based on Eclipse 3.7, Java 1.6 and Android 4.0 (Ice Cream Sandwich) (Gingerbread).

1. Android Basics

The following assumes that you have already basic knowledge in Android development. Please check the Android development tutorial for the basics.

2. Android Location API

2.1. Android Location API

Most Android devices allow to determine the current geolocation. This can be done via a GPS (Global Positioning System) device, via cell tower triangulation or via wifi networks for which the geolocation is known. Android contains the android.location package which provides the API to determine the current geo position.

The LocationManager provides access to the Android location service. This services allows to access location providers, to register location update listeners and proximity alerts and more.

The LocationProvider class provides location data via the Location class. The LocationProvider class is the superclass of the different location providers which deliver the information about the current location.

The Android device might have several LocationProvider available and you can select one of them. For a flexible selection of the best location provider use a Criteria object in which you can define how the provider should be selected.

You can register a LocationListener object with the LocationManager class to receive periodic updates about the geoposition.

You can also register an Intent which allows to define a proximity alert, this alert will be triggered if the device enters a area given by a longitude, latitude and radius (proximity alert).

2.2. Forward and reverse Geocoding

The Geocoder class allows to determine the geo-coordinates (longitude, laditude) for a given address and possible addresses for given geo-coordinates.

This process is known as forward and reverse geocoding.

2.3. Security

If you want to access the GSP then you need the ACCESS_FINE_LOCATION permission. Otherwise you need the ACCESS_COARSE_LOCATION.

2.4. Setting the geoposition

You can use the “DDMS” Perspective of Eclipse to send your geoposition to the emulator or a connected device. For open this Perspective select Window → Open Perspective → Other → DDMS.

In the Emulator Control part you can enter the geocoordinates and press “Send.”

You can als set the geoposition the Android emulator via telnet. Open a console and connect to your device. The port number of your device can be seen in the title area of your emulator.

				
telnet localhost 5554

Set the position via the following command.

				
geo fix 13.24 52.31

3. How to check if the LocationProvider is available

You can find out if a LocationManager is enabled via the isProviderEnabled() method. If its not enabled you can send the user to the settings via an Intent with the Settings.ACTION_LOCATION_SOURCE_SETTINGS action for the android.provider.Settings class.

			
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
	.isProviderEnabled(LocationManager.GPS_PROVIDER);

// Check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to 
// go to the settings
if (!enabled) {
  Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
	startActivity(intent);
}

Typically you would open an AlarmDialog prompt the user and if he wants to enable GPS or if the application should be canceled.

You cannot enable the GPS directly in your code, the user has to do this.

4. Activating the GPS module on the device

You need to activate GPS on your test device. If you test on the emulator and its not activated you “null” if you try to use a LocationManager.

The Google Map Activity should automatically activate the GPS device in the emulator but if you want to use the location manager directly you need to do this yourself. Currently their seems to be an issue with this.

Start Google Maps on the emulator and request the current geo-position, this will allow you to activate the GPS. Send new GPS coordinates to the Android emulator.

5. Tutorial: Using the Android Location API

Create a new project called “de.vogella.android.locationapi.simple” with the Activity called “ShowLocationActivity”.

This example will not use the Google Map therefore is also runs on an Android device.

Change your “main.xml” layout file from the “res/layout” folder to the following:

				
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dip"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Latitude: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView03"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="5dip"
            android:text="Longitute: "
            android:textSize="20dip" >
        </TextView>

        <TextView
            android:id="@+id/TextView04"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="unknown"
            android:textSize="20dip" >
        </TextView>
    </LinearLayout>

</LinearLayout>

5.2. Add permissions

Add the following permissions to your application in your “AndroidManifest.xml” file

  • INTERNET
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

5.3. Activity

Change ShowLocationActivity to the following. It queries the location manager and display the queried values in the activity.

package de.vogella.android.locationsapi.simple;

import android.app.Activity;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class ShowLocationActivity extends Activity implements LocationListener {
	private TextView latituteField;
	private TextView longitudeField;
	private LocationManager locationManager;
	private String provider;
/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		latituteField = (TextView) findViewById(R.id.TextView02);
		longitudeField = (TextView) findViewById(R.id.TextView04);

		// Get the location manager
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the locatioin provider -> use
		// default
		Criteria criteria = new Criteria();
		provider = locationManager.getBestProvider(criteria, false);
		Location location = locationManager.getLastKnownLocation(provider);

		// Initialize the location fields
		if (location != null) {
			System.out.println("Provider " + provider + " has been selected.");
			int lat = (int) (location.getLatitude());
			int lng = (int) (location.getLongitude());
			latituteField.setText(String.valueOf(lat));
			longitudeField.setText(String.valueOf(lng));
		} else {
			latituteField.setText("Provider not available");
			longitudeField.setText("Provider not available");
		}
	}

	/* Request updates at startup */
	@Override
	protected void onResume() {
		super.onResume();
		locationManager.requestLocationUpdates(provider, 400, 1, this);
	}

	/* Remove the locationlistener updates when Activity is paused */
	@Override
	protected void onPause() {
		super.onPause();
		locationManager.removeUpdates(this);
	}

	@Override
	public void onLocationChanged(Location location) {
		int lat = (int) (location.getLatitude());
		int lng = (int) (location.getLongitude());
		latituteField.setText(String.valueOf(lat));
		longitudeField.setText(String.valueOf(lng));
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		Toast.makeText(this, "Enabled new provider " + provider,
				Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onProviderDisabled(String provider) {
		Toast.makeText(this, "Disabled provider " + provider,
				Toast.LENGTH_SHORT).show();
	}
}

5.4. Run and Test

If you using the emulator send some geo-coordinates to your device. These geo-coordinate should be displayed as soon as you press the button.

6. Google Maps

6.1. MapsView

Google provides via the com.google.android.maps package a library for using the MapView in your application. You require an additional key to use them. This key will be specified in the View which displays the map.

You need to add the following uses-library statement to your AndroidManifest.xml file. The project creation wizard does this automatically if you select a Google API version.

				
<uses-library android:required="true" android:name="com.google.android.maps"></uses-library>

The usage of MapView requires the permission to access the Internet, as the data displayed in the MapView is downloaded from the Internet.

6.2. MapsActivity

The MapActivity class extends the Activity class and provides the life-cycle management and the services for displaying a MapView widget.

MapActivity simplify the handling MapViews similar to ListActivity simplifies the usage of ListViews.

A MapView is typically defined in the XML layout file used by the MapActivity and requires the API key in the “android:apiKey” attribute. A MapView can be used with other user interface components in the same layout.

The MapController class can be used to interact with the MapView, e.g. by moving it. A Geopoint is a position described via latitude and longitude.

6.3. OverlayItem

You can also draw OverlayItem on the map. These are typical graphics which you want to display on the map.

6.4. maps library usage declaration

You must declare that your application uses the com.google.android.maps library in the application of your AndroidManifest.xml file. Please note that the usage declaration must be in the application tag otherwise you get java.lang.ClassNotFoundException for your Activity.

				
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.vogella.android.locationapi.maps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps" >
        </uses-library>

        <activity
            android:name="MapViewDemo"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

7. Device with Google API

In case you want to use Google Maps in your emulator you have to create a device which supports the Google API’s. This requires that you also install the “Google API”. During device creation select the target Google API’s in the version of your SDK.

8. Google Map key

To use Google Maps you need an additional key. See for following description:

			
http://code.google.com/android/add-ons/google-apis/mapkey.html

This process is a little bit time consuming and involves creating a value on the command line. This values is needed as input for a website which allow to create the key.

9. Google Maps

9.1. Create Project

Create a new Android project called “de.vogella.android.locationapi.maps” with an Activity called “ShowMapActivity”. Make sure to select the “Google API” als Target.

Add the following permissions to your application.

  • INTERNET
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

9.2. Google Map library

You need to add the Google maps library to your application. Add “uses library” to “AndroidManifest.xml”.

				
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.vogella.android.locationapi.maps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps" >
        </uses-library>

        <activity
            android:name="MapViewDemo"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

9.3. Overlays

Create the following class. We will later use an image called “point”. But one icon with this name in your drawable folders.

				
package de.vogella.android.locationapi.maps;

import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class MyOverlays extends ItemizedOverlay<OverlayItem> {

	private static int maxNum = 3;
	private OverlayItem overlays[] = new OverlayItem[maxNum];
	private int index = 0;
	private boolean full = false;
	private MyOverlays itemizedoverlay;

	public MyOverlays(Drawable defaultMarker) {
		super(boundCenterBottom(defaultMarker));
	}

	@Override
	protected OverlayItem createItem(int i) {
		return overlays[i];
	}

	@Override
	public int size() {
		if (full) {
			return overlays.length;
		} else {
			return index;
		}

	}

	public void addOverlay(OverlayItem overlay) {
		if (index < maxNum) {
			overlays[index] = overlay;
		} else {
			index = 0;
			full = true;
			overlays[index] = overlay;
		}
		index++;
		populate();
	}

}

9.4. Layout

The next step requires that you have created a valid key for using the MapView widget.

Change the “main.xml” layout file in your “res/layout” folder to the following. and replace “Your Maps API Key” with your Google Maps API key.

				
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <com.google.android.maps.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:apiKey="Your Maps API Key"
        android:clickable="true" />

</RelativeLayout>

9.5. Activity

Change your Activity to the following. This Activity use an LocationListner to update the MapView with the current location.

				
package de.vogella.android.locationapi.maps;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.LinearLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class ShowMapActivity extends MapActivity {

	private MapController mapController;
	private MapView mapView;
	private LocationManager locationManager;
	private MyOverlays itemizedoverlay;

	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		setContentView(R.layout.main); // bind the layout to the activity

		// create a map view
		LinearLayout linearLayout = (LinearLayout) findViewById(R.id.main);
		mapView = (MapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setStreetView(true);
		mapController = mapView.getController();
		mapController.setZoom(14); // Zoon 1 is world view
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
				0, new GeoUpdateHandler());

		Drawable drawable = this.getResources().getDrawable(R.drawable.point);
		itemizedoverlay = new MyOverlays(drawable);
		createMarker();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	public class GeoUpdateHandler implements LocationListener {

		@Override
		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			GeoPoint point = new GeoPoint(lat, lng);
			createMarker();
			mapController.animateTo(point); // mapController.setCenter(point);

		}		@Override
		public void onProviderDisabled(String provider) {
		}		@Override
		public void onProviderEnabled(String provider) {
		}		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}	private void createMarker() {
		GeoPoint p = mapView.getMapCenter();
		OverlayItem overlayitem = new OverlayItem(p, "", "");
		itemizedoverlay.addOverlay(overlayitem);
		mapView.getOverlays().add(itemizedoverlay);
	}
}

9.6. Run and Test

Run and test your application. You should be able to zoom in and out and send new geocoordinates to your map via the Emulator .

It will also draw Overlays on the Map.

10. Thank you