Total Pageviews

2017/06/30

2017/06 UK

Tower Bridge
DSC01942

DSC01948

DSC01964


Piccadilly Circus
DSC01985

DSC01994

DSC02014


The Roman Baths
DSC02031

DSC02085

DSC02059

DSC02063


The circle
DSC02126

DSC02136


Notting Hill
DSC02163

DSC02155

DSC02161


Harrods
DSC02188









2017/06/29

2017/06 UK

Heathrow airport
DSC01576


Bayswater street view
DSC01596


Buckingham Palace
DSC01612


Big Ben
DSC01654


British Museum
DSC01699


Cambridge
DSC01750

DSC01805

DSC01801

DSC01802


Windsor Castle at Windsor England
DSC01906

DSC01853

DSC01900

DSC01881





2017/06/10

[Design Pattern] Builder Pattern

Definition of Builder Pattern

  • The builder pattern, as name implies, is an alternative way to construct complex objects. 
  • A builder pattern is more like fluent interface. A fluent interface is normally implemented by using method cascading (or method chaining).
  • Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”

A complete Java builder pattern example
 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
package albert.practice.designpattern.builder;

import java.util.regex.Pattern;

import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public class User {

    private final String firstName;
    private final String lastName;
    private final Integer age;
    private final String phone;
    private final String email;

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.email = builder.email;
    }

    public static class UserBuilder {
        private String firstName;
        private String lastName;
        private Integer age;
        private String phone;
        private String email;

        public UserBuilder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public UserBuilder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public UserBuilder age(Integer age) {
            this.age = age;
            return this;
        }

        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }

        public UserBuilder email(String email) {
            this.email = email;
            return this;
        }

        public User build() {
            User user = new User(this);

            // Do some basic validations to check
            if (!isEmailValid(user.getEmail())) {
                throw new RuntimeException(user.getEmail() + " is invalid Email format!");
            }

            return user;
        }

        public Boolean isEmailValid(String email) {
            Boolean isValid = Boolean.FALSE;
            Pattern EMAIL_PATTERN = Pattern.compile("^\\w+\\.*\\w+@(\\w+\\.){1,5}[a-zA-Z]{2,3}$");
            if (EMAIL_PATTERN.matcher(email).matches()) {
                isValid = Boolean.TRUE;
            }
            return isValid;
        }

    }
}


Example to use above builder pattern to create a User object
 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
package albert.practice.designpattern.builder;

import albert.practice.designpattern.builder.User.UserBuilder;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BuilderTest {
    public static void main(String[] args) {
        User albert = new UserBuilder()
                .lastName("Kuo")
                .firstName("Albert")
                .phone("1234567890")
                .age(30)
                .email("test@gmail.com")
                .build();
        log.debug(" user1 = " + albert.toString());

        User mandy = new UserBuilder()
                .lastName("Yeh")
                .firstName("Mandy")
                .email("yeh@gmail.com")
                .build();
        log.debug(" user2 = " + mandy.toString());
    }
}



Benefits and Advantages

  • The number of lines of code increase at least to double in builder pattern, but the effort pays off in terms of design flexibility and much more readable code. The parameters to the constructor are reduced and are provided in highly readable method calls.
  • The constructor is private, which means that this class can not be directly instantiated from the client code.
  • The class is once again immutable. All attributes are final and they’re set on the constructor. Additionally, only provide getters for them.
  • The builder uses the Fluent Interface idiom to make the client code more readable.


Conclusion
Using builder pattern for constructing objects when having a lot of parameters, especially if many of these parameters are null and when many of them share the same data type. A developer might feel that the extra code to implement a Builder might not justify its benefits for a small number of parameters, especially if the few parameters are required and of different types. In such cases, it might be considered desirable to use traditional constructors or, if immutability is not desired, use a no-argument constructor and require the client to know to call the necessary "set" methods.


Reference
[1] http://www.javaworld.com/article/2074938/core-java/too-many-parameters-in-java-methods-part-3-builder-pattern.html?page=2
[2] http://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/

2017/06/09

[Eclipse] project configuration is not up to date with pom.xml

Problem
I have Maven Project in Eclipse Mars.

One day I have an error in my project, but it does not have any negative effect to my implementation or maven build :


How-To
Although the root cause is still unclear, it works to follow these steps to get rid of this annoying error:

Step 1. Click this error => right click => Quick Fix


Step 2. Click Finish in Quick Fix window

Fixing problem in progress:

After fixing process, the problem is disappeared:

2017/06/08

[Eclipse] EclEmma - Java Code Coverage for Eclipse

In computer science, code coverage is a measure used to describe the degree to which the source code of a program is executed when a particular test suite runs. A program with high code coverage, measured as a percentage, has had more of its source code executed during testing which suggests it has a lower chance of containing undetected software bugs compared to a program with low code coverage.

EclEmma is a free Java code coverage tool for Eclipse, it brings code coverage analysis directly into the Eclipse workbench.


Prerequisite
Prepare your unit test programs:



Execution
After you installed EclEmma Plugin, you can run  Coverage as => JUnit Test


Then you can get the converge analysis report


Summary
While 100% code coverage is nice, it's not a good metric to blindly follow. 100% code coverage doesn't tell you anything other than you have tests that execute all your lines of code. Your code can still have bugs if that covered code does the wrong thing or doesn't do enough. 


Reference
[1] https://en.wikipedia.org/wiki/Code_coverage
[2] http://www.eclemma.org/
[3] https://stackoverflow.com/questions/26360245/try-with-resource-unit-test-coverage


2017/06/07

