출처 : http://www.jakartaproject.com/article/etctip/119821689035842

규칙1: properties 파일은 Text 파일이며, 다음과 같은 형태의 이름들을 가질 수 있습니다.

MyResource_ko_KR_IBMeucKR.properties
MyResource_ko_KR.properties
MyResource_ko.properties
MyResource_en_US.properties
MyResource_en.properties
MyResource.properties


baseclass "_" language1 "_" country1 "_" variant1
baseclass "_" language1 "_" country1
baseclass "_" language1
baseclass

즉, 자동으로 JVM의 Locale 정보를 찾아서 위 순서대로 프로퍼티 파일을 순차적으로 찾아
나갑니다.

Locale 옵션을 주지 않으면, Locale.getDefault()를 사용하게 됩니다.
System.out.println(Locale.getDefault()) 해 보시면 확인이 가능하며, 이 값은
"file.encoding" 이라는 System Property 값에 의해 영향을 받으며, 이것은 다시
환경변수 "LANG" 값에 영향을 받습니다.

이 기능을 이용하여, Locale 값이 무엇이냐에 따라 서로 다른 문자열을 프로그램내에서
제공할 수 있게 되는 것이지요...
즉, 아래와 같은 서로 다른 이름의 resource 파일을 두게 되면, 영어와 한글 문자열을
Locale 값에 따라 서로 다르게 제공할 수 있는 것이지요.

MyResource_ko.properties
MyResource_en.properties
MyResource.properties <--- 이도저도 아닐 때 사용되는 defualt



규칙2: 위의 해당 properties 파일은 classpath 에 잡혀 있는 곳에 있어야 하며,
만약, package 로 구분된 sub directory 에 두었다면, 반드시 full path 를 주어야
합니다.


ResourceBundle resource =
    ResourceBundle.getBundle("org.jsn.somewhere.MyResource")

그리고, MyResource_??_??.properties 파일들(!)은 org/jsn/somewhere/ 하부 디렉토리에
놓여 있어야 합니다.

해당 properties 파일들은 jar 파일내에 함께 묶어 두어도 됩니다.


규칙3: properties 파일들은 다음과 같은 포멧으로 구성되어 있습니다.
----------------------------------------------------------------------
# 1. key = value_string 으로 기술된다.
# 2. Comment 는 '#'으로 시작되면 되나, 문자열 중간에 있는 '#'기호는 Comment로
#    인식하지 않는다.
# 3. '=' 대신 ' '(공백)을 사용해도 된다.
#    (즉 첫번째 나오는 공백이 key와 vlaue string를 나누는 구실도 한다.
# 4. 3번의 이유로 인하여 key에는 중간에 공백이 허용되지 않는다.
# 5. 반면, value string에는 공백이 허용된다.
# 6. value string를 사용할 때 한글이 지원된다. 그러나 key는 한글지원이 안된다.
# 7. 두 줄 이상을 사용하려면 라인의 끝에 '\' 문자를 사용하면 된다.
#    '\'문자 자체가 필요할 땐 '\' 대신 '\\'을 사용하라.
# 8. 7번의 이유로 인하여 Windows 환경에서 디렉토리 구분은 '\'가 아니라 '\\' 이다.
key = value
name = 이원영
.....
----------------------------------------------------------------------




규칙4: 한글은 8859_1 캐릭터 셋으로만 읽혀 집니다. 따라서, JVM의 인코딩이 8859_1 이
아니라면, 다음처럼 변환하여야 합니다. file.encoding 이 "KSC5601" 이라면,


ResourceBundle resource = ResourceBundle.getBundle("resource.MyResource");
System.out.println(Locale.getDefault());
System.out.println(resource.getString("name"));
System.out.println(new String(resource.getString("name").getBytes("8859_1"),"KSC5601"));

내부적으로 ClassLoader.getResourceAsStream(filename); 의 형태로 읽혀 들이기
때문입니다.

보다 자세한 사항은 해당 클래스의 API 문서와 JDK 소스를 직접 읽어 보시길 바랍니다.
가장 빨리/정확히/깊이있게 공부하는 지름길입니다.


