Compare commits
No commits in common. "3cfbf9cf6ea3f967b8150eaa4a183b4c129a84fd" and "6f7ae313ce4c50bda1e0473ae8adf55817b71649" have entirely different histories.
3cfbf9cf6e
...
6f7ae313ce
|
@ -117,11 +117,3 @@ Followup: Excess payloads were being added to the welcome page
|
|||
that caused HTTP "400" errors fetching resources. A fix has
|
||||
been made, although the ultimate solution will probably be more
|
||||
JSF-friendly.
|
||||
|
||||
## Minor release 2.0.1
|
||||
|
||||
This release can build an installable RPM for Red Hat-compatible
|
||||
systems, including CentOS and its relatives and Fedora.
|
||||
|
||||
Just run ``mvn install`` and the RPM will be produced under the
|
||||
``/target/rpm`` directory.
|
|
@ -1,96 +0,0 @@
|
|||
# GourmetJ application Architecture.
|
||||
|
||||
This is a Spring Boot self-hosted website built on standard JEE
|
||||
components like JavaServer Faces (JSF) and the Java Persistence
|
||||
Architecture (JPA). It is built and can be tested using Maven.
|
||||
|
||||
The Maven pom.xml file determines the build and what dependencies
|
||||
it has. The core dependencies and their versions are determined
|
||||
in the `dependencyManagement` section of the POM. Actual inclusion
|
||||
of dependencies is done in the `dependencies` section.
|
||||
|
||||
Of the 3 dependencyManagement dependencies, the JoinFaces BOM is
|
||||
the most important. It ensures that the proper version of Spring
|
||||
Boot and its dependencies is brought into the `dependencies` as
|
||||
well as allowing the option to select which JSF extension libraries
|
||||
are to be used. For this project, PrimeFaces is the primary JSF
|
||||
framework.
|
||||
|
||||
## Source Code components
|
||||
|
||||
Source code files come in 4 major types:
|
||||
|
||||
1. Spring/Spring Boot support
|
||||
1. JSF Backing Beans
|
||||
1. Data Persistence
|
||||
1. General Utilities (for example data format converters and parsers)
|
||||
|
||||
### Spring and Spring Boot Support
|
||||
|
||||
The application code root package is `com.mousetech.gourmetj`. The
|
||||
Spring configuration classes are located in this package. There
|
||||
are two of them: `SpringPrimeFacesApplication'java`, which is the
|
||||
main class for the app, and `SpringSecurityConfig.java`, which
|
||||
defines security. Security credentials (userid/password) are taken
|
||||
from an external password file whose location is defined by the
|
||||
`application.yml` properties file. There are no security roles, and
|
||||
all site pages are accessible without logging in except for the
|
||||
ones that can modify the database (create/edit recipe).
|
||||
|
||||
Secondary Spring characteristics come from the `WelcomePageRedirect.java`
|
||||
file which defines the site's welcome page (index.html).
|
||||
|
||||
A small bit of Spring Web in the `springweb.PicureController` class.
|
||||
This Controller resolves the image URLs for recipe images and
|
||||
thumbnails.
|
||||
|
||||
### JSF BackingBeans
|
||||
|
||||
The heart of the webapp is in JavaServer Faces Backing Beans which
|
||||
provide the Models for their corresponding View Template (.xhtml)
|
||||
files. The most important beans are the adminMain bean, which
|
||||
generates the recipe list page and the recipeDetail bean, which
|
||||
back the display and editing of a recipe. The CookieBean is
|
||||
a utility class that allows keeping search information in user-side
|
||||
cookies between user sessions and JSFUtils allows access to
|
||||
HTTP/Servlet soecific resources in a way that isolates them from
|
||||
the general application code. That allows platform independence
|
||||
and easier unit testing.
|
||||
|
||||
### Persistence
|
||||
|
||||
Persistence is done via JPA and has 3 layers:
|
||||
|
||||
1. Service layer. This layer fetches and updates "working sets" of
|
||||
related database entity objects. All service methods are
|
||||
Transactions. Working sets passed in or out of the service layer
|
||||
to the higher (business) layer of the app are detached objects,
|
||||
so the Service layer also ensures detaching and re-attaching
|
||||
(merging) as needed for the lower layer functions.
|
||||
|
||||
1. DAO layer. This layer does find/CRUD functions for a single
|
||||
Entity type or sometimes a parent/child Entity set. I've coded this
|
||||
using explicit logic in times past, but in this app, I've leveraged
|
||||
Spring's Repository feature to let it write the grunt code.
|
||||
|
||||
1. Model layer. This layer contains the actual Entity classes,
|
||||
which are all POJOs and have no executable logic except get/set.
|
||||
|
||||
### Utilities
|
||||
|
||||
Most utility services are in the ``utils`` package, except for
|
||||
JSFUtils, which serves as a liason between JSF server-independent
|
||||
code and server platform-specific services.
|
||||
|
||||
## Future considerations
|
||||
|
||||
There's probably still some lint in the POM and perhaps some dead
|
||||
code from deadend solutions that weren't viable. That's how apps
|
||||
are in the Real World.
|
||||
|
||||
Adding an I18N Bundle would probably be nice.
|
||||
|
||||
A Schema file was recently added to the project and it needs to
|
||||
be checked for functionality. A similar `data.sql` is probably
|
||||
needed to be able to fully set up a database from scratch. My
|
||||
current copy was simply cloned from an existing database.
|
76
pom.xml
76
pom.xml
|
@ -7,7 +7,7 @@
|
|||
|
||||
<groupId>com.mousetech.gourmet</groupId>
|
||||
<artifactId>gourmetj</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>0.3.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>GourmetJ</name>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.3</version>
|
||||
<version>3.2.2</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
@ -177,78 +177,6 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>rpm-maven-plugin</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-rpm</id>
|
||||
<goals>
|
||||
<goal>rpm</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<license>GPL (c) 2024, mousetech.com</license>
|
||||
<distribution>Gourmetj</distribution>
|
||||
<group>Application/Collectors</group>
|
||||
<packager>Tom Holloway</packager>
|
||||
<prefix>/usr/local</prefix>
|
||||
<changelogFile>src/changelog</changelogFile>
|
||||
<defineStatements>
|
||||
<defineStatement>_unpackaged_files_terminate_build 0</defineStatement>
|
||||
</defineStatements>
|
||||
<mappings>
|
||||
<mapping>
|
||||
<directory>/opt/mousetech/gourmetj</directory>
|
||||
<filemode>750</filemode>
|
||||
<username>gourmetj</username>
|
||||
<groupname>gourmetj</groupname>
|
||||
<sources>
|
||||
<source>
|
||||
<location>
|
||||
target/${project.build.finalName}.jar</location>
|
||||
</source>
|
||||
<softlinkSource>
|
||||
<destination>gourmetj.jar</destination>
|
||||
<location>
|
||||
${project.build.finalName}.jar</location>
|
||||
</softlinkSource>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/opt/mousetech/gourmetj</directory>
|
||||
<configuration>true</configuration>
|
||||
<filemode>440</filemode>
|
||||
<username>gourmetj</username>
|
||||
<groupname>gourmetj</groupname>
|
||||
<sources>
|
||||
<source>
|
||||
<location>src/main/conf</location>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
<mapping>
|
||||
<directory>/etc/systemd/system/</directory>
|
||||
<directoryIncluded>false</directoryIncluded>
|
||||
<configuration>true</configuration>
|
||||
<filemode>440</filemode>
|
||||
<sources>
|
||||
<source>
|
||||
<location>src/main/systemd/gourmetj.service</location>
|
||||
</source>
|
||||
</sources>
|
||||
</mapping>
|
||||
</mappings>
|
||||
<preinstallScriptlet>
|
||||
<script>echo "installing ${project.name} now"
|
||||
/usr/bin/getent passwd gourmetj || /usr/sbin/useradd -r -d /opt/mousetech/gourmetj -s /sbin/nologin gourmetj
|
||||
</script>
|
||||
</preinstallScriptlet>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# Application user password file
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
# THIS is the application properties used when testing in the IDE
|
||||
# or running stand-alone from the command line.
|
||||
# It augments/overrides application.yml in the JAR
|
||||
joinfaces.jsf.webapp-resources-directory=/resources
|
||||
server.servlet.session.timeout=30m
|
||||
|
||||
spring.thymeleaf.enabled=false
|
||||
server.error.whitelabel.enabled=false
|
||||
|
||||
spring.datasource.url=jdbc:mysql://dbase/recipes
|
||||
#jdbc:sqlite:${home}/recipes.db
|
||||
spring.datasource.username=recipes
|
||||
pring.datasource.password=yumyumyum
|
||||
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
|
||||
|
||||
#Runtime lies and says no longer required, but it defaults to MySQL5.5.0!:
|
||||
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
|
||||
#org.sqlite.hibernate.dialect.SQLiteDialect
|
||||
#spring.jpa.show-sql: true
|
||||
|
||||
# My special properties
|
||||
gourmet.password.file=.gourmetpw
|
||||
|
||||
# This will override aplication.yml
|
||||
#server.servlet.context-parameters.primefaces.THEME=le-frog
|
||||
|
||||
### HttpSession timeout (note effects on detailEdit idleMonitors)
|
||||
server.servlet.session.timeout=35m
|
|
@ -3,8 +3,6 @@ package com.mousetech.gourmetj;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.faces.model.SelectItem;
|
||||
import jakarta.inject.Named;
|
||||
|
@ -49,12 +47,5 @@ public class AppBean {
|
|||
new SelectItem(RecipeSearchType.rst_BY_INGREDIENT.ordinal(),
|
||||
"Ingredient"));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Value("${appVersion}")
|
||||
String appVersion = "Not Supplied.";
|
||||
|
||||
public String getAppVersion() {
|
||||
return appVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</h:head>
|
||||
<h:body>
|
||||
<h1>
|
||||
<ui:insert name="title">Gourmet Recipe Manager (web version #{appBean.appVersion})</ui:insert>
|
||||
<ui:insert name="title">Gourmet Recipe Manager (web version)</ui:insert>
|
||||
</h1>
|
||||
<p:ajaxStatus onerror="PF('opError').show()"/>
|
||||
<ui:insert name="content">
|
||||
|
@ -28,11 +28,10 @@
|
|||
</ui:insert>
|
||||
<!-- -->
|
||||
<div id="footer">
|
||||
<h:outputText value="Version #{appBean.appVersion}"/><br/>
|
||||
(C) 2021, 2024 Tim Holloway, Licensed under
|
||||
the Common Development and Distribution License (CDDL).
|
||||
<p>Based on Gourmet Recipe Manager by T.
|
||||
Hinkle.</p>
|
||||
Hinkle</p>
|
||||
</div>
|
||||
<!-- -->
|
||||
</h:body>
|
||||
|
|
|
@ -21,9 +21,6 @@ spring:
|
|||
ddl-auto: none
|
||||
database-platform: org.hibernate.dialect.MySQLDialect
|
||||
|
||||
# From Maven POM:
|
||||
appVersion: "@project.version@"
|
||||
|
||||
# Tracking-modes prevent URL rewrite jsessionid on Primecases
|
||||
# resources. Which causes "400" errors on initial main.jsf fetch.
|
||||
server:
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
[Unit]
|
||||
Description=Gourmet Recipe Manager
|
||||
Documentation=https://gogs.mousetech.com/gourmetj
|
||||
Requires=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=gourmetj
|
||||
WorkingDirectory=/opt/mousetech/gourmetj
|
||||
ExecStart=/usr/bin/java -jar gourmetj.jar
|
||||
#Restart=yes
|
||||
|
||||
[Install]
|
||||
Alias=gourmetj.service
|
||||
|
Loading…
Reference in New Issue
Block a user