Total Pageviews

2016/09/30

[Travel] 台東

多良車站
DSC00487

鹿野高台
DSC00499


台東太麻里海岸線
DSC00573


台東金針山
DSC00587

DSC00588

DSC00587


台東縣小野柳風景區
DSC00609


台東藝術鐵花村
DSC00646

DSC00650


太麻里 第一道曙光紀念公園
DSC00675


利吉惡地
DSC00699

2016/09/09

[Java] try-with-resources statement

JDK 7 introduces a new version of try statement known as try-with-resources statement. This feature add another way to exception handling with resources management,it is also referred to as automatic resource management.

If this class implements AutoClossable interface, then you can make good use of  try-with-resources statement. Do not need to close manually.
e

As-is (does not apply try-with-resources statement)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
  FileOutputStream outputStream = null;
  File tmpFile = null;
  try {
      tmpFile = File.createTempFile("issue", ".xls");
      outputStream = new FileOutputStream(tmpFile);
      workbook.write(outputStream);
  } catch (FileNotFoundException e) {
      log.error(e.getMessage(), e);
  } finally {
      if (outputStream != null) {
          outputStream.close();
      }
      if (workbook != null) {
          workbook.close();
      }
  }


To-be (apply try-with-resources statement)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  File tmpFile = File.createTempFile("issue", ".xls");
  try(FileOutputStream outputStream  = new FileOutputStream(tmpFile)){
      workbook.write(outputStream);
  } catch (FileNotFoundException e) {
      log.error(e.getMessage(), e);
  } finally{
      if (workbook != null) {
          workbook.close();
      }
  }


Reference
[1] http://www.studytonight.com/java/try-with-resource-statement.php

2016/09/08

[Apache POI] How to freeze the first row

Problem
I am using Apache POI to write data into Microsoft Excel. 
If I would like to keep the first row on the top of this document when I scroll down, how to do it?


How-to
You can utilize createFreezePane API which provide by Apache POI to fulfill this requirement. Here has code snippet:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 @Override
 public File exportIssuesToXls(List < Issue > issues) throws IOException, RedmineException {
  Workbook workbook = new HSSFWorkbook();
  Sheet sheet = workbook.createSheet("issue list");
  CellStyle style = createCellStyle(workbook);

  //....

  //freeze the first row
  sheet.createFreezePane(0, 1);

  FileOutputStream outputStream = null;
  File tmpFile = null;
  try {
   tmpFile = File.createTempFile("issue", ".xls");
   log.info("tmpFile = " + tmpFile.getCanonicalPath());
   outputStream = new FileOutputStream(tmpFile);
   workbook.write(outputStream);

  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } finally {
   if (outputStream != null) {
    outputStream.close();
   }
   if (workbook != null) {
    workbook.close();
   }
  }
  return tmpFile;
 }



Reference
[1] https://stackoverflow.com/questions/17932575/apache-poi-locking-header-rows

2016/09/07

[Apache POI] How to add new line in cell data

Problem
I am using Apache POI to write data into Microsoft Excel.
I would like to break data into new line in some cell, how to do it?


How-to
You can add \n for the new line. For example,
1
Issue issue1 = new Issue(1, "查不到資料", "新建立", "正常", "蜘蛛人(2016-05-26 17:05:00):\n這個提議不錯,來做吧!\n\n浩克(2016-05-26 17:05:00):\n測試無誤\n\n");




Reference
[1] https://stackoverflow.com/questions/14646349/how-to-add-new-line-character-in-the-cell-comment-using-apache-poi

2016/09/06

[Microsoft Word] 如何新增檔名到頁尾

Problem
如果我要在 word 文件的頁尾插入 word 檔名,在 Microsoft Word 中如何做?

How-to
1. 點選頁尾


2. 插入 => 快速組件 => 功能變數


3. 選擇 file name,按下確定按鈕


4. 此時,就可以看到頁尾出現此檔案的檔名


Reference
[1] https://support.office.com/zh-tw/article/%E6%96%B0%E5%A2%9E%E6%AA%94%E5%90%8D%E5%88%B0%E9%A0%81%E9%A6%96%E6%88%96%E9%A0%81%E5%B0%BE-dc62245f-b6af-45b2-a521-17753fc3539e 

2016/09/05

[Windows 7] 參考到的帳戶目前已鎖定,且可能無法登入

Problem
有次在登入windows 7的帳號密碼時,因故輸入三次錯誤,導致電腦被鎖定,即便是重新開機以後還是出現相同的錯誤訊息


Solution
由於之前已經有過一次經驗,必須要有windows 7光碟進入才有辦法解決,故經過上次以後,有建立一個擁有 administration 權限的另外一個 user

所以在本次,我只要先重開機,按下F8,選擇以安全模式進入Windows,再利用另外一個帳號log in 進去

