Wednesday, May 27, 2009

HTTP GET and POST Thread Service on Android

HttpService.java
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;

public class HttpService implements Runnable {

private static final String TAG = "HttpService";
public static final int GET = 0;
public static final int POST = 1;
public static final String HTTP_RESPONSE = "HTTP_RESPONSE";

private Activity activity;
private Intent intent;
private int requestCode;
private String url;
private int getOrPost = 0;
private List<NameValuePair> nameValuePairs;
private boolean handleByMe;

/*
* for example:
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("aaa", "bbb"));
nameValuePairs.add(new BasicNameValuePair("ccc", "ddd"));
*/
public HttpService(Activity activity, Intent intent, int requestCode, String url, int getOrPost, List<NameValuePair> nameValuePairs, boolean handleByMe){
this.activity = activity;
this.intent = intent;
this.requestCode = requestCode;
this.url = url;
this.getOrPost = getOrPost;
this.nameValuePairs = nameValuePairs;
this.handleByMe = handleByMe;
}

public void start(){
Thread thread = new Thread(this);
try{
thread.start();
}catch(IllegalThreadStateException itse){
Log.e(TAG, "The Thread has been started before.", itse);
}
}

public void run() {
doRequest();
}

public void doRequest(){
HttpClient httpclient = new DefaultHttpClient();
HttpRequestBase httpRequest = null;
HttpResponse httpResponse = null;
InputStream inputStream = null;
String response = "";
StringBuffer buffer = new StringBuffer();

if(POST == getOrPost){
httpRequest = new HttpPost(url);
try {
((HttpPost)httpRequest).setEntity(new UrlEncodedFormEntity(nameValuePairs));
} catch (UnsupportedEncodingException usee) {
Log.e(TAG, "Could not encode the nameVaulePairs.", usee);
}
}else{
httpRequest = new HttpGet(url);
}
if(httpRequest != null){
try{
httpResponse = httpclient.execute(httpRequest);
inputStream = httpResponse.getEntity().getContent();
int contentLength = (int) httpResponse.getEntity().getContentLength();
if (contentLength < 0){
Log.e(TAG, "The HTTP response is too long.");
}
byte[] data = new byte[256];
int len = 0;
while (-1 != (len = inputStream.read(data)) )
{
buffer.append(new String(data, 0, len));
}
inputStream.close();
}catch (ClientProtocolException cpe) {
Log.e(TAG, "Http protocol error occured.", cpe);
}catch (IllegalStateException ise) {
Log.e(TAG, "Could not get a HTTP response from the server.", ise);
}catch (IOException ioe) {
Log.e(TAG, "Could not establish a HTTP connection to the server or could not get a response properly from the server.", ioe);
}
}
response = buffer.toString();
intent.putExtra(HTTP_RESPONSE, response);

if(handleByMe){
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
activity.startActivity(intent);
}else{
activity.startActivityForResult(intent, requestCode);
}
}

}



