Skip to content

Commit 16bd68b

Browse files
committed
Update
1 parent 5fd3643 commit 16bd68b

File tree

2 files changed

+138
-59
lines changed

2 files changed

+138
-59
lines changed

_pages/en/docs/guides/introduce-asel.md

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,67 +9,107 @@ This guide will first explore 'Token Expressions', a basic feature of Aspectran,
99

1010
## 1. Token Expressions (Aspectran's Basic Feature)
1111

12-
Token expressions are simple expressions used to directly access specific data (Beans, attributes, parameters, etc.) within Aspectran's configuration. Each token has a defined syntax and role.
12+
Token expressions are simple yet powerful placeholders used to directly access specific data (Beans, attributes, parameters, etc.) within Aspectran's configuration. They act as bridges connecting your configuration to the runtime data.
1313

14-
| Token Type | Expression Syntax | Description |
15-
| :--- | :--- | :--- |
16-
| **Bean** | `#{beanId}` | References the Bean object with the ID `beanId`. |
17-
| **Attribute** | `@{attributeName}` | References the `attributeName` attribute of the current request. |
18-
| **Parameter** | `${parameterName}` | References the `parameterName` parameter of the current request. |
19-
| **Property** | `%{propertyName}` | References the `propertyName` environment property of the application. |
20-
| **Template** | `~{templateId}` | Renders the template with the ID `templateId` and **includes the result**. |
14+
| Token Type | Expression Syntax | Description | Usage Example |
15+
| :--- | :--- | :--- | :--- |
16+
| **Bean** | `#{beanId}` | References the Bean object with the ID `beanId`. | `#{userService}` |
17+
| **Attribute** | `@{attributeName}` | References the `attributeName` attribute of the current request context. Attributes are often used to pass data between actions. | `@{userInfo}` |
18+
| **Parameter** | `${parameterName}` | References the `parameterName` parameter of the current request (e.g., HTTP query parameter). | `${userId}` |
19+
| **Property** | `%{propertyName}` | References the `propertyName` environment property (e.g., from properties files or system properties). | `%{app.uploadDir}` |
20+
| **Template** | `~{templateId}` | Renders the template with the ID `templateId` and **includes the result**. | `~{emailTemplate}` |
2121

2222
### 1.1. Property Accessor: `^`
2323

24-
To access a specific property (Getter) of an object referenced by a token expression, use the `^` separator instead of `.`.
24+
To access a specific property (Getter) of an object referenced by a token expression, use the `^` separator instead of `.`. This is a unique feature of Aspectran to distinguish between dot-delimited IDs and property access.
2525

2626
* **Syntax**: `#{beanId^propertyName}`
27-
* **Explanation**: If you use `.`, the entire `bean.property` is recognized as a single ID. However, using `^` finds the `propertyName` property from the object referenced by the `beanId` token.
27+
* **Java Equivalent**: `getBean("beanId").getPropertyName()`
28+
* **Explanation**: If you use `.`, Aspectran interprets `bean.property` as the full ID of the bean. Using `^` explicitly tells Aspectran to "get the bean first, then access its property".
2829

2930
### 1.2. Setting Default Values
3031

31-
You can use the `:` separator to specify a default value to be used if a parameter or attribute is not present. This feature is mainly used within the `<item>` tag.
32+
You can use the `:` separator to specify a default value to be used if a parameter or attribute is null or missing. This prevents runtime errors and simplifies configuration.
3233

3334
```xml
3435
<attributes>
35-
<!-- If the 'name' parameter is not present, use "Jane" as the default value -->
36-
<item name="name">${name:Jane}</item>
36+
<!-- If 'page' parameter is missing, default to "1" -->
37+
<item name="page">${page:1}</item>
38+
39+
<!-- If 'sort' parameter is missing, default to "desc" -->
40+
<item name="sort">${sort:desc}</item>
3741
</attributes>
3842
```
3943

4044
### 1.3. Token Directives
4145

42-
You can specify the source of a value within a token expression using a colon (`:`). These are called token directives, and you can use the types defined in `TokenDirectiveType`.
46+
You can specify the source of a value within a token expression using a colon (`:`). These are called token directives.
4347