Steps:
1. 在我的電腦按下右鍵,選擇管理


2 .系統工具=>本機使用者與群組=>使用者


3. 於 lock 的使用者帳號按下滑鼠右鍵,選擇內容



4. 將最後一個 checkbox 勾勾取消,並重新開機即可



2016/09/04

[POI] Write /Read Excel Files in Java using Apache POI

Here has a simple example to demonstrate how to write / read excel file via Apache POI.

Add Apache POI dependency:
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.14</version>
</dependency>

Create a POJO class:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package albert.practice.poi;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Issue implements Serializable {
    /**
    * 
    */
    private static final long serialVersionUID = 1L;

    private Integer id;
    private String subject;
    private String status;
    private String priority;
}

Sample code is as bellows:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package albert.practice.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import lombok.extern.slf4j.Slf4j;

//http://www.codejava.net/coding/how-to-write-excel-files-in-java-using-apache-poi
//http://viralpatel.net/blogs/java-read-write-excel-file-apache-poi/
@Slf4j
public class PoiExample {

    private static String excelFile = "D:" + File.separator + "issue.xls";

    public static void main(String[] args) throws IOException {
        PoiExample test = new PoiExample();
        test.writeExcel();

        test.readExcel(excelFile);
    }

    public List<Issue> readExcel(String excelFile) throws IOException {

        List<Issue> issues = new ArrayList<Issue>();

        InputStream inputStream = null;
        Workbook workbook = null;
        try {
            // 1. Create a Workbook.
            inputStream = new FileInputStream(new File(excelFile));
            workbook = new HSSFWorkbook(inputStream);

            // 2. Get first sheet
            Sheet sheet = workbook.getSheetAt(0);

            // 3. Iterate through each rows from first sheet
            Iterator<Row> rowIterator = sheet.iterator();
            int rowCount = 1;
            while (rowIterator.hasNext()) {
                // (1) ignore header row
                if (rowCount == 1) {
                rowIterator.next();
                rowCount++;
                }
                // (2) start to read each row from second row
                else {
                    Row row = rowIterator.next();
                    Integer id = Double.valueOf(row.getCell(0).getNumericCellValue()).intValue();
                    String subject = row.getCell(1).getStringCellValue();
                    String status = row.getCell(2).getStringCellValue();
                    String priority = row.getCell(3).getStringCellValue();

                    Issue issue = new Issue();
                    issue.setId(id);
                    issue.setSubject(subject);
                    issue.setStatus(status);
                    issue.setPriority(priority);

                    issues.add(issue);
                 }
             }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (workbook != null) {
                workbook.close();
            }
        }

        for (Issue issue : issues) {
            log.debug("issue = " + issue.toString());
        }

        return issues;
    }

    public void writeExcel() throws IOException {
        // 0. prepare dummy data
        List<Issue> issues = createDummyIssues();

        // 1. Create a Workbook.
        Workbook workbook = new HSSFWorkbook();

        // 2. Create a Sheet.
        Sheet sheet = workbook.createSheet("issue list");

        // 3. create cell style
        CellStyle style = createCellStyle(workbook);

        // 4. Repeat the following steps until all data is processed:
        // (1) Create a Row.
        // (2) Create Cells in a Row. Apply formatting using CellStyle.
        int rowCount = 0;
        Row headerRow = sheet.createRow(rowCount);
        writeHeader(headerRow, style);

        for (Issue issue : issues) {
            Row row = sheet.createRow(++rowCount);
            writeDataForEachRow(issue, row, style);
        }

        // 5. auto resize column width
        for (int i = 0; i < 4; i++) {
            sheet.autoSizeColumn(i);
        }

        // 6. Write to an OutputStream.
        // 7. Close the output stream.
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(excelFile);
            workbook.write(outputStream);

            log.debug("write issue data to excel file successfully");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
            if (workbook != null) {
                workbook.close();
            }
        }
    }

    private void writeHeader(Row headerRow, CellStyle style) {
        Cell cell = headerRow.createCell(0);
        cell.setCellValue("編號");
        cell.setCellStyle(style);

        cell = headerRow.createCell(1);
        cell.setCellValue("主旨");
        cell.setCellStyle(style);

        cell = headerRow.createCell(2);
        cell.setCellValue("狀態");
        cell.setCellStyle(style);

        cell = headerRow.createCell(3);
        cell.setCellValue("優先");
        cell.setCellStyle(style);
    }

    private void writeDataForEachRow(Issue issue, Row row, CellStyle style) {
        Cell cell = row.createCell(0);
        cell.setCellValue(issue.getId());
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue(issue.getSubject());
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue(issue.getStatus());
        cell.setCellStyle(style);

        cell = row.createCell(3);
        cell.setCellValue(issue.getPriority());
        cell.setCellStyle(style);
    }

    private CellStyle createCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setBorderBottom((short) 1);
        cellStyle.setBorderTop((short) 1);
        cellStyle.setBorderLeft((short) 1);
        cellStyle.setBorderRight((short) 1);
        cellStyle.setWrapText(true);

        return cellStyle;
    }

    private List<Issue> createDummyIssues() {
        Issue issue1 = new Issue(1, "查不到資料", "新建立", "正常");
        Issue issue2 = new Issue(2, "新增時發生錯誤", "新建立", "高");
        Issue issue3 = new Issue(3, "刪除失敗", "處理中", "高");

        return Arrays.asList(issue1, issue2, issue3);
    }

}