How to use it?
Intent intent = new Intent(this, SkeletonActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
HttpService httpService = new HttpService(this, intent, 0, "http://www.google.com", 0, null, true);
httpService.start();


protected void onNewIntent(Intent intent) {
String message = intent.getStringExtra(HttpService.HTTP_RESPONSE);
editor.setText(message);
}

Tuesday, May 26, 2009

GenericDAO for Android SQLite

GenericDAO.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class GenericDAO extends SQLiteOpenHelper {

private static final String TAG = "GenericDAO";
private static SQLiteDatabase db;
private static String dName;
private static String tName;
private static String sql;
public static final String KEY_ID = "_id";

private static GenericDAO instance;

private GenericDAO(Context ctx, String dbName, String sql, String tableName, int ver){
super(ctx, dbName, null, ver);
Log.i(TAG, "Creating or opening database [ " + dbName + " ].");
GenericDAO.sql = sql;
dName = dbName;
tName = tableName;
}

public static GenericDAO getInstance(Context ctx, String dbName, String sql, String tableName, int ver){
if(instance == null){
instance = new GenericDAO(ctx, dbName, sql, tableName, ver);
try{
Log.i(TAG, "Creating or opening the database [ " + dbName + " ].");
db = instance.getWritableDatabase();
}catch(SQLiteException se){
Log.e(TAG, "Cound not create and/or open the database [ " + dbName + " ] that will be used for reading and writing.", se);
}
}
return instance;
}

public void close(){
if(instance != null){
Log.i(TAG, "Closing the database [ " + dName + " ].");
db.close();
instance = null;
}
}

@Override
public void onCreate(SQLiteDatabase db){
Log.i(TAG, "Trying to create database table if it isn't existed [ " + sql + " ].");
try{
db.execSQL(sql);
}catch(SQLException se){
Log.e(TAG, "Cound not create the database table according to the SQL statement [ " + sql + " ].", se);
}
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
Log.i(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
try{
db.execSQL("DROP TABLE IF EXISTS " + tName);
}catch(SQLException se){
Log.e(TAG, "Cound not drop the database table [ " + tName + " ].", se);
}
onCreate(db);
}

public long insert(String table, ContentValues values){
return db.insert(table, null, values);
}

public Cursor get(String table, String[] columns){
return db.query(table, columns, null, null, null, null, null);
}

public Cursor get(String table, String[] columns, long id){
Cursor cursor =db.query(true, table, columns, KEY_ID + "=" + id, null, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}

public int delete(String table) {
return db.delete(table, "1", null);
}

public int delete(String table, long id) {
return db.delete(table, KEY_ID + "=" + id, null);
}

public int update(String table, long id, ContentValues values) {
return db.update(table, values, KEY_ID + "=" + id, null);
}
}



How to use it?
Notes.java
public class Notes {

public static final String DATABASE_NAME = "data";
public static final String DATABASE_TABLE = "notes";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_CREATE =
"create table notes (_id integer primary key autoincrement, "
+ "title text not null, body text not null);";

public static final String COL_TITLE = "title";
public static final String COL_BODY = "body";

private int id;
private String title;
private String body;

public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getBody() {
return body;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setBody(String body) {
this.body = body;
}


}



    private String testCRUD(){

String result="";
Cursor cursor = null;
String[] columns = new String[] {GenericDAO.KEY_ID, Notes.COL_TITLE, Notes.COL_BODY};

GenericDAO dao = GenericDAO.getInstance(this, Notes.DATABASE_NAME, Notes.TABLE_CREATE, Notes.DATABASE_TABLE, Notes.DATABASE_VERSION);

if(dao != null){

ContentValues values = new ContentValues();
values.put(Notes.COL_TITLE, "aaa");
values.put(Notes.COL_BODY, "bbb");
dao.insert(Notes.DATABASE_TABLE, values);

values = new ContentValues();
values.put(Notes.COL_TITLE, "ccc");
values.put(Notes.COL_BODY, "ddd");
dao.insert(Notes.DATABASE_TABLE, values);

cursor = dao.get(Notes.DATABASE_TABLE, columns);


int idColumn = cursor.getColumnIndex(GenericDAO.KEY_ID);
int titleColumn = cursor.getColumnIndex(Notes.COL_TITLE);
int bodyColumn = cursor.getColumnIndex(Notes.COL_BODY);

if(cursor != null){
if(cursor.moveToFirst()){

int count = cursor.getCount();
result = "there are " + count + " records.";
List<Notes> list = new ArrayList<Notes>();

for(int i=0; i<count; i++){

int id = cursor.getInt(idColumn);
String title = cursor.getString(titleColumn);
String body = cursor.getString(bodyColumn);

Notes notes = new Notes();
notes.setId(id);
notes.setTitle(title);
notes.setBody(body);

list.add(notes);

result += " " + i + ": " + "id=" + id + ", title=" + title + ", body=" + body + ";";

cursor.moveToNext();
}
}
}

result += " now update the second record.";

values = new ContentValues();
values.put(Notes.COL_TITLE, "eee");
values.put(Notes.COL_BODY, "fff");
dao.update(Notes.DATABASE_TABLE, 2, values);

cursor.requery();
cursor.close();

result += " now delete first record.";

dao.delete(Notes.DATABASE_TABLE, 1);

result += " now delete all records.";

dao.delete(Notes.DATABASE_TABLE);

dao.close();
}

return result;
}


Sunday, May 17, 2009

How to Fix "Failed to find an AVD compatible with target" on Android

"Failed to find an AVD compatible with target"
cd ANDROID_HOME/tools/
android create avd -n android1.1 -t 1
android create avd -n android1.5 -t 2
android create avd -n goolgeapi -t 3

Date Between Syntax Bug from MS SQL Server 2005?

1. select TradeDate from test where TradeDate between '2009-05-13 00:00:00.000' and '2009-05-13 23:59:59.999'
result:
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
(5 row(s) affected)


2. select TradeDate from test where TradeDate between '2009-05-13 00:00:00.000' and '2009-05-13 23:59:59.998'
result:
(0 row(s) affected)


3. select TradeDate from test where TradeDate between '2009-05-13 00:00:00.000' and '2009-05-14 00:00:00.000'
result:
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
2009-05-14 00:00:00.000
(5 row(s) affected)

Friday, May 15, 2009

A Solution for Equals and HashCode Method of Hibernate Domain Ojbect

Issue:

Solution:
every domain object extends the following object.
public abstract class BaseObject {

private String uuid = UUID.randomUUID().toString();

public String getUuid() {
return uuid;
}

public void setUuid(String uuid) {
this.uuid = uuid;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final BaseObject other = (BaseObject) obj;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
}

Thursday, May 14, 2009

Sample of Hibernate Annotation on Entity Bean Associations/Relationships

1. one-one
@Entity
public class Body {
@Id
public Long getId() { return id; }

@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {
return heart;
}
...
}

@Entity
public class Heart {
@Id
public Long getId() { ...}
}


@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
...
}

@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}


2. many-one
    @ManyToOne(fetch = FetchType.EAGER)
@org.hibernate.annotations.Cascade(value={org.hibernate.annotations.CascadeType.SAVE_UPDATE})
@JoinColumn(name = "SecurityID")
public SecurityMaster getSecurity()
{
return this.security;
}



3. one-many
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "transactionId")
@OrderBy("transactionTaxlotId asc")
public Set<TransactionTaxlot> getTransactionTaxlots() {
return transactionTaxlots;
}



4. many-many
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "trelTrader",
joinColumns = {
@JoinColumn(name="traderId", unique = true)
},
inverseJoinColumns = {
@JoinColumn(name="fundId")
}
)
public Set<Fund> getFunds() {
return this.funds;
}

Wednesday, May 6, 2009

Cascade Attribute in Hibernate

none
ignore the association.
save-update
navigate the association when the transaction is committed and when an object is passed to save() or update() and save newly instantiated transient instances and persist changes to detached instances.
delete
navigate the association and delete persistent instances when an object is passed to delete().
all
cascade both save-update and delete as well as calls to evict and lock.
all-delete-orphan
the same as cascade "all" but in addition deletes any persistent entity instance that has been removed (dereferenced) from the association (for example from a collection).
delete-orphan
delete any persistent entity instance that has been removed (dereferenced) from the association (for example from a collection).

Tuesday, May 5, 2009

Performance Competition Within Hibernate Query Methods

Table or Object Struct:
    private Integer    historyId;
private Integer accountId;
private Date historyDate;
private Double units;
private Double sharePrice;
private Double amount;
private Integer createId;
private Date createDate;



Rows in the Table:
40797


Performance Competition (time unit is ms) :



conclusion:

findByNamedQuery(namedQuery) > createCriteria(clazz).list() > loadAll(clazz) > createSQLQuery(sqlString).addEntity(clazz).list(), but basically they are in the one level.