4448
| Directive | Description | Example |
4549
| :--- | :--- | :--- |
46-
| **`field`** | References the value of a static field. | `#{field:com.example.Constant^STATIC_FIELD}` |
50+
| **`field`** | References the value of a static field. | `#{field:java.awt.Color^RED}` |
4751
| **`method`** | Calls a static method and uses its return value. | `#{method:java.lang.System^currentTimeMillis}` |
4852
| **`class`** | References a static property (getter) of a class. | `#{class:java.io.File^separator}` |
49-
| **`classpath`** | References a property from a resource on the classpath (usually a .properties file). | `%{classpath:config/app.properties^db.url}` |
50-
| **`system`** | References a Java System Property value. | `%{system:java.version}` |
53+
| **`classpath`** | References a property from a resource on the classpath. | `%{classpath:config/jdbc.properties^jdbc.url}` |
54+
| **`system`** | References a Java System Property value. | `%{system:user.home}` |
5155

5256
## 2. AsEL Expressions (Token Expressions + OGNL)
5357

54-
AsEL expressions are used by combining the token expressions described above with OGNL expressions. This enables dynamic data processing and operations that go beyond simple value references. They can be used freely in places like the `@Value` annotation or templates.
58+
AsEL expressions combine the simplicity of token expressions with the power of OGNL (Object-Graph Navigation Language). This enables dynamic data processing, mathematical operations, and complex conditional logic directly in your configuration.
59+
60+
* **Bean Property Reference**
61+
```java
62+
// Accessing a property using the getter method
63+
@Value("%{properties^serverPort}")
64+
public int port;
65+
```
5566

56-
* **Bean Property Reference (using `^`)**
67+
* **String Concatenation**
5768
```java
58-
@Value("%{properties^property1}")
59-
public String property1;
69+
// Combining static strings with dynamic values
70+
@Value("'User: ' + @{user^name} + ' (ID: ' + ${userId} + ')'")
71+
public String userDescription;
6072
```
6173

