From 532aff351212bf18a10f549550ab4bba69d7f740 Mon Sep 17 00:00:00 2001 From: Shinsuke Sugaya Date: Mon, 21 Jul 2025 15:31:09 +0900 Subject: [PATCH] Expand README and improve test coverage for CustomSystemHelper --- README.md | 194 +++++++++++++++++- .../webapp/helper/CustomSystemHelper.java | 13 ++ .../webapp/helper/CustomSystemHelperTest.java | 145 +++++++++++++ 3 files changed, 346 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dacf9b5..7e7e751 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,198 @@ -Example WebApp Plugin for Fess +# Fess WebApp Plugin Example + [![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) -========================== +[![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) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +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. ## Overview -This is a sample plugin for Fess webapp. +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. + +### Key Features + +- **Custom JSP Templates**: Provides custom design templates for search pages, navigation, and error handling +- **System Helper Extension**: Extends Fess's `SystemHelper` class with enhanced error handling and logging +- **Component Registration**: Demonstrates dependency injection configuration using LastaDi framework +- **Comprehensive UI Coverage**: Includes templates for search interface, user management, and error pages + +## Supported UI Components + +The plugin registers custom JSP templates for the following components: + +### Search Interface +- `index.jsp` - Main search page +- `search.jsp` - Search interface +- `searchResults.jsp` - Search results display +- `searchNoResult.jsp` - No results found page +- `searchOptions.jsp` - Search options +- `advance.jsp` - Advanced search +- `help.jsp` - Help page -## Download +### Navigation & Layout +- `header.jsp` - Page header +- `footer.jsp` - Page footer -See [Maven Repository](https://repo1.maven.org/maven2/org/codelibs/fess/fess-webapp-example/). +### Error Handling +- `error/error.jsp` - General error page +- `error/notFound.jsp` - 404 Not Found +- `error/system.jsp` - System error +- `error/redirect.jsp` - Redirect error +- `error/badRequest.jsp` - 400 Bad Request + +### User Interface +- `login/index.jsp` - Login page +- `profile/index.jsp` - User profile page + +### Cache Display +- `cache.hbs` - Cache display template (Handlebars) + +## Requirements + +- Java 21 or later +- Maven 3.6 or later +- Fess 15.0 or later ## Installation -See [Plugin](https://fess.codelibs.org/13.9/admin/plugin-guide.html) of Administration guide. +### From Maven Repository + +The plugin is available on Maven Central: + +```xml + + org.codelibs.fess + fess-webapp-example + 15.0.0 + +``` + +### Manual Installation + +1. Download the plugin JAR from [Maven Repository](https://repo1.maven.org/maven2/org/codelibs/fess/fess-webapp-example/) +2. Follow the [Plugin Installation Guide](https://fess.codelibs.org/admin/plugin-guide.html) in the Fess documentation + +### Building from Source + +```bash +git clone https://github.com/codelibs/fess-webapp-example.git +cd fess-webapp-example +mvn clean package +``` + +The compiled JAR will be available in the `target/` directory. + +## Development + +### Project Structure + +``` +src/ +├── main/ +│ ├── java/ +│ │ └── org/codelibs/fess/plugin/webapp/helper/ +│ │ └── CustomSystemHelper.java +│ └── resources/ +│ └── fess+systemHelper.xml +└── test/ + ├── java/ + │ └── org/codelibs/fess/plugin/webapp/helper/ + │ └── CustomSystemHelperTest.java + └── resources/ + └── test_app.xml +``` + +### Core Components + +#### CustomSystemHelper + +The main plugin class that extends Fess's `SystemHelper`: + +- **Location**: `src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java` +- **Function**: Overrides `parseProjectProperties()` with enhanced error handling +- **System Property**: Sets `fess.webapp.plugin=true` during initialization + +#### Configuration + +- **DI Configuration**: `src/main/resources/fess+systemHelper.xml` +- **Component Registration**: Maps UI component names to JSP template files +- **Test Configuration**: `src/test/resources/test_app.xml` + +### Building and Testing + +```bash +# Compile the project +mvn clean compile + +# Run tests +mvn test + +# Create package +mvn clean package + +# Format code +mvn formatter:format + +# Check license headers +mvn license:check + +# Generate documentation +mvn javadoc:javadoc +``` + +### Creating Custom Templates + +1. Extend the `CustomSystemHelper` class or create your own helper +2. Register your JSP templates in the DI configuration file +3. Ensure your plugin JAR includes the manifest entry: `Fess-WebAppJar=true` + +## Configuration + +The plugin uses LastaDi dependency injection framework. Template mappings are configured in `fess+systemHelper.xml`: + +```xml + + + "index" + "index.jsp" + + + +``` + +## Contributing + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/your-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin feature/your-feature`) +5. Create a Pull Request + +### Development Guidelines + +- Follow the existing code style and conventions +- Add appropriate test cases for new functionality +- Ensure all tests pass before submitting +- Update documentation as needed + +## License + +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. + +## Support + +- **Documentation**: [Fess Documentation](https://fess.codelibs.org/) +- **Plugin Guide**: [Plugin Installation Guide](https://fess.codelibs.org/admin/plugin-guide.html) +- **Issues**: [GitHub Issues](https://github.com/codelibs/fess-webapp-example/issues) +- **Discussions**: [GitHub Discussions](https://github.com/codelibs/fess-webapp-example/discussions) + +## Related Projects + +- [Fess](https://github.com/codelibs/fess) - The main Fess search server +- [LastaFlute](https://github.com/lastaflute/lastaflute) - Web framework used by Fess +- [DBFlute](https://github.com/dbflute/dbflute-core) - Database access framework + +--- +**CodeLibs Project** - https://www.codelibs.org/ \ No newline at end of file diff --git a/src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java b/src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java index 9076823..1174776 100644 --- a/src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java +++ b/src/main/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelper.java @@ -21,8 +21,21 @@ import org.apache.logging.log4j.Logger; import org.codelibs.fess.helper.SystemHelper; +/** + * Custom system helper for Fess webapp plugin that extends the default SystemHelper. + * This helper enables webapp plugin functionality by setting the appropriate system property + * and provides enhanced error handling for project properties parsing. + */ public class CustomSystemHelper extends SystemHelper { + /** + * Default constructor for CustomSystemHelper. + * Initializes the custom system helper with webapp plugin capabilities. + */ + public CustomSystemHelper() { + super(); + } + private static final Logger logger = LogManager.getLogger(CustomSystemHelper.class); @Override diff --git a/src/test/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelperTest.java b/src/test/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelperTest.java index 5f69702..15bfecb 100644 --- a/src/test/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelperTest.java +++ b/src/test/java/org/codelibs/fess/plugin/webapp/helper/CustomSystemHelperTest.java @@ -15,6 +15,14 @@ */ package org.codelibs.fess.plugin.webapp.helper; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.LoggerConfig; import org.codelibs.fess.mylasta.direction.FessConfig; import org.codelibs.fess.util.ComponentUtil; import org.dbflute.utflute.lastaflute.LastaFluteTestCase; @@ -64,4 +72,141 @@ public void tearDown() throws Exception { public void test_checkProperty() { assertEquals("true", System.getProperty("fess.webapp.plugin")); } + + public void test_parseProjectProperties_withValidPath() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + Path validPath = Paths.get("src/test/resources/test_app.xml"); + + // When + helper.parseProjectProperties(validPath); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_parseProjectProperties_withNullPath() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + + // When + helper.parseProjectProperties(null); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_parseProjectProperties_withNonExistentPath() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + Path nonExistentPath = Paths.get("non/existent/path/project.properties"); + + // When + helper.parseProjectProperties(nonExistentPath); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_parseProjectProperties_systemPropertyAlwaysSet() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + System.clearProperty("fess.webapp.plugin"); + assertNull("Property should be cleared initially", System.getProperty("fess.webapp.plugin")); + + // When + helper.parseProjectProperties(Paths.get("invalid/path")); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_parseProjectProperties_multipleCalls() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + Path testPath = Paths.get("src/test/resources/test_app.xml"); + + // When + helper.parseProjectProperties(testPath); + helper.parseProjectProperties(testPath); + helper.parseProjectProperties(null); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_inheritance_extendsSystemHelper() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + + // Then + assertTrue("CustomSystemHelper should extend SystemHelper", helper instanceof org.codelibs.fess.helper.SystemHelper); + } + + public void test_loggerConfiguration() { + // Given + LoggerContext context = (LoggerContext) LogManager.getContext(false); + Configuration config = context.getConfiguration(); + LoggerConfig loggerConfig = config.getLoggerConfig(CustomSystemHelper.class.getName()); + + // Then + assertNotNull("Logger should be configured", loggerConfig); + } + + public void test_parseProjectProperties_withEmptyPath() { + // Given + CustomSystemHelper helper = new CustomSystemHelper(); + Path emptyPath = Paths.get(""); + + // When + helper.parseProjectProperties(emptyPath); + + // Then + assertEquals("true", System.getProperty("fess.webapp.plugin")); + } + + public void test_parseProjectProperties_propertyPersistence() { + // Given + CustomSystemHelper helper1 = new CustomSystemHelper(); + CustomSystemHelper helper2 = new CustomSystemHelper(); + System.clearProperty("fess.webapp.plugin"); + + // When + helper1.parseProjectProperties(null); + String propertyAfterFirst = System.getProperty("fess.webapp.plugin"); + helper2.parseProjectProperties(null); + String propertyAfterSecond = System.getProperty("fess.webapp.plugin"); + + // Then + assertEquals("true", propertyAfterFirst); + assertEquals("true", propertyAfterSecond); + assertEquals("Property should remain consistent", propertyAfterFirst, propertyAfterSecond); + } + + public void test_parseProjectProperties_threadSafety() throws InterruptedException { + // Given + final CustomSystemHelper helper = new CustomSystemHelper(); + final int threadCount = 10; + Thread[] threads = new Thread[threadCount]; + final boolean[] results = new boolean[threadCount]; + + // When + for (int i = 0; i < threadCount; i++) { + final int index = i; + threads[i] = new Thread(() -> { + helper.parseProjectProperties(null); + results[index] = "true".equals(System.getProperty("fess.webapp.plugin")); + }); + threads[i].start(); + } + + for (Thread thread : threads) { + thread.join(); + } + + // Then + for (boolean result : results) { + assertTrue("All threads should see the property set", result); + } + } }