Saturday, June 25, 2011

Write your DateConverter for Struts2




I didn't see Struts2 provide a good DateConverter implementation, so I wrote my own. It also use ResourceBundle to work with i18n requirements. Below is my DateConverter.java, and don't forget to add your own package path.

import java.text.ParseException;
import java.util.Date;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.struts2.util.StrutsTypeConverter;

import util.DateUtil;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;


public class DateConverter extends StrutsTypeConverter {
  
  private static Logger LOG = LoggerFactory.getLogger(DateConverter.class);
  
  @Override
  /**
   * Converts one or more String values to the specified class.
   *
   * @param context the action context
   * @param values  the String values to be converted, such as those submitted from an HTML form
   * @param toClass the class to convert to
   * @return the converted object
   */
  public Object convertFromString(Map context, String[] values, Class toClass) {
    
    Date returnObject = null;
    String value = values[0];
    if (value != null && !value.trim().equals("")) {
      try {
        returnObject = DateUtil.parseDate(value, getDatePattern());
      } catch (ParseException e) {
        // Just to ignore the parse exception
      }
    }
    return returnObject;
  }

  @Override
  /**
   * Converts the specified object to a String.
   *
   * @param context the action context
   * @param o       the object to be converted
   * @return the converted String
   */
  public String convertToString(Map context, Object o) {
    
    Date date = (Date) o;
    String formatedDate = DateUtil.dateFormater(date, getDatePattern());
    return formatedDate;
  }
  
  private String getDatePattern() {
    
    ResourceBundle bundle = ResourceBundle.getBundle("package", ActionContext.getContext().getLocale());
    String pattern = bundle.getString("text.date.format");
    //LOG.info("current date pattern is:" + pattern);
    return pattern;
  }
}

Please don't forget to add "xwork-conversion.properties" and "package.properties" at your source folder root.
"xwork-conversion.properties" content should be

java.util.Date = DateConverter


"package.properties" content should be
text.date.format=MM/dd/yyyy
or other format pattern for different locale. For example package_zh_TW.properties or package_ja_JP.properties.
With this DateConverter, you can see different Date conversion result for your locale setting.




Friday, January 21, 2011

Next trend - Android in cars

I really recommend that car manufacturers should consider adding mobile phone dock in cars, so that mobile phones can be provided with unlimited electricity and stand firmly on the panel.


Since Google phones provide better and better GPS navigation, in order to let these electricity consuming monsters work as long as possible, mobile phone dock should be considered as regular equipment in cars. Furthermore, in the future, I bet there will soon be some system communication interfaces that come along with these smart phone docks, so that iPhone or Android phone developers can use these API to communicate with cars - no matter the car status or identification, to prevent unauthorized driving.

Recently I saw a Benz car interior photo. There was a computer screen showing Google search portal. I don't know what operating system it was running, maybe Android or Linux. No matter what it was, I believe there will soon be some application markets targeted for in-car-use. And that's what I am engaged in.

Soon in the early summer, I will release my first version of car tracking system. Please stay tuned and I will update at any time :-)

Sunday, January 02, 2011

Root HTC Magic and install new ROM easily

Thanks to these guys's efforts, so I can root my HTC-Magic with few pains.
(Steps below only fits to HTC Magic 32A edition)

1. I strongly recommend making "golden card" by using Mac, trust me, it is really easy to make it. Here is the article to make "golden card" on Mac.
  • http://bloggadgets.web.id/techno-blog/how-to-create-a-goldcard-with-mac-or-linux-for-rooting-ht-03a.html
If you have installed Android SDK on your Mac, you can just begin from section "Create a goldcard image file"