------------------------------------------------------- 
  본 문서는 자유롭게 배포/복사 할 수 있으나 반드시
  이 문서의 저자에 대한 언급을 삭제하시면 안됩니다
================================================
  자바서비스넷 이원영
  E-mail: javaservice@hanmail.net
  PCS:011-898-7904
================================================


출처 : http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=javatip&c=r_p&n=993541416&p=13&s=t

출처 : http://www.jakartaproject.com/article/data/117521573669532

jad -o -r -sjava -d디컴파일될타겟디렉토리 클래스파일소스디렉토리/**/*.class

예) jad -o -r -sjava -src unicorn/**/*.class



This is README file for Jad - the fast Java Decompiler.
Jad home page: http://www.kpdus.com/jad.html
Copyright 2001 Pavel Kouznetsov (jad@kpdus.com).

0. Please read the disclaimer on the Jad home page.

1. Installation.

Unzip jad.zip file into any appropriate directory on your hard drive.
This will create two files:

    - an executable file named 'jad.exe' (Windows *)
      or 'jad' (*n*x)

    - this README file

No other setup is required.

2. How to use Jad

To decompile a single JAVA class file 'example1.class'
type the following:

     jad example1.class

This command creates file 'example1.jad' in the current directory.
If such file already exists Jad asks whether you want to overwrite it or not.
Option -o permits overwriting without a confirmation.

You can omit .class extension and/or use wildcards in the names of
input files.

Option -s <ext> allows to change output file extension:

     jad -sjava example1.class

This command creates file 'example1.java'. Be careful when using
options -o and -sjava together, because Jad can accidentally overwrite
your own source files.

Jad uses JAVA class name as an output file name. For example, if class
file 'example1.class' contains JAVA class 'test1' then Jad will create
file 'test1.jad' rather than 'example1.jad'. If you want to specify
your own output file name use the output redirection:

   jad -p example1.class > myexm1.java

Option -d allows you to specify another directory for output files,
which are created, by default, in the current directory. For example:

   jad -o -dtest -sjava *.class

   (or jad -o -d test -s java *.class, which has the same effect)

This command decompiles all .class files in the current directory
and places all output files with extension .java into directory 'test'.


If you want to decompile the whole tree of JAVA classes,
use the following command:

   jad -o -r -sjava -dsrc tree/**/*.class

This command decompiles all .class files located in all
subdirectories of 'tree' and creates output files in subdirectories
of 'src' according to package names of classes. For example, if file
'tree/a/b/c.class' contains class 'c' from package 'a.b', then
output file will have a name 'src/a/b/c.java'.

Note the use of the "two stars" wildcard ('**') in the previous
command. It is handled by Jad rather than the command shell, so on
UNIX the last argument should be single-quoted:

   jad -o -r -sjava -dsrc 'tree/**/*.class'


In a case you want to check the accuracy of the decompilation or just
curious, there is an option -a which tells Jad to annotate the output
with JAVA Virtual Machine bytecodes.

Jad supports the inner and anonymous classes.
When Jad expands wildcards in the input file names,
it automatically skips matching inner classes.
On UNIX Jad skips inner classes if there is more than
one class specified in the command line.
Jad looks for inner classes in the directory of their top-level
container class.

3. List of the command-line options.