Excel file looks like: https://github.com/junyuo/AlbertGitProject/blob/master/src/albert/practice/poi/issue.xls


Reference
[1] http://www.codejava.net/coding/how-to-write-excel-files-in-java-using-apache-poi
[2] http://viralpatel.net/blogs/java-read-write-excel-file-apache-poi/

2016/09/03

[jackson] How to generate json from java bean and vice versa

Problem
If I would like to do conversation with Java Bean to JSON and JSON to Java Bean, any library can be used?

How-To
Add dependency to your pom.xml
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Create an User bean for test:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package albert.practice.json;

import java.io.Serializable;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;
    private String login;
    private String mail;
}

Test code is as bellows:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package albert.practice.json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class JacksonTest {

    public static void main(String[] args) {
        JacksonTest test = new JacksonTest();
        String jsonString = test.convertOjbectToJson();

        List<User> users = test.convertJsonToObject(jsonString);
        for (User user : users) {
           log.debug("user = " + user.toString());
        }
    }

    public List<User> convertJsonToObject(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();
        List<User> users = new ArrayList<User>();
        try {
            users = mapper.readValue(jsonString, new TypeReference<List<User>>() {
        });
    } catch (JsonParseException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
        return users;
    }

    public String convertOjbectToJson() {
        List<User> users = createUsers();
        String jsonString = "";

        ObjectMapper mapper = new ObjectMapper();

        try {
            jsonString = mapper.writeValueAsString(users);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.debug("jsonString = " + jsonString);
        return jsonString;
    }

    private List<User> createUsers() {
        User albert = new User();
        albert.setId("1");
        albert.setLogin("albert");
        albert.setMail("albert@gmail.com");

        User mandy = new User();
        mandy.setId("2");
        mandy.setLogin("mandy");
        mandy.setMail("mandy@gmail.com");

        User verio = new User();
        verio.setId("3");
        verio.setLogin("verio");
        verio.setMail("verio@gmail.com");

        List<User> users = new ArrayList<User>();
        users.add(albert);
        users.add(mandy);
        users.add(verio);

        return users;
    }

}

print log:
1
2
3
4
2016-06-01 15:35:39.630 [main] DEBUG albert.practice.json.JacksonTest - jsonString = [{"id":"1","login":"albert","mail":"albert@gmail.com"},{"id":"2","login":"mandy","mail":"mandy@gmail.com"},{"id":"3","login":"verio","mail":"verio@gmail.com"}]
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=1, login=albert, mail=albert@gmail.com)
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=2, login=mandy, mail=mandy@gmail.com)
2016-06-01 15:35:39.670 [main] DEBUG albert.practice.json.JacksonTest - user = User(id=3, login=verio, mail=verio@gmail.com)

Reference
[1] http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
[2] https://stackoverflow.com/questions/28821715/java-lang-classcastexception-java-util-linkedhashmap-cannot-be-cast-to-com-test

2016/09/02