2. Then switch to Windows platform, because we have to install a RUU update file below.
RUU_Sapphire_HTC_Europe_3.04.401.2_HTC_AT_test_signed_NoDriver.exe
Please download it(You can find it in http://shipped-roms.com/), make sure HTC sync is connected to your HTC Magic, then you can run the .exe file above to install RUU.
After install European version of RUU. Your HTC Magic will reboot automatically, it needs longer boot time than usual, please be patient. Now you have totally rooted HTC Magic.

-- If you are satisfied with rooted HTC official ROM, you can stopped here. But why we root? It is because we like new stuff and adventure! Please go further steps --

3. After reboot completed, please mount it to your Mac, copy
  • recovery-RA-hero-v1.6.2.img
  • update-hboot-1762007-signed.zip
into your mobile device sdcard. Then unmount USB mode, keep USB line plugged.

4. Open your shell, change directory to /platform-tools.
In shell window, type
./adb devices
to make sure Android Debug Bridge connect to your device. Please be aware that if you install "EasyTether" on your Mac, it will cause adb not to list devices, you can follow the FAQ here to solve this problem: http://www.mobile-stream.com/easytether/android_faq.html#adbmacosx

5. Next type
flash_image recovery /sdcard/recovery-RA-hero-v1.6.2.img
to flash new recovery. It completes quickly, then shutdown mobile device.

6. Press power + home button together to boot into recovery mode. Scroll menu to "Flash zip from sdcard", press navigation ball to show zip file list. Now you can see the other file "update-hboot-1762007-signed.zip" shown on the list. Press navigation ball to install it, follow instruction shown on screen to complete installation.

7. Shut down and press "power" + "volume down" button, reboot into fastboot mode. You should the following version info:
SAPPHIRE PVT 32A ENG S-OFF H
HBOOT-1.76-2007 (SAPP10000)
CPLD-12
RADIO-6.35.08.29
(Font in red color is what you need to pay attention to)

-- Milestone notice: After this you can install any ROM you like, good luck. --

8. Now my HTC-Magic runs Cyanogen MOD v.6, it is my recommendation for you.
But it needs quite a few more complicated steps to install it, you can refer to
http://wiki.cyanogenmod.com/index.php?title=HTC_Magic for more details.

Please follow introductions above to install new ROM. As a MAC user, it is important to have "fastboot", but it is not shipped with Android SDK. You can download it from http://developer.htc.com/adp.html#s1
This will help you a lot during the procedures.

Friday, December 21, 2007

Two most fast ways to set up SubVersion server

Here I would like to introduce two quick instructions to set up Subversion server, this is for people who can't wait to set up and using Subversion. But in order to use Subversion correctly, I still strongly recommend people to study Subversion books in detail.

I. Set up Subversion server running over svn:// protocol

  1. After you install Subversion, open shell, change directory to subversion's /bin folder.
  2. Type svnadmin create <Your Resporitory Path>

    For example: svnadmin create /home/svn-repos
  3. Then Subversion will create necessary files into repository folder.
  4. Change directory to repository, you will find "svnserve.conf" and "passwd" two files under "{repository-root}/conf" folder.
  5. First to open "svnserve.conf" file, you can just clean all of the default content, and just put the following content into that file.

    [general]

    anon-access=none

    password-db=passwd

  6. After that, open "passwd" file. Follow the syntax below to add user name and password.

    [users]

    user1=password1

    user2=password2

  7. Finally, start Subversion server.

    Change directory back to subversion's bin folder, execute svnserve -d -r <Your Repository Path>
  8. Now you can start to commit and update source with your team members.



II. Set up SubVersion server running over http:// protocol
<This part will be added soon....>

Monday, October 29, 2007

A Linked List Sorter


About sorting LinkedList, I just implemented a sotrer class two weeks ago because I was asked how to sort a linked list. I tried to write a Java class to sort LinkedList.
Here is my implementation, just for everyone reference, and please advise if any mistake.

Suppose we have a data structure just as below, upper part display origional position, we have to sort out a sequence as lower part.
(Element has null parent ID means it is the first/top one)


First of all, I define an Interface as below:

public interface SortingElement {

Long getId();
Long getParentId();
void setParentId(Long parentId);

}

A sorting element is composed of two value, one is my id, the other is the id which I am linking to (that means parentId). So we have getId() and a pair of setter and getter for parentId.

Following is the LinkedListSorter class:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class Sorter {

public static List sort(List elements) {

List rs = new ArrayList();
Map temp = new HashMap();
SortingElement currentElement = null;
for (SortingElement element : elements) {
Long parentId = element.getParentId();
if (parentId != null)
temp.put(element.getParentId(), element);
else
currentElement = element;
}

for (int i=0; i<elements.size(); i++) {
Long childParentId = currentElement.getId();
SortingElement child = temp.get(childParentId);
rs.add(currentElement);
currentElement = child;
}
return rs;
}
}


Before passing List of SortingElement into sorter, we have a pre-condition has to be satisfied, that is only one element can return a null parent id, it means it sits at the top of these elements, others elements must contain its parent id.

Gets into the method, first of all these parent Id value of each elements are extracted out, they are put into a Map which using parent Id as key and element itsself as value.

Then a List is used to sequentially retrieve element from Map according each elements parent Id.

I didn't test its efficiency, but at least it seems works up to now by my test case. Attached is the test Java class, just for you are interested in it.

Tuesday, October 02, 2007

Study note: how the limitless nonvolatile memory will affect the future of world

I am studying the MSc of IT programme in Liverpool University. This week we discussed how the limitless nonvolatile memory will affect the future of world.


Below is the discussion summary of what I wrote to forum wtoday:


Hi All,

Super large but cheap storage device is not a dream in the coming future, but to keep the stored data organized is also the necessary thing we have to bear in mind. I think the problem is not how large of the storage capacity, it is because we misuse the large storage device, and the lack of softwares to help organize the large amount of documents, photos or binary files.

Vee mentioned a key point of these large amount of documents or images - metadata. Everyone knows the concept of web 2.0. It is a popular marketing phrase we can see in the Internet. If we can't organize data well, even 10MB data we could mess it up. Web 2.0 emphasize the interaction among Internet users, people contribute everything into many kinds of web 2.0 model web site, e.g. Del.icio.us, Flicker. Everytime you bookmark or upload something, you have to give metadata to your documents or photos, thus the sofrware, might be a search engine or something like that, behind the user interface can start to analyze the new uploaded document, and associate these data by many kinds of algorism. I would say that the 20th century is the era of data collecting century; and the 21th century is the era of data manipulating. So many ERP systems were built in the last century, these data are collected large enough to start predicting trends, analyzing behavior or something else. Thus who owns the most powerful search engine or analyzing algorism, who will lead the business of 21th century. So a stong back bone hardware to support these large raw data or results is the same important.

A reliable, fast, large, and reasonable price sotrage device is the foundation to support the everything above make make true in the future.

Thursday, May 10, 2007

An easy way to remove blank page generated by JasperReports

If your JasperReports report has one more sub-reports and it was generated as PDF file. In some circumstances, a blank page might be found within PDF file. Here is my solution to easily remove it.

private void removeBlankPage(List<JRPrintPage> pages) {

for (Iterator<JRPrintPage> i=pages.iterator(); i.hasNext();) {
JRPrintPage page = i.next();
if (page.getElements().size() == 0)
i.remove();
}
}

This method should be called before you flush your JasperPrint instance to PDF.

Followed with the sample code, it would be better to know the object hierarchy of JasperPrint.

  1. 1. A JasperPrint has one or more JRPrintPage, you can get it via getPages() method of JasperPrint. It returns a List of JRPrintPage. If you have three elements, then your printer will print 3 pages.
  2. 2. A JRPrintPage has one ore more JRPrintElement, each element might be a string of text, or a picture, or a rectangle, etc. You can change its position or content dynamically, or even add new JRPrintElement into JRPrintPage.