Jad accepts the following options:

   -a       - annotate the output with JVM bytecodes (default: off)
   -af      - same as -a, but output fully qualified names when annotating
   -clear   - clear all prefixes, including the default ones (can be abbreviated as -cl)
   -b       - output redundant braces (e.g., if(a) { b(); }, default: off)
   -d <dir> - directory for output files (will be created when necessary)
   -dead    - try to decompile dead parts of code (if any) (default: off)
   -disass  - disassemble method bytecodes (no JAVA source generated)
   -f       - output fully qualified names for classes/fields/methods (default: off)
   -ff      - output class fields before methods (default: after methods)
   -i       - output default initializers for all non-final fields
   -l<num>  - split strings into pieces of maximum <num> chars (default: off)
   -lnc     - annotate the output with line numbers (default: off)
   -lradix<num> - display long integers using the specified radix (8, 10 or 16)
   -nl      - split strings on newline character (default: off)
   -nocast  - don't generate auxiliary casts
   -nocode  - don't generate the source code for methods
   -noconv  - don't convert Java identifiers (default: convert)
   -noctor  - suppress the empty constructors
   -nodos   - do not check for class files written in DOS mode (CR before NL, default: check)
   -nofd    - don't disambiguate fields with the same names by adding signatures to their names (default: do)
   -noinner - turn off the support of inner classes (default: on)
   -nolvt   - ignore Local Variable Table information
   -nonlb   - don't output a newline before opening brace (default: do)
   -o       - overwrite output files without confirmation (default: off)
   -p       - send decompiled code to STDOUT (e.g., for piping)
   -pi<num> - pack imports into one line after <num> imports (default: 3)
   -pv<num> - pack fields with identical types into one line (default: off)
   -pa <pfx>- prefix for all packages in generated source files
   -pc <pfx>- prefix for classes with numerical names (default: _cls)
   -pf <pfx>- prefix for fields with numerical names (default: _fld)
   -pe <pfx>- prefix for unused exception names (default: _ex)
   -pl <pfx>- prefix for locals with numerical names (default: _lcl)
   -pm <pfx>- prefix for methods with numerical names (default: _mth)
   -pp <pfx>- prefix for method parms with numerical names (default: _prm)
   -r       - restore package directory structrure
   -radix<num> - display integers using the specified radix (8, 10 or 16)
   -s <ext> - output file extension (by default '.jad')
   -safe    - generate additional casts to disambiguate methods/fields (default: off)
   -space   - output space between keyword (if/for/while/etc) and expression (default: off)
   -stat    - display the total number of processed classes/methods/fields
   -t       - use tabs instead of spaces for indentation
   -t<num>  - use <num> spaces for indentation (default: 4)
   -v       - display method names being decompiled
   -8       - convert UNICODE strings into 8-bit strings
              using the current ANSI code page (Win32 only)
   -&       - redirect STDERR to STDOUT (Win32 only)

All single-word options have three formats:

  -o    - 'reverses' value of an option
  -o+   - set value to 'true' or 'on'
  -o-   - set value to 'false' or 'off'

You can specify the options you want to be set by default in the environment variable
JAD_OPTIONS. For example:

JAD_OPTIONS=-ff+ -nonlb+ -t+ -space+

출처 : http://www.javastudy.co.kr/docs/techtips/020502.html

javax.util.regex 패키지는 J2SE(Java 2 Platform, Standard Edition) 1.4 에서 새로 추가된 패키지이다.
이 패키지는 정규식(regular expression) 라이브러리를 제공한다.
정규식은 일련의 집합으로 표현되는 문자들의 패턴이고, 패턴 매칭(pattern matching)에서 자주 사용되어진다.
javax.util.regex 패키지에 있는 클래스들은 정규식을 고려하여 문자들의 순서를 일치시켜준다.
정규식 라이브러리를 포함하는 이러한 클래스들은 펄(Perl) 5 정규식 패턴 문법(syntax)을 사용한다.
그리고, 문장을 분석하는 일에 있어 이전에 java.io.StreamTokenizer와 java.util.StringTokenizer 클래스를 이용하여 것 보다 훨씬 더 강력한 방법을 제공한다.

정규식 라이브러리는 다음 세개의 클래스를 포함한다. Pattern, Matcher, PatternSyntaxException.
예외(exception)와 관련된 클래스를 중요하지 않게 생각하면, 정말 필요한 것은 일치하기를 원하는 정규식을 정의하기 위한 클래스(Pattern) 하나와, 주어진 문자열에서 패턴을 찾아내기 위한 또 다른 클래스(Matcher) 하나, 이렇게 단 두개의 클래스뿐이다.

정규식 라이브러리를 사용하기 위해서 가장 필요한 것은 패턴 문법을 이해하는 것이다.
실제로 문장을 분석하는 것은 비교적 쉬운 부분이다. 그러므로, 여기서는 정규식을 구성하는 것들이 무엇인지 살펴보도록 하자.