62-
* **Combining Multiple Token Expressions and OGNL Operators**
74+
* **Arithmetic & Logical Operations**
75+
```java
76+
// Calculating values dynamically
77+
@Value("#{cart^totalPrice} * 1.1") // Adding 10% tax
78+
public double totalWithTax;
79+
```
80+
81+
* **Conditional Logic (Ternary Operator)**
82+
```java
83+
// Switching values based on conditions
84+
@Value("%{app.mode} == 'dev' ? 'DEBUG' : 'INFO'")
85+
public String logLevel;
86+
```
87+
88+
* **List and Map Access**
89+
```java
90+
// Accessing elements in a List or Map
91+
@Value("@{userList}[0]") // First user in the list
92+
public User firstUser;
93+
94+
@Value("@{configMap}['timeout']") // Value for key 'timeout'
95+
public int timeout;
96+
```
97+
98+
### 2.1. String Concatenation Rules
99+
100+
When an AsEL expression contains multiple tokens or a mix of literal text and tokens, the entire string is evaluated as a single OGNL expression. Therefore, you must strictly follow OGNL syntax, such as using single quotes (`'`) for literal text and the `+` operator for concatenation.
101+
102+
* **Correct Example**:
63103
```java
64-
@Value("#{properties^property1} + '/' + #{properties^property2}")
65-
public String combinedPath;
104+
@Value("'User: ' + @{user^name} + ' (ID: ' + ${userId} + ')'")
66105
```
106+
In this case, `@{user^name}` and `${userId}` are substituted with OGNL variables (e.g., `#__var1__`), and OGNL evaluates the combined string successfully.
67107
68-
* **Performing Conditional Logic with the Value of a Token Expression**
108+
* **Incorrect Example**:
69109
```java
70-
@Value("%{app.mode} == 'development'")
71-
public boolean isDevelopmentMode;
110+
@Value("User: @{user^name} (ID: ${userId})")
72111
```
112+
This will cause an `ExpressionParserException` because `User:` and `(ID:` are not valid OGNL syntax when used without quotes and operators.
73113
74114
## 3. Template Usage
75115
@@ -87,8 +127,8 @@ The `~{...}` token is used to render the template with the specified ID at the c
87127
```xml
88128
<!-- Built-in template rule definition -->
89129
<template id="welcomeMailTemplate" style="apon">
90-
|Hello, @{user^name}! Welcome to our service.
91-
|Your current point balance is #{pointBean^currentPoints}.
130+
|Hello, @{user^name}! Welcome to our service.
131+
|Your current point balance is #{pointBean^currentPoints}.
92132
</template>
93133

94134
<!-- Use the template by transforming it elsewhere -->

_pages/ko/docs/guides/introduce-asel.md

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,67 +9,107 @@ AsEL(Aspectran Expression Language)은 Aspectran 프레임워크에 내장된
99

1010
## 1. 토큰 표현식 (Aspectran 기본 기능)
1111

12-
토큰 표현식은 Aspectran의 설정 내에서 특정 데이터(Bean, 속성, 파라미터 등)에 직접 접근하기 위한 간단한 표현식입니다. 각 토큰은 정해진 구문과 역할을 가집니다.
12+
토큰 표현식은 Aspectran의 설정 내에서 특정 데이터(Bean, 속성, 파라미터 등)에 직접 접근하기 위한 간단하지만 강력한 플레이스홀더입니다. 설정 파일과 실행 시간(Runtime)의 데이터를 연결해 주는 다리 역할을 합니다.
1313

14-
| 토큰 종류 | 표현식 구문 | 설명 |
15-
| :--- | :--- | :--- |
16-
| **Bean** | `#{beanId}` | ID가 `beanId`인 Bean 객체를 참조합니다. |
17-
| **Attribute** | `@{attributeName}` | 현재 요청(Request)`attributeName` 어트리뷰트를 참조합니다. |
18-
| **Parameter** | `${parameterName}` | 현재 요청(Request)의 `parameterName` 파라미터를 참조합니다. |
19-
| **Property** | `%{propertyName}` | 애플리케이션의 `propertyName` 환경 속성을 참조합니다. |
20-
| **Template** | `~{templateId}` | ID가 `templateId`인 템플릿을 렌더링하고 **그 결과를 포함**시킵니다. |
14+
| 토큰 종류 | 표현식 구문 | 설명 | 사용 예시 |
15+
| :--- | :--- | :--- | :--- |
16+
| **Bean** | `#{beanId}` | ID가 `beanId`인 Bean 객체를 참조합니다. | `#{userService}` |
17+
| **Attribute** | `@{attributeName}` | 현재 요청(Request) 컨텍스트의 `attributeName` 속성을 참조합니다. 액션 간 데이터 전달에 주로 사용됩니다. | `@{userInfo}` |
18+
| **Parameter** | `${parameterName}` | 현재 요청의 `parameterName` 파라미터를 참조합니다. (예: HTTP 쿼리 파라미터) | `${userId}` |
19+
| **Property** | `%{propertyName}` | 애플리케이션의 `propertyName` 환경 속성을 참조합니다. (프로퍼티 파일이나 시스템 속성 등) | `%{app.uploadDir}` |
20+
| **Template** | `~{templateId}` | ID가 `templateId`인 템플릿을 렌더링하고 **그 결과를 포함**시킵니다. | `~{emailTemplate}` |
2121

2222
### 1.1. 프로퍼티(속성) 접근자: `^`
2323

24-
토큰 표현식이 참조하는 객체의 특정 속성(Getter)에 접근할 때는 `.` 대신 `^` 구분자를 사용합니다.
24+
토큰 표현식이 참조하는 객체의 특정 속성(Getter)에 접근할 때는 `.` 대신 `^` 구분자를 사용합니다. 이는 Aspectran만의 독특한 문법으로, 점(.)으로 구분된 ID와 실제 프로퍼티 접근을 명확히 구별하기 위함입니다.
2525

