Skip to content

Commit 5df13da

Browse files
authored
Expand README and improve test coverage for CustomSystemHelper (#1)
1 parent 7795991 commit 5df13da

3 files changed

Lines changed: 346 additions & 6 deletions

File tree

README.md

Lines changed: 188 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,198 @@
1-
Example WebApp Plugin for Fess
1+
# Fess WebApp Plugin Example
2+
23
[![Java CI with Maven](https://github.com/codelibs/fess-webapp-example/actions/workflows/maven.yml/badge.svg)](https://github.com/codelibs/fess-webapp-example/actions/workflows/maven.yml)
3-
==========================
4+
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.codelibs.fess/fess-webapp-example/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.codelibs.fess/fess-webapp-example)
5+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6+
7+
A demonstration WebApp plugin for [Fess](https://fess.codelibs.org/), showing how to create custom JSP design templates and extend the search engine's web interface functionality.
48

59
## Overview
610

7-
This is a sample plugin for Fess webapp.
11+
This plugin demonstrates how to extend Fess's web application layer by providing custom JSP templates for various UI components. It serves as a practical example for developers who want to create their own custom web interfaces for Fess search applications.
12+
13+
### Key Features
14+
15+
- **Custom JSP Templates**: Provides custom design templates for search pages, navigation, and error handling
16+
- **System Helper Extension**: Extends Fess's `SystemHelper` class with enhanced error handling and logging
17+
- **Component Registration**: Demonstrates dependency injection configuration using LastaDi framework
18+
- **Comprehensive UI Coverage**: Includes templates for search interface, user management, and error pages
19+
20+
## Supported UI Components
21+
22+
The plugin registers custom JSP templates for the following components:
23+
24+
### Search Interface
25+
- `index.jsp` - Main search page
26+
- `search.jsp` - Search interface
27+
- `searchResults.jsp` - Search results display
28+
- `searchNoResult.jsp` - No results found page
29+
- `searchOptions.jsp` - Search options
30+
- `advance.jsp` - Advanced search
31+
- `help.jsp` - Help page
832

9-
## Download
33+
### Navigation & Layout
34+
- `header.jsp` - Page header
35+
- `footer.jsp` - Page footer
1036

11-
See [Maven Repository](https://repo1.maven.org/maven2/org/codelibs/fess/fess-webapp-example/).
37+
### Error Handling
38+
- `error/error.jsp` - General error page
39+
- `error/notFound.jsp` - 404 Not Found
40+
- `error/system.jsp` - System error
41+
- `error/redirect.jsp` - Redirect error
42+
- `error/badRequest.jsp` - 400 Bad Request
43+
44+
### User Interface
45+
- `login/index.jsp` - Login page
46+
- `profile/index.jsp` - User profile page
47+
48+
### Cache Display
49+
- `cache.hbs` - Cache display template (Handlebars)
50+
51+
## Requirements
52+
53+
- Java 21 or later
54+
- Maven 3.6 or later
55+
- Fess 15.0 or later
1256

1357
## Installation
1458

15-
See [Plugin](https://fess.codelibs.org/13.9/admin/plugin-guide.html) of Administration guide.
59+
### From Maven Repository
60+
61+
The plugin is available on Maven Central:
62+
63+
```xml
64+
<dependency>
65+
<groupId>org.codelibs.fess</groupId>
66+
<artifactId>fess-webapp-example</artifactId>
67+
<version>15.0.0</version>
68+
</dependency>
69+
```
70+
71+
### Manual Installation
72+
73+
1. Download the plugin JAR from [Maven Repository](https://repo1.maven.org/maven2/org/codelibs/fess/fess-webapp-example/)
74+
2. Follow the [Plugin Installation Guide](https://fess.codelibs.org/admin/plugin-guide.html) in the Fess documentation
75+
76+
### Building from Source
77+
78+
```bash
79+
git clone https://github.com/codelibs/fess-webapp-example.git
80+
cd fess-webapp-example
81+
mvn clean package
82+
```
83+
84+
The compiled JAR will be available in the `target/` directory.
85+
86+
## Development
87+
88+
### Project Structure
89+
90+
```
91+
src/
92+
├── main/
93+
│ ├── java/
94+
│ │ └── org/codelibs/fess/plugin/webapp/helper/
95+
│ │ └── CustomSystemHelper.java
96+
│ └── resources/
97+
│ └── fess+systemHelper.xml
98+
└── test/
99+
├── java/
100+
│ └── org/codelibs/fess/plugin/webapp/helper/
101+
│ └── CustomSystemHelperTest.java
102+
└── resources/
103+
└── test_app.xml
104+
```
105+
106+
### Core Components
107+
108+
#### CustomSystemHelper
109+
110+
The main plugin class that extends Fess's `SystemHelper`:
111+
112+
- **Location**: `src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java`
113+
- **Function**: Overrides `parseProjectProperties()` with enhanced error handling
114+
- **System Property**: Sets `fess.webapp.plugin=true` during initialization
115+
116+
#### Configuration
117+
118+
- **DI Configuration**: `src/main/resources/fess+systemHelper.xml`
119+
- **Component Registration**: Maps UI component names to JSP template files
120+
- **Test Configuration**: `src/test/resources/test_app.xml`
121+
122+
### Building and Testing
123+
124+
```bash
125+
# Compile the project
126+
mvn clean compile
127+
128+
# Run tests
129+
mvn test
130+
131+
# Create package
132+
mvn clean package
133+
134+
# Format code
135+
mvn formatter:format
136+
137+
# Check license headers
138+
mvn license:check
139+
140+
# Generate documentation
141+
mvn javadoc:javadoc
142+
```
143+
144+
### Creating Custom Templates
145+
146+
1. Extend the `CustomSystemHelper` class or create your own helper
147+
2. Register your JSP templates in the DI configuration file
148+
3. Ensure your plugin JAR includes the manifest entry: `Fess-WebAppJar=true`
149+
150+
## Configuration
151+
152+
The plugin uses LastaDi dependency injection framework. Template mappings are configured in `fess+systemHelper.xml`:
153+
154+
```xml
155+
<component name="systemHelper" class="org.codelibs.fess.plugin.webapp.helper.CustomSystemHelper">
156+
<postConstruct name="addDesignJspFileName">
157+
<arg>"index"</arg>
158+
<arg>"index.jsp"</arg>
159+
</postConstruct>
160+
<!-- Additional template mappings... -->
161+
</component>
162+
```
163+
164+
## Contributing
165+
166+
1. Fork the repository
167+
2. Create a feature branch (`git checkout -b feature/your-feature`)
168+
3. Commit your changes (`git commit -am 'Add some feature'`)
169+
4. Push to the branch (`git push origin feature/your-feature`)
170+
5. Create a Pull Request
171+
172+
### Development Guidelines
173+
174+
- Follow the existing code style and conventions
175+
- Add appropriate test cases for new functionality
176+
- Ensure all tests pass before submitting
177+
- Update documentation as needed
178+
179+
## License
180+
181+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
182+
183+
## Support
184+
185+
- **Documentation**: [Fess Documentation](https://fess.codelibs.org/)
186+
- **Plugin Guide**: [Plugin Installation Guide](https://fess.codelibs.org/admin/plugin-guide.html)
187+
- **Issues**: [GitHub Issues](https://github.com/codelibs/fess-webapp-example/issues)
188+
- **Discussions**: [GitHub Discussions](https://github.com/codelibs/fess-webapp-example/discussions)
189+
190+
## Related Projects
191+
192+
- [Fess](https://github.com/codelibs/fess) - The main Fess search server
193+
- [LastaFlute](https://github.com/lastaflute/lastaflute) - Web framework used by Fess
194+
- [DBFlute](https://github.com/dbflute/dbflute-core) - Database access framework
195+
196+
---
16197

198+
**CodeLibs Project** - https://www.codelibs.org/

src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,21 @@
2121
import org.apache.logging.log4j.Logger;
2222
import org.codelibs.fess.helper.SystemHelper;
2323

24+
/**
25+
* Custom system helper for Fess webapp plugin that extends the default SystemHelper.
26+
* This helper enables webapp plugin functionality by setting the appropriate system property
27+
* and provides enhanced error handling for project properties parsing.
28+
*/
2429
public class CustomSystemHelper extends SystemHelper {
2530

31+
/**
32+
* Default constructor for CustomSystemHelper.
33+
* Initializes the custom system helper with webapp plugin capabilities.
34+
*/
35+
public CustomSystemHelper() {
36+
super();
37+
}
38+
2639
private static final Logger logger = LogManager.getLogger(CustomSystemHelper.class);
2740

2841
@Override

src/test/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelperTest.java

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
*/
1616
package org.codelibs.fess.plugin.webapp.helper;
1717

18+
import java.nio.file.Path;
19+
import java.nio.file.Paths;
20+
21+
import org.apache.logging.log4j.Level;
22+
import org.apache.logging.log4j.LogManager;
23+
import org.apache.logging.log4j.core.LoggerContext;
24+
import org.apache.logging.log4j.core.config.Configuration;
25+
import org.apache.logging.log4j.core.config.LoggerConfig;
1826
import org.codelibs.fess.mylasta.direction.FessConfig;
1927
import org.codelibs.fess.util.ComponentUtil;
2028
import org.dbflute.utflute.lastaflute.LastaFluteTestCase;
@@ -64,4 +72,141 @@ public void tearDown() throws Exception {
6472
public void test_checkProperty() {
6573
assertEquals("true", System.getProperty("fess.webapp.plugin"));
6674
}
75+
76+
public void test_parseProjectProperties_withValidPath() {
77+
// Given
78+
CustomSystemHelper helper = new CustomSystemHelper();
79+
Path validPath = Paths.get("src/test/resources/test_app.xml");
80+
81+
// When
82+
helper.parseProjectProperties(validPath);
83+
84+
// Then
85+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
86+
}
87+
88+
public void test_parseProjectProperties_withNullPath() {
89+
// Given
90+
CustomSystemHelper helper = new CustomSystemHelper();
91+
92+
// When
93+
helper.parseProjectProperties(null);
94+
95+
// Then
96+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
97+
}
98+
99+
public void test_parseProjectProperties_withNonExistentPath() {
100+
// Given
101+
CustomSystemHelper helper = new CustomSystemHelper();
102+
Path nonExistentPath = Paths.get("non/existent/path/project.properties");
103+
104+
// When
105+
helper.parseProjectProperties(nonExistentPath);
106+
107+
// Then
108+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
109+
}
110+
111+
public void test_parseProjectProperties_systemPropertyAlwaysSet() {
112+
// Given
113+
CustomSystemHelper helper = new CustomSystemHelper();
114+
System.clearProperty("fess.webapp.plugin");
115+
assertNull("Property should be cleared initially", System.getProperty("fess.webapp.plugin"));
116+
117+
// When
118+
helper.parseProjectProperties(Paths.get("invalid/path"));
119+
120+
// Then
121+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
122+
}
123+
124+
public void test_parseProjectProperties_multipleCalls() {
125+
// Given
126+
CustomSystemHelper helper = new CustomSystemHelper();
127+
Path testPath = Paths.get("src/test/resources/test_app.xml");
128+
129+
// When
130+
helper.parseProjectProperties(testPath);
131+
helper.parseProjectProperties(testPath);
132+
helper.parseProjectProperties(null);
133+
134+
// Then
135+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
136+
}
137+
138+
public void test_inheritance_extendsSystemHelper() {
139+
// Given
140+
CustomSystemHelper helper = new CustomSystemHelper();
141+
142+
// Then
143+
assertTrue("CustomSystemHelper should extend SystemHelper", helper instanceof org.codelibs.fess.helper.SystemHelper);
144+
}
145+
146+
public void test_loggerConfiguration() {
147+
// Given
148+
LoggerContext context = (LoggerContext) LogManager.getContext(false);
149+
Configuration config = context.getConfiguration();
150+
LoggerConfig loggerConfig = config.getLoggerConfig(CustomSystemHelper.class.getName());
151+
152+
// Then
153+
assertNotNull("Logger should be configured", loggerConfig);
154+
}
155+
156+
public void test_parseProjectProperties_withEmptyPath() {
157+
// Given
158+
CustomSystemHelper helper = new CustomSystemHelper();
159+
Path emptyPath = Paths.get("");
160+
161+
// When
162+
helper.parseProjectProperties(emptyPath);
163+
164+
// Then
165+
assertEquals("true", System.getProperty("fess.webapp.plugin"));
166+
}
167+
168+
public void test_parseProjectProperties_propertyPersistence() {
169+
// Given
170+
CustomSystemHelper helper1 = new CustomSystemHelper();
171+
CustomSystemHelper helper2 = new CustomSystemHelper();
172+
System.clearProperty("fess.webapp.plugin");
173+
174+
// When
175+
helper1.parseProjectProperties(null);
176+
String propertyAfterFirst = System.getProperty("fess.webapp.plugin");
177+
helper2.parseProjectProperties(null);
178+
String propertyAfterSecond = System.getProperty("fess.webapp.plugin");
179+
180+
// Then
181+
assertEquals("true", propertyAfterFirst);
182+
assertEquals("true", propertyAfterSecond);
183+
assertEquals("Property should remain consistent", propertyAfterFirst, propertyAfterSecond);
184+
}
185+
186+
public void test_parseProjectProperties_threadSafety() throws InterruptedException {
187+
// Given
188+
final CustomSystemHelper helper = new CustomSystemHelper();
189+
final int threadCount = 10;
190+
Thread[] threads = new Thread[threadCount];
191+
final boolean[] results = new boolean[threadCount];
192+
193+
// When
194+
for (int i = 0; i < threadCount; i++) {
195+
final int index = i;
196+
threads[i] = new Thread(() -> {
197+
helper.parseProjectProperties(null);
198+
results[index] = "true".equals(System.getProperty("fess.webapp.plugin"));
199+
});
200+
threads[i].start();
201+
}
202+
203+
for (Thread thread : threads) {
204+
thread.join();
205+
}
206+
207+
// Then
208+
for (boolean result : results) {
209+
assertTrue("All threads should see the property set", result);
210+
}
211+
}
67212
}

0 commit comments

Comments
 (0)