정규식의 가장 간단한 예제는 리터럴(literal)이다.
리터럴은 정규식에 포함되어 있는 단순한 문자가 아니라, 정규식에 포함된 어떤 특별한 배합이나 식의 일부분이 아닌 문자이다.

예를 들면, 리터럴 "x"는 정규식이다.
리터럴과 매처(matcher), 그리고 문자열을 사용하면, "정규식 'x'가 전체 문자열과 일치하는가?"라고 물어볼 수 있다.
다음은 이러한 질문에 대한 소스 코드이다.

boolean b = Pattern.matches("x", someString);


 만약 패턴 "x"가 someString 과 일치하는 일련의 문자라면, b는 true 값을 가지게 된다.
그렇지 않다면, b의 값은 false가 된다. 홀로 사용되는 경우에, 리터럴은 이해하기 위해서 분석하는 것이 어렵지 않다.
매처(matcher)가 Matcher 클래스가 아닌 Pattern 클래스에 의해서 만들어진다는 것을 주의해야 한다.
정규식이 단 한번만 사용되는 경우에 손 쉽게 사용 하기 위해서, matches 메서드는 Pattern 클래스에 정의된다.
일반적으로, Pattern 인스턴스를 정의하고, 그 Pattern 에 대한 Matcher 인스턴스를 정의한 후에, Matcher 클래스에 정의된 matches 메서드를 사용하는 것이 좋다.

Pattern p = Pattern.compile("x");  
Matcher m = p.matcher("sometext");
boolean b = m.matches();


이 팁의 후반부에 이런 단계를 다룰것이다.

물론, 정규식은 리터럴보다 더 복잡해질 수 있다.
와일드카드(wildcard)와 한정사(quantifier)를 추가하면 더 복잡해진다.
정규식에서는 오직 하나의 와일드카드만이 존재하는데, 바로 마침표(.) 문자이다.
와일드카드는 어느 한 문자와 일치시키기 위해서 사용되어지는데, 심지어는 개행문자도 가능하다.
한정사를 나타내는 문자는 +와 *이다.(원칙적으로는, 물음표 또한 한정사를 나타내는 문자이다)
정규식 뒤에 위치하는 + 문자는 정규식이 한번 또는 여러번 나타나는 것을 인정한다.
* 문자는 + 문자와 비슷하지만, 한번도 나오지 않거나 여러번 나오는 것을 인정한다.
예를 들어, 만약 처음에 j로 시작해서 마지막은 z로 끝나고 이 두 문자 사이에 적어도 하나의 문자가 존재하는 문자열을 찾기를 원한다면, 식 "j.+z"를 사용하면 된다. 만약 j와 z 사이에 문자가 없을수도 있다면, 앞에 나오는 식 대신 "j.*z"를 사용하면 된다.

패턴 매칭은 문자열 내에서 패턴을 만족시키는 가장 긴 문자열을 찾으려고 한다는 사실에 대해 주의해라.
만일 문자열 "jazjazjazjaz"가 주어지고 패턴 "j.*z"과 일치하는 문자열을 요구한다면, 하나의 "jaz" 문자열이 아닌 전체 문자열을 리턴한다. 이러한 특징을 "greedy behavior"라고 부른다.
만약 정규식에 다른 설정이 없다면, 이 특징이 정규식의 기본(default)이 된다.

이제 좀 더 복잡한 예제를 살펴보도록 하자.
소괄호 안에 여러개의 식을 사용하면, 여러문자 패턴들에 대해 일치하는 문자열을 찾게 할 수 있다.
예를 들어, j 다음에 z가 나타나는 문자열을 원하는 경우에, "(jz)" 패턴을 사용할 수 있다.
이렇게 홀로 사용되는 경우에는, 추가적인 기능을 활용할 수 없다. 즉, "jz"와 똑같게 된다.
그러나, 소괄호를 사용함으로써, 한정사를 사용할수 있게 되고 "jz" 패턴이 여러번 나타난다는 표현을 할 수 있다: "(jz)+".