[webMethods] Global Variable

Problem
若我們有些變數是全域使用的,在 webMethods 中要設定在哪邊,才能讓所有的 Java Service、Flow Service 使用?

How-To
可以在 Integration Server 設定 global variable,步驟如下:
Step 1. 進入 Integration Server Administrator,在 Navigation panel 中選擇 Settings => Global Variables


步驟 2.  按下  Add Global Variable


步驟 3. 輸入 key (Global variable 的名字) 與 value (Global variable 的值),並按下 Save Changes



接下來,我們可以建立一個 Flow Service 來做測試
步驟1. drag and drop debugLog 此套件到 Flow Service 中,點選 Pipeline tab,並點選 message


步驟 2. 在 message 中輸入 global variable 的名字,頭尾用 % 包起來,記得要勾選 Perform global variable substitution 此選項,並按下 OK 按鈕

步驟 3. 執行此 Flow Service 進行測試



2017/06/06

[Eclipse Plugin] EasyShell

While working in eclipse you may want to open selected file from project explorer to Windows File Explorer. 
One way is by selecting file, go to properties, copying path and open Windows File Explorer then paste that path. 



Another convenient way is to utilize EasyShell plugin

This Eclipse plugin allows to open a shell window or file manager from the popup menu in the navigation tree or editor view. Additionally it is possible to run selected file in the shell, copy file or directory path or run user defined external tools. 

EasyShell usage looks like:



Reference
[1] https://marketplace.eclipse.org/content/easyshell

2017/06/05

How to use Apache Commons CSV to Read/Write CSV file

Step 1. You need to add this dependency to your pom.xml
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.4</version>
</dependency>


Step 2. Create a POJO class
package albert.practice.csv;

import java.io.Serializable;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class OpcVo implements Serializable {

    private Integer ns;
    private String identifier;
    
}


Step 3. Here has an example regarding how to read/write CSV file via Apache Commons CSV
package albert.practice.csv;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.CSVRecord;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CSVTest {

    // Delimiter used in CSV file
    private static final String NEW_LINE_SEPARATOR = "\n";

    // CSV file header
    private static final String[] FILE_HEADER = {"ns", "identifier"};

    // OpcVo attributes
    private static final String NS = "ns";
    private static final String ID = "identifier";

    public static void main(String[] args) throws IOException {
        String csvDirectory = "D:/work/AOCS/csv/";
        String csvFileName = "test.csv";

        CSVTest test = new CSVTest();
        // test.writeToCSV(csvFolder.concat(csvFile));
        List<OpcVo> opcs = test.readFromCsv(csvDirectory.concat(csvFileName));
        opcs.forEach(opc -> log.debug(opc.toString()));
    }

    public void writeToCSV(String fileName) throws IOException {
        List<OpcVo> opcs = getDummyData();

        // Create the CSVFormat object with "\n" as a record delimiter
        CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR);

        try (FileWriter fileWriter = new FileWriter(fileName);
                CSVPrinter csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat);) {
            // Create CSV file header
            csvFilePrinter.printRecord(FILE_HEADER);

            // Write a new OpcVo object list to the CSV file
            for (OpcVo opc : opcs) {
                List dataRecord = new ArrayList<>();
                dataRecord.add(String.valueOf(opc.getNs()));
                dataRecord.add(opc.getIdentifier());
                csvFilePrinter.printRecord(dataRecord);
            }
        } catch (IOException e) {
            throw e;
        }
    }

    public List<OpcVo> readFromCsv(String fileName) throws IOException {
        // Create a new list of OpcVo to be filled by CSV file data
        List<OpcVo> result = new ArrayList<>();

        // Create the CSVFormat object with the header mapping
        CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader(FILE_HEADER);

        try (FileReader fileReader = new FileReader(fileName);
                CSVParser csvFileParser = new CSVParser(fileReader, csvFileFormat);) {
            List dataRecord = new ArrayList<>();
            // Get a list of CSV file records
            List<CSVRecord> csvRecords = csvFileParser.getRecords();
            
            for (int i = 1; i < csvRecords.size(); i++) {
              //Create a new OpcVo object and fill this data
                CSVRecord record = csvRecords.get(i);
                String ns = record.get(NS);
                String identifier = record.get(ID);
                result.add(new OpcVo(Integer.valueOf(ns), identifier));
            }
        } catch (IOException e) {
            throw e;
        }

        return result;
    }

    private List<OpcVo> getDummyData() {
        OpcVo opc1 = new OpcVo(2, "Channel1.Device1.FireZone_01");
        OpcVo opc2 = new OpcVo(2, "Channel1.Device1.EmergencyPushButton_01");
        OpcVo opc3 = new OpcVo(2, "Channel1.Device1.EmergencyExitWindow_01");
        OpcVo opc4 = new OpcVo(2, "Channel1.Device1.EmergencyExit_01");

        return Arrays.asList(opc1, opc2, opc3, opc4);
    }
}




2017/06/04

[Windows 7] 如何將資料上傳到遠端桌面?

Problem
若我用 Windows 的遠端桌面連線程式連上遠端的電腦,我該如何將本機的檔案上傳到遠端的電腦?

How-to
步驟 1. 打開遠端桌面連線,點選『本機資源』,點選『其他』


步驟 2. 勾選要分享的目錄,如畫面中的隨身碟


步驟 3. 連線到遠端的電腦以後,可以在檔案總管看到 步驟 2. 勾選的磁碟機,若有檔案要從遠端複製回本機端,或者是從本機端複製到遠端,可以利用此磁碟機當作是分享的橋樑