2626
* **구문**: `#{beanId^propertyName}`
27-
* **설명**: `.`를 사용하면 `bean.property` 전체가 하나의 ID로 인식되지만, `^`를 사용하면 `beanId` 토큰이 참조하는 객체에서 `propertyName` 속성을 찾습니다.
27+
* **Java 대응**: `getBean("beanId").getPropertyName()`
28+
* **설명**: 만약 `.`를 사용하면 Aspectran은 `bean.property` 전체를 하나의 빈 ID로 해석합니다. `^`를 사용함으로써 "빈을 먼저 찾고, 그 다음 프로퍼티에 접근하라"고 명시적으로 지시하는 것입니다.
2829

2930
### 1.2. 기본값 설정
3031

31-
`:` 구분자를 사용하여 파라미터나 어트리뷰트가 없을 경우 사용할 기본값을 지정할 수 있습니다. 이 기능은 주로 `<item>` 태그 내에서 사용됩니다.
32+
`:` 구분자를 사용하여 파라미터나 어트리뷰트가 없거나 null일 경우 사용할 기본값을 지정할 수 있습니다. 이를 통해 런타임 오류를 방지하고 설정을 단순화할 수 있습니다.
3233

3334
```xml
3435
<attributes>
35-
<!-- 'name' 파라미터가 없으면 "Jane"을 기본값으로 사용 -->
36-
<item name="name">${name:Jane}</item>
36+
<!-- 'page' 파라미터가 없으면 "1"을 기본값으로 사용 -->
37+
<item name="page">${page:1}</item>
38+
39+
<!-- 'sort' 파라미터가 없으면 "desc"를 기본값으로 사용 -->
40+
<item name="sort">${sort:desc}</item>
3741
</attributes>
3842
```
3943

4044
### 1.3. 토큰 지시자 (Token Directives)
4145

42-
토큰 표현식 내에서 콜론(`:`)을 사용하여 값의 출처를 명시할 수 있습니다. 이를 토큰 지시자라고 하며, `TokenDirectiveType`에 정의된 유형들을 사용할 수 있습니다.
46+
토큰 표현식 내에서 콜론(`:`)을 사용하여 값의 출처를 명시할 수 있습니다. 이를 토큰 지시자라고 합니다.
4347

4448
| 지시자 | 설명 | 예시 |
4549
| :--- | :--- | :--- |
46-
| **`field`** | 정적(static) 필드의 값을 참조합니다. | `#{field:com.example.Constant^STATIC_FIELD}` |
50+
| **`field`** | 정적(static) 필드의 값을 참조합니다. | `#{field:java.awt.Color^RED}` |
4751
| **`method`** | 정적(static) 메소드를 호출하고 반환 값을 사용합니다. | `#{method:java.lang.System^currentTimeMillis}` |
4852
| **`class`** | 클래스의 정적(static) 프로퍼티(getter)를 참조합니다. | `#{class:java.io.File^separator}` |
49-
| **`classpath`** | 클래스패스에 있는 자원(주로 .properties 파일)의 속성을 참조합니다. | `%{classpath:config/app.properties^db.url}` |
50-
| **`system`** | 자바 시스템 속성(System Property) 값을 참조합니다. | `%{system:java.version}` |
53+
| **`classpath`** | 클래스패스에 있는 자원(주로 .properties 파일)의 속성을 참조합니다. | `%{classpath:config/jdbc.properties^jdbc.url}` |
54+
| **`system`** | 자바 시스템 속성(System Property) 값을 참조합니다. | `%{system:user.home}` |
5155

5256
## 2. AsEL 표현식 (토큰 표현식 + OGNL)
5357