패턴을 사용하는 또 다른 방법은 다른 문자 종류(class)들과 함께 사용하는 것이다.
특정 문자 종류를 사용하면, 각각의 문자들을 하나 하나 지정하는 대신에 가능한 문자들의 범위를 지정할 수도 있다.
예를 들어, j에서 z사이의 어떤 문자와도 일치하기를 원한다면, 대괄호를 사용하여 j-z의 범위를 지정할 수 있다:
"[j-z]". 또한 j와 z 사이에 적어도 한 문자와 일치하면서 이것이 여러번 나타날 수 있는 식이 필요하다면, 위의 식에 예를 들어 다음과 같이, "[j-z]+", 한정사를 추가할 수도 있다.

어떤 문자 종류들은 미리 정의되어져 있다. 이러한 문자 종류들은 공통으로 사용되어지므로, 공통의 단축 문자를 가지고 있다.
미리 정의된 몇개의 문자 종류는 다음과 같다.

\d    숫자: ([0-9])
\D    숫자가 아닌 문자: ([^0-9])
\s    공백 문자: [ \t\n\x0B\f\r]
\S    공백이 아닌 문자: [^\s]
\w    word 문자: [a-zA-Z_0-9]
\W    word가 아닌 문자: [^\w]

문자 종류에 있어서, ^ 문자는 식의 부정을 나타내기 위해서 사용되어짐을 주의하자.

다음은 POSIX 문자 셋이라 불리는 미리 정의된 문자 종류이다. 다음의 항목들은 POSIX 기술 명세서에서 가져왔고, 오직 US-ASCII 문자들과만 함께 동작한다.

\p{Lower}    알파벳 소문자: [a-z]
\p{Upper}    알파벳 대문자: [A-Z]
\p{ASCII}    모든 ASCII 문자: [\x00-\x7F]
\p{Alpha}    알파벳 문자: [\p{Lower}\p{Upper}]
\p{Digit}    10진법의 숫자: [0-9]
\p{Alnum}    문자숫자식의(alphanumeric) 문자: [\p{Alpha}\p{Digit}]
\p{Punct}    구두점(punctuation): !"#$%&'()*,-./:;<=>?@[\]^_`{|}~ 중의 하나
\p{Graph}    눈에 보이는 문자: [\p{Alnum}\p{Punct}]
\p{Print}    프린트 가능한 문자: [\p{Graph}]
\p{Blank}    공백(space) 또는 탭: [ \t]
\p{Cntrl}    제어 문자: [\x00-\x1F\x7F]
\p{XDigit}   16진법의 숫자: [0-9a-fA-F]
\p{Space}    흰공백(whitespace) 문자: [ \t\n\x0B\f\r]

마지막으로 언급되는 문자 종류의 집합은 경계를 나타내는 매처이다.
다시말해 문자(구체적으로 말하면 행, 단어 또는 패턴)들의 순서의 처음 또는 끝이 일치한다는 것을 의미한다.

^     행의 시작
$     행의 끝
\b    단어의 경계
\B    단어가 아닌 것의 경계
\A    입력의 시작
\G    이전 일치의 끝
\Z    마지막 종결자가 없을 경우 입력의 끝
\z    입력의 끝

문자 종류의 표현에 대해 이해하기 위해서 꼭 알아야 할 것은 \ 의 사용이다.
자바 문자열로 정규식을 만들때는, \ 문자를 사용하지 말아야 한다.
그렇지 않고 \ 문자를 사용하면, \ 다음에 오는 문자는 자바 컴파일러에 의해 특별하게 다루어 진다. \ 문자를 사용하기 위해서는, \\ 로 지정하면 된다. 즉, 문자열에 \\ 를 사용하면, 실제로 그 자리에 \ 문자가 오기를 원한다고 말하는 것이 된다.
예를 들어, 만약 문자숫자(alphanumeric) 문자로 이루어진 모든 문자열에 대한 패턴을 사용하기를 원하는 경우, 간단하게 \p{Alnum}* 만을 포함하는 문자열로는 충분하지 않다.
꼭 다음과 같이 \ 문자를 피해야만 한다.

