2013年10月18日 星期五

The powerful text search utility in Linux - Grep


Since we use Seam as our framework to develop web applications, we adopt its mechanism of securing JSF pages to restrict access to users that aren't authenticated, which is to add the login-required attribute to the .page.xml file.  (Section 11.2.2 in 'Seam in Action' )

<page xmlns="http://jboss.com/products/seam/pages"

      login-required="true"    
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd">
...
</page>
However, one day, we suddenly noticed there were some .page.xml files didn't include that authentication attribute, and this might introduce security issue to our system. We needed to find all those files and correct them, but they distributed over all the directories which was not easy to find, at least I didn't think I could achieve that in a fast way by JBoss Developer Studio, manually checking through all the .page.xml files (hundreds of them) in the workspace obviously was not a good idea.

Therefore, I tried to check if our text search utility in Linux - grep can solve my problem:
I want to search all the .page.xml files under webapp directory recursively, and get a list of filename which doesn't contains 'login-required' string. 

I thought I needed to use several pipelines, or applied regression expression which I'm not very good at.
After surveyed for a while, fortunately, things didn't get that complicated. One simple line can serve my need:

[root@localhost webapp]# pwd
/root/workspace/proj/target/proj/proj-war/src/main/webapp
[root@localhost webapp]# grep -RL 'login-required=\"true' --include='*.page.xml' .
Within 1 second, the screen started to print out the results I wanted, thanks for this powerful "Global Regular Expression Print"!

tag note for the grep:
       --include=GLOB
              Search only files whose base name matches GLOB (using wildcard  matching  as
              described under --exclude).

       -L, --files-without-match
              Suppress normal output; instead print the name of each input file from which
              no output would normally have been printed.  The scanning will stop  on  the
              first match
.

       -l, --files-with-matches
              Suppress normal output; instead print the name of each input file from which
              output would normally have been printed.  The  scanning  will  stop  on  the
              first match.  (-l is specified by POSIX.)

       -R, -r, --recursive
              Read  all files under each directory, recursively; this is equivalent to the
              -d recurse option.

2013年6月30日 星期日

Testing display the code nicely via Google Code Prettify

Here is the result:

int sum=0;  
for(int i=0;i<10;i++){
  sum+=i;
} 
System.out.println("total:"+sum);


What I did basically was according to stackoverflow: How to use prettify with blogger/blogspot?  I took the solution provided by SK9 because it looked simpler.

However, since the posts was three years ago, now the Blogger setting UI is slightly different, let me post my steps here.

Step1:Login blogger with your account, select 'Template', and click on 'Edit HTML' button.




Step2:
Copy the following two lines to the block inside <head></head>, and add onload='prettyPrint()' in <body> tag.




Step3: When post an article, switch to 'HTML' mode, and wrapper your code with <pre class="prettyprint"> and </pre>, you will see the effect!




Nevertheless, looks like wordpress has this function as built-in, and the appearance is quite decent and clear.

(btw, I have also found another tutorial in Chinese: 
http://blog.cookys.net/2012/10/blogger-google-code-prettify.html, the article was not too long ago)

2013年1月9日 星期三

The evil getter and setter 萬惡的getter和setter


今天在Stackoverflow上讀到了一篇文章 Are Getters and Setters evil?  (getter跟setter真的那麼邪惡嗎?)

把一些重點摘錄如下,有習慣看英文的可以直接去看這邊: http://stackoverflow.com/questions/565095/are-getters-and-setters-evil

其中一個大原則是,針對private field, 不使用public setter去直接改值, 用其他有意義且必要的metohd去改變值

範例:  使用kill()或者是damaget()這兩個method去對private的hp欄位進行值的更改,而不使用setHp()來修改
(發表者Zarkonnen)
private int hp; // Set in constructor.
public boolean isAlive() { return hp > 0; } // Same method signature.
public void kill() { hp = 0; } // Same method signature.
public void damage(int damage) { hp -= damage; }


而另一位Jon Skeet網友則如此定義邪惡的等級 (或者說是code的好壞/安全性/OO觀念):

Very evil: public fields.
Somewhat evil: Getters and setters where they're not required.
Good: Getters and setters only where they're really required - make the type expose "larger" behaviour which happens to use its state, rather than just treating the type as a repository of state to be manipulated by other types.
不確定我是否理解正確,他覺得最糟的狀況是直接使用public field (比不必要的getter/setter還糟),好的狀況則是在必要的狀況下使用getter及setter,而所謂必要的狀況,應該是有一些額外的行為想要在getter及setter裡面做,而非僅僅取值/設值.

那除了取值/設值外,會有什麼"額外的行為"是需要在getter和setter裡面做的呢?
 coobird網友提供了兩個例子:
範例1: 計算值遭到修改的次數   (更常見的狀況可能是驗證使用者所輸入的資料)
 public void setValue(int value)
{
    this.value = value;
    count++;
}
範例2: 保護原值不任意遭到修改
public int[] getArray()
{
    return myArray.clone();
}
ImmutableArray a = new ImmutableArray();
int[] b = a.getArray();
b[0] = 10;      // 不會真正更改到myArray本身

而也有人提出 (網友nathan),如果在setter裡面做了許多多餘的動作,別人在使用此API時並無法得知, 如果每個setter使用者都要去確認相當麻煩。
像是這樣的method會是個壞例子

public void setAlive(boolean isAlive){
    this.isAlive = isAlive;
    if (isAlive)
        addToWorld(this);
    else
        removeFromWorld(this);
}
建議改成在setter外的method做,如:
public void kill(){
    isAlive = false;
    removeFromWorld(this);
}

還有一篇裡面有人引用到的來自Java World的文章,作者為Allen Holub,還沒讀完,等讀完再一併整理...  (天啊..看日期是九年前發表的文章的意思嗎...)
http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html