54-
AsEL 표현식은 위에서 설명한 토큰 표현식을 OGNL 표현식과 조합하여 사용합니다. 이를 통해 단순한 값 참조를 넘어, 동적인 데이터 처리와 연산이 가능해집니다. `@Value` 어노테이션이나 템플릿 등에서 자유롭게 사용할 수 있습니다.
58+
AsEL 표현식은 토큰 표현식의 간결함과 OGNL(Object-Graph Navigation Language)의 강력함을 결합한 것입니다. 이를 통해 설정 파일 내에서 직접 동적인 데이터 처리, 수학 연산, 복잡한 조건부 로직 등을 수행할 수 있습니다.
59+
60+
* **Bean 속성 참조**
61+
```java
62+
// Getter 메소드를 통한 속성 값 참조
63+
@Value("%{properties^serverPort}")
64+
public int port;
65+
```
66+
67+
* **문자열 결합**
68+
```java
69+
// 정적 문자열과 동적 값의 결합
70+
@Value("'사용자: ' + @{user^name} + ' (ID: ' + ${userId} + ')'")
71+
public String userDescription;
72+
```
73+
74+
* **산술 및 논리 연산**
75+
```java
76+
// 값을 동적으로 계산
77+
@Value("#{cart^totalPrice} * 1.1") // 10% 세금 추가
78+
public double totalWithTax;
79+
```
5580

56-
* **Bean 속성 참조 (`^` 사용)**
81+
* **조건부 로직 (삼항 연산자)**
5782
```java
58-
@Value("%{properties^property1}")
59-
public String property1;
83+
// 조건에 따라 다른 값 사용
84+
@Value("%{app.mode} == 'dev' ? 'DEBUG' : 'INFO'")
85+
public String logLevel;
6086
```
6187

62-
* **여러 토큰 표현식과 OGNL 연산자 조합**
88+
* **리스트 및 맵 접근**
6389
```java
64-
@Value("#{properties^property1} + '/' + #{properties^property2}")
65-
public String combinedPath;
90+
// List나 Map의 요소에 접근
91+
@Value("@{userList}[0]") // 리스트의 첫 번째 사용자
92+
public User firstUser;
93+
94+
@Value("@{configMap}['timeout']") // 'timeout' 키에 해당하는 값
95+
public int timeout;
6696
```
6797

68-
* **토큰 표현식의 값으로 조건부 로직 수행**
98+
### 2.1. 문자열 결합 규칙
99+
100+
AsEL 표현식에 여러 개의 토큰이 포함되거나 일반 텍스트와 토큰이 혼합된 경우, 전체 문자열은 **하나의 OGNL 표현식**으로 평가됩니다. 따라서 일반 텍스트에는 작은따옴표(`'`)를 사용하고 결합에는 `+` 연산자를 사용하는 등 OGNL 문법을 엄격히 따라야 합니다.
101+
102+
* **올바른 예**:
69103
```java
70-
@Value("%{app.mode} == 'development'")
71-
public boolean isDevelopmentMode;
104+
@Value("'사용자: ' + @{user^name} + ' (ID: ' + ${userId} + ')'")
72105
```
106+
이 경우 `@{user^name}`과 `${userId}`는 OGNL 변수(예: `#__var1__`)로 치환되며, OGNL 엔진에 의해 전체 문자열이 성공적으로 결합됩니다.
107+
108+
* **잘못된 예**:
109+
```java
110+
@Value("사용자: @{user^name} (ID: ${userId})")
111+
```
112+
이 표현식은 `사용자:`와 `(ID:` 부분이 따옴표와 연산자 없이 사용되었기 때문에 OGNL 문법 오류(`ExpressionParserException`)를 발생시킵니다.
73113
74114
## 3. 템플릿 활용
75115
@@ -87,11 +127,10 @@ AsEL 표현식은 위에서 설명한 토큰 표현식을 OGNL 표현식과 조
87127
```xml
88128
<!-- 내장 템플릿 규칙 정의 -->
89129
<template id="welcomeMailTemplate" style="apon">
90-
|Hello, @{user^name}! Welcome to our service.
91-
|Your current point balance is #{pointBean^currentPoints}.
130+
|Hello, @{user^name}! Welcome to our service.
131+
|Your current point balance is #{pointBean^currentPoints}.
92132
</template>
93133
94-
95134
<!-- 다른 곳에서 템플릿을 변환(transform)하여 사용 -->
96135
<transform format="text">
97136
<template>~{welcomeMailTemplate}</template>

0 commit comments

Comments
 (0)