boolean b = Pattern.matches("\\p{Alnum}*", someString);


이름이 함축하고 있는것처럼, Pattern 클래스는 패턴을 정의하기 위한 것이다.
패턴을 정의한다는 것은, 일치하기를 원하는 정규식을 정의하는 것이다.
패턴이 전체 문자열과 일치하는지를 알기 위해서 사용하는 것 보다는, 패턴이 문자열의 다음 부분과 일치하는지를 확인하기 위해서 사용하는 것이 일반적이다.

패턴을 사용하기 위해서는 먼저 패턴을 컴파일 해야 한다. compile 메서드를 사용하면 된다.

Pattern pattern = Pattern.compile(somePattern);


패턴 컴파일에는 약간의 시간이 필요하므로 한번만 하는 것이 현명하다.
Pattern 클래스의 matches 메서드는 매번 호출이 될때마다 패턴을 컴파일한다.
만약 패턴을 여러 번 사용해야 하는 경우라면, Pattern 클래스에서 Matcher 클래스를 얻고 Matcher 클래스를 사용함으로써 컴파일이 여러번 발생하는 것을 피할 수 있다.

패턴을 컴파일한 후에는, 명시된 문자열에 대한 Matcher 클래스를 얻을 수 있다.

Matcher matcher = pattern.matcher(someString);


Matcher 클래스는 전체 문자열을 검사하는 matches 메서드를 제공한다. 이 클래스는 패턴과 일치하는 것을 다음 부분(문자열의 시작이 아니라)에서부터 찾아주는 find() 메서드도 제공한다.

일치하는 것을 찾아낸 후에는, group 메서드를 사용해서 일치하는 것을 얻을 수 있다.

if (matcher.find()) {
  System.out.println(matcher.group());
}

또한 일치하는 것을 검색하고 바꾸기 위해서 matcher 클래스를 사용할 수 있다. 예를 들면, 문자열 내부에서 패턴과 일치하는 모든 부분을 바꾸기 위해서, 다음과 같이 사용할 수 있다.

String newString = matcher.replaceAll("replacement words");


이렇게 하면, 패턴이 발생하는 모든 부분은 교체 단어로 변경된다.

다음은 패턴 매칭에 대한 실제 예제이다.
다음 프로그램은 세 개의 명령줄 아규먼트를 필요로 한다.
첫 번째 인자는 검색하기 위한 문자열이다. 두번째는 검색하기 위한 패턴이다.
세번째는 교체 문자열이다. 검색하기 위한 문자열에서 패턴과 일치하는 모든 부분은 교체 단어로 변경된다.

import java.util.regex.*;

public class MyMatch {
  public static void main(String args[]) {

    if (args.length != 3) {
      System.out.println(
        "Pass in source string, pattern, " +
        "and replacement string");
      System.exit(-1);
    }

    String sourceString = args[0];
    String thePattern = args[1];
    String replacementString = args[2];

    Pattern pattern = Pattern.compile(thePattern);
    Matcher match = pattern.matcher(sourceString);
    if (match.find()) {
      System.out.println(
        match.replaceAll(replacementString));
    }
  }
}


예를 들어, 프로그램이 컴파일 되어 있다면 다음과 같이 실행할 수 있다.

java MyMatch "I want to be in lectures" "lect" "pict"

실행의 결과는 다음과 같다.

I want to be in pictures


그리고 이 프로그램을 실행할때, 명령줄에서 \ 문자의 사용은 불필요하다.
그 이유는 자바 컴파일러가 그러한 정보를 처리하지 않기 때문이다.
예를 들어, 만약 검색하기 위한 문자열이 

"I want to be in lectures\I want to be a star"

위와 같다면, 똑같은 패턴 ("lect")과 똑같은 교체 문자열("pict")을 이용하여 프로그램을 실행하면, 실행의 결과는 다음과 같다.

I want to be in pictures\I want to be a star

패턴 매칭과 정규식에 대한 자세한 정보는, 기술적인 기사(technical article)인 Regular Expressions and the Java Programming Language 를 참고하면 된다.

+ Recent posts