[閱讀筆記] 97 Things Every Programmer Should Know (1/2)


  1. 最新式的電腦,只不過是加速加重了人與人之間一直以來的問題,最終,溝通者要面對的,依然在於如何表達出自己要說的
  2. 技術債 (technical debt) 就像貸款,你可以為了時程決定「先快速做完」,而不是「做好」,你會在短期內得利,但在債務還清之前都必須支付利息。滿足一時的程式碼,會使新增功能與重構變得困難。時間越久,傷害越大。事實上,往往都是當事情糟到你不得不修正時,你才會真的回頭去解決當初的問題,但是這時候程式碼已經變得很難修正。
  3. 記得要儘快償還技術債 (technical debt),否則會因為草率的行為而嚐到惡果。
  4. 我們常認為別人的想法和我們一樣,但事實上不是。心理學將此稱為共識偏誤(false consensus bias)。請直接去問使用者會怎麼操作,你不算是使用者
  5. 使用者傾向於只要有能用的方法就好,他們一旦找到一種可行的方法之後,就會一直用,不論這個方法是多麼迂迴。因此,最好準備一條明顯的道路,而不是給兩三種道路供選擇
  6. 你也會發現使用者所描述的,和他們實際做的往往有段落差。因此最好的方法是直接觀察使用者,花幾個小時觀察,比起花一整天想使用者到底要什麼,反而可以得到更多資訊
  7. coding standard 應該是靈活不死板的,隨著專案演進,需求改變,一些當初看似聰明的想法,在幾個月後已經不見得聰明了
  8. 柏拉圖曾說:風格之美、和諧、優美與節奏取決於簡約。美麗的程式的最低限度是簡單的程式碼。不只職責簡單,與系統的其他部分也要保持簡單的關係。簡單、乾淨、可測試的程式碼,可以提高可讀性、可維護性、開發效率。美,就在簡單中誕生,在簡單之中發現
  9. 在你重構前,你要思考:
    1. 從現有的程式碼與其對應的測試開始,從當前系統的錯誤中學到教訓
    2. 避免全部重寫的誘惑,重寫代表要放棄經年累月的測試
    3. 多次漸進式的修改會優於一次大量的修改
    4. 每次development iteration結束後,要確保現有的測試都必須通過
    5. 程式碼的結構與風格不符合你的喜好,不是重構的正確理由
    6. 新技術的出現不足以成為重構的理由
    7. 每個人都是會犯錯的,重構不保證新的程式碼一定比較好
  10. 童子軍有一條規則:『每次離開營區時,都要讓它比剛到的時候更乾淨』。也就是說,如果你發現環境髒亂,不管是誰造成的,你都要把它打掃乾淨,留給下一批露營者有更好的環境。相同的,你不必在 check in 前讓每個模組盡善盡美,只要讓它比當初 check out 的時候好一點點就可以,如改善了變數名稱、將一個過長的function拆成兩個小的function等。軟體開發團隊要互相幫助,互相清理程式碼。成員門遵循童子軍規則,不只是為了自己,而是因為這對每一個人都好。
  11. Debug 時,回想福爾摩斯的建議:「除去不可能的,剩下的即使不尋常,那也是真相。」
  12. 面對multi-thread 的系統,簡潔的設計非常重要,簡潔代表容易debug
  13. 程式碼的排版很重要,有研究指出,我們花在瀏覽和閱讀程式碼,找出哪裡該修改的時間,比實際修改的時間多更多。所以程式排版有三個優化措施:易於瀏覽、清楚的排版、緊湊的格式
  14. code review 不只是找出並修正程式錯誤,更重要的是分享知識,並建立普遍的coding方針。code review 的重點是在 review 的過程當中去學習、了解這些程式碼
  15. 採用表達力佳(但相對較短)的名稱來命名物件、型別與函式,讓程式碼本身具備如文件的說明能力
  16. 註解應該要說出程式碼所沒有表達、也無法表達的事情。如果程式自己可以說清楚的事情,你就不需要為它加上註解
  17. 外科醫生知道必須要切出傷口才能進行手術,也知道傷口是暫時的,會痊癒的。害怕改變程式碼導致癱瘓,可能正是造成系統落入癱瘓的起點。投入時間 refactor,對於專案的整個生命週期可以帶來數倍的價值,也因為有了處理病態系統的經驗,也成為了解系統應當如何運作的專家
  18. 無論你認為你的程式碼有多麼不可能出現錯誤,你也應該每一次都檢查並處理,即使你現在不做,你也不會省下時間,你未來還是要還債,而且累積越久,要還的債更多,未來會連本帶利要你償還
  19. 如果你忽視一項錯誤,選擇視而不見,假裝沒這件事情,你其實在承擔巨大的風險,你也無法預料這個巨大的風險會在何時向你反撲。
  20. 放著錯誤不管會造成
    1. 脆弱的程式碼且難以debug
    2. 不安全的程式碼
    3. 糟糕的結構
  21. 沒有開發經驗的專案經理會認為程式設計師做的事情很簡單,而沒有管理經驗的程式設計師,也認為專案經理做的事情很簡單
  22. 軟體的構成實體,應當對於擴充保持開放,但對修改保持封閉
  23. DRY ( Don’t Repeat Yourself ) 的原則,是指開發人員要學會便是重複的程式碼,也懂得利用更好的實踐和更適當的抽象化來消除重複,比起只知道用不必要的重複來污染程式的人,可以產出更乾淨的程式碼。DRY 原則,位開發人員提供基本指引,幫助開發人員所產出的程式變得更簡單、更容易維護且品質更好
  24. 假設有個物件,其典型的特色是需要先完成幾件事情才能開始使用,此時就可以使用abstract factory pattern or factory method pattern 來實現。如果某個物件有多種可變的行為,那麼這些行為可以用strategy pattern 來實作並放進物件,不該用一個巨大的 if-else 結構
  25. 當一個class 的containment (封裝)被破壞,常會看到其method 出現大量的if-then-else的結構,這樣的method 很容易崩壞且幾乎無法維護