commit f6aa1b06d258e8729b1388c714967e6445d2d721 Author: heshunme Date: Sun Jul 14 01:35:24 2024 +0800 成功迁移到现代化的maven中 新增数据库服务类,待完善。 ProjectBean待去除无效代码 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..97f93a0 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,15 @@ + + + + + derby.embedded + true + org.apache.derby.jdbc.EmbeddedDriver + jdbc:derby:$PROJECT_DIR$/../tomcat9/bin/testDB + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..bdc1db1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..a3a8727 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..40ca015 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ae8392b --- /dev/null +++ b/pom.xml @@ -0,0 +1,121 @@ + + + 4.0.0 + + com.web + web_assignment + 1.0-SNAPSHOT + web_assignment + war + + + UTF-8 + 1.8 + 1.8 + 5.9.2 + + + + + javax.validation + validation-api + 2.0.1.Final + provided + + + javax.enterprise + cdi-api + 2.0.SP1 + provided + + + javax.ejb + javax.ejb-api + 3.2.2 + provided + + + javax.json.bind + javax.json.bind-api + 1.0 + provided + + + javax.json + javax.json-api + 1.1.4 + provided + + + javax.persistence + javax.persistence-api + 2.2 + provided + + + javax.faces + javax.faces-api + 2.2 + provided + + + javax.annotation + javax.annotation-api + 1.3.2 + provided + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + com.zaxxer + HikariCP + 5.1.0 + + + + + + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.derby + 10.14.2.0_2 + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.2 + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + \ No newline at end of file diff --git a/src/main/java/com/web/web_assignment/DatabaseService.java b/src/main/java/com/web/web_assignment/DatabaseService.java new file mode 100644 index 0000000..af18bda --- /dev/null +++ b/src/main/java/com/web/web_assignment/DatabaseService.java @@ -0,0 +1,307 @@ +package com.web.web_assignment; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + + +public class DatabaseService { + private HikariDataSource dataSource; + + public DatabaseService() { + init(); + } + + public void init() { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:derby:testDB;create=true"); + config.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver"); + dataSource = new HikariDataSource(config); + + // Initialize the database + try (Connection conn = getConnection()) { + createTables(conn); + } catch (SQLException e) { + e.printStackTrace(); + } + try { + String sql = "SELECT * FROM users"; + try (Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + ResultSet rs = stmt.executeQuery(); + int count = 0; + while (rs.next()) { + count++; + } + if (count == 0) { + loadFakeUsers(); + loadAndSaveFakeProjects(); + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + public void close() { + if (dataSource != null) { + dataSource.close(); + } + } + + public Connection getConnection() throws SQLException { + return dataSource.getConnection(); + } + + private void createTables(Connection conn) throws SQLException { + String createUsersTable = "CREATE TABLE users (" + + "id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " + + "username VARCHAR(255) UNIQUE, " + + "password VARCHAR(255))"; + + String createProjectsTable = "CREATE TABLE projects (" + + "id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " + + "user_id INT, " + + "title VARCHAR(255), " + + "summary VARCHAR(255), " + + "description CLOB, " + + "keywords VARCHAR(255), " + + "type VARCHAR(255), " + + "collaborators VARCHAR(255), " + + "link VARCHAR(255), " + + "time VARCHAR(255), " + + "FOREIGN KEY (user_id) REFERENCES users(id))"; + + try { + conn.createStatement().executeUpdate(createUsersTable); + } catch (SQLException e) { + e.printStackTrace(); + } + + try { + conn.createStatement().executeUpdate(createProjectsTable); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + + public List getProjectsByUser(String username) { + List projects = new ArrayList<>(); + String sql = "SELECT p.* FROM projects p JOIN users u ON p.user_id = u.id WHERE u.username = ?"; + + try (Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, username); + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + Project project = new Project( + rs.getString("title"), + rs.getString("summary"), + rs.getString("description"), + Arrays.asList(rs.getString("keywords").split(", ")), + rs.getString("type"), + Arrays.asList(rs.getString("collaborators").split(", ")), + rs.getString("link"), + rs.getString("time") + ); + projects.add(project); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return projects; + } + + public void registerUser(String username, String password) throws SQLException { + String sql = "INSERT INTO users (username, password) VALUES (?, ?)"; + try (Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, username); + stmt.setString(2, password); + stmt.executeUpdate(); + } + } + + public boolean validateUser(String username, String password) throws SQLException { + String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; + try (Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, username); + stmt.setString(2, password); + ResultSet rs = stmt.executeQuery(); + return rs.next(); + } + } + + public void saveProjects(String username, List projects) throws SQLException { + try (Connection conn = getConnection()) { + for (Project project : projects) { + String checkSql = "SELECT COUNT(*) FROM projects WHERE title = ? AND user_id = (SELECT id FROM users WHERE username = ?)"; + try (PreparedStatement checkStmt = conn.prepareStatement(checkSql)) { + checkStmt.setString(1, project.getTitle()); + checkStmt.setString(2, username); + ResultSet rs = checkStmt.executeQuery(); + rs.next(); + int count = rs.getInt(1); + + if (count > 0) { + String updateSql = "UPDATE projects SET summary = ?, description = ?, keywords = ?, type = ?, collaborators = ?, link = ?, time = ? WHERE title = ? AND user_id = (SELECT id FROM users WHERE username = ?)"; + try (PreparedStatement updateStmt = conn.prepareStatement(updateSql)) { + updateStmt.setString(1, project.getSummary()); + updateStmt.setString(2, project.getDescription()); + updateStmt.setString(3, String.join(", ", project.getKeywords())); + updateStmt.setString(4, project.getType()); + updateStmt.setString(5, String.join(", ", project.getCollaborators())); + updateStmt.setString(6, project.getLink()); + updateStmt.setString(7, project.getTime()); + updateStmt.setString(8, project.getTitle()); + updateStmt.setString(9, username); + updateStmt.executeUpdate(); + } + } else { + String insertSql = "INSERT INTO projects (user_id, title, summary, description, keywords, type, collaborators, link, time) VALUES ((SELECT id FROM users WHERE username = ?), ?, ?, ?, ?, ?, ?, ?, ?)"; + try (PreparedStatement insertStmt = conn.prepareStatement(insertSql)) { + insertStmt.setString(1, username); + insertStmt.setString(2, project.getTitle()); + insertStmt.setString(3, project.getSummary()); + insertStmt.setString(4, project.getDescription()); + insertStmt.setString(5, String.join(", ", project.getKeywords())); + insertStmt.setString(6, project.getType()); + insertStmt.setString(7, String.join(", ", project.getCollaborators())); + insertStmt.setString(8, project.getLink()); + insertStmt.setString(9, project.getTime()); + insertStmt.executeUpdate(); + } + } + } + } + } + } + + public void loadFakeUsers() throws SQLException { + registerUser("admin", "admin"); + registerUser("user", "user"); + } + + public void loadAndSaveFakeProjects() throws SQLException { + ArrayList projects = new ArrayList<>(); + + Project project1 = new Project( + "Mental Abacus Calculation Practice Tool", + "A tool for practicing mental abacus calculations", + "Created a mental abacus calculation practice tool using Python during high school.", + Arrays.asList("Python", "Abacus", "Calculation"), + "Personal Project", + new ArrayList<>(), + "https://github.com/heshunme/Abacus-Training-tool", + "2020-03" + ); + + Project project2 = new Project( + "Web fiction Crawler", + "A tool for crawling web fiction", + "Developed a novel web fiction crawler using Python during high school.", + List.of(new String[]{"Python", "Crawler", "Web Fiction"}), + "Personal Project", + new ArrayList<>(), + "", + "2022-05" + ); + + Project project3 = new Project( + "Cloud Factory Management", + "A project management system", + "Accomplished an assignment about a project management system named 'Cloud Factory Management' using Java during university studies.", + List.of(new String[]{"Java", "Project Management"}), + "Assignment", + new ArrayList<>(), + "", + "2023-06" + ); + + Project project4 = new Project( + "Weather Forecast Application", + "An Android weather forecast application", + "Developed a weather forecast application in my Android course during university studies.", + List.of(new String[]{"Android", "Weather", "Java"}), + "Assignment", + new ArrayList<>(), + "", + "2024-06" + ); + + Project project5 = new Project( + "Infrared Communication Protocol", + "A simple protocol and drivers for infrared communication", + "Developed a simple protocol and corresponding drivers for infrared communication using a Raspberry Pi with Python.", + List.of(new String[]{"Python", "Raspberry Pi", "Infrared Communication"}), + "Personal Project& Assignment", + new ArrayList<>(), + "", + "2023-04" + ); + + Project project6 = new Project( + "Plant Care Box", + "A plant care system using Raspberry Pi", + "Created a plant care box for the Raspberry Pi, utilizing sensors to maintain a stable environment for plants through control of a fan, stepper motor, and water pump. Built a simple control webpage with Django for remote hardware control and RTMP video streaming.", + List.of(new String[]{"Python", "Raspberry Pi", "Django", "Sensors", "RTMP"}), + "Assignment", + List.of(new String[]{"Xinyang Tang", "Haochen Shi", "Zihang Yu"}), + "", + "2023-04" + ); + + Project project7 = new Project( + "Large Language Models Deployment", + "Locally deployed and tested multiple LLM projects", + "Locally deployed and tested multiple Large Language Models (LLM) projects, including ChatGLM-6B, llama2, llama3, ChatGLM3-6B, Qwen1, Qwen1.5, Qwen2, Phi3-mini, and several versions of Stable Diffusion for AI image generation projects.", + List.of(new String[]{"LLM", "AI", "ChatGLM", "Llama", "Stable Diffusion"}), + "Personal Project", + new ArrayList<>(), + "", + "2022-12~...(ongoing)" + ); + + Project project8 = new Project( + "AI Voice Synthesis Projects", + "Worked on AI voice synthesis projects", + "Worked on AI voice synthesis projects such as so-vits-svc and GPT-SoVITS.Just for fun", + List.of(new String[]{"AI", "Voice Synthesis", "so-vits-svc", "GPT-SoVITS"}), + "Personal Project", + new ArrayList<>(), + "", + "2024-02" + ); + + Project project9 = new Project( + "Video Download and Analysis Project", + "A project for downloading, analyzing, and storing videos", + "Currently working on a project that allows downloading videos from user-specified websites, performing OCR and ASR locally, correcting errors, vectorizing data into SVG, and storing it for local LLM queries.", + List.of(new String[]{"Video Download", "OCR", "ASR", "SVG", "LLM"}), + "Personal Project", + new ArrayList<>(), + "", + "2024-05~...(ongoing)" + ); + + projects.add(project1); + projects.add(project2); + projects.add(project3); + projects.add(project4); + projects.add(project5); + projects.add(project6); + projects.add(project7); + projects.add(project8); + projects.add(project9); + saveProjects("admin", projects); + } +} \ No newline at end of file diff --git a/src/main/java/com/web/web_assignment/Project.java b/src/main/java/com/web/web_assignment/Project.java new file mode 100644 index 0000000..ebb8a5c --- /dev/null +++ b/src/main/java/com/web/web_assignment/Project.java @@ -0,0 +1,95 @@ +package com.web.web_assignment; + +import java.util.List; + +public class Project { + private String title; + private String summary; + private String description; + private List keywords; + private String type; + private List collaborators; + private String link; + private String time; + + public Project(String title, String summary, String description, List keywords, String type, List collaborators, String link, String time) { + this.title = title; + this.summary = summary; + this.description = description; + this.keywords = keywords; + this.type = type; + this.collaborators = collaborators; + this.link = link; + this.time = time; + } + + public Project(){ + + } + + // Getters and setters for each field + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getKeywords() { + return keywords; + } + + public void setKeywords(List keywords) { + this.keywords = keywords; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getCollaborators() { + return collaborators; + } + + public void setCollaborators(List collaborators) { + this.collaborators = collaborators; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } +} + diff --git a/src/main/java/com/web/web_assignment/ProjectBean.java b/src/main/java/com/web/web_assignment/ProjectBean.java new file mode 100644 index 0000000..30f9d90 --- /dev/null +++ b/src/main/java/com/web/web_assignment/ProjectBean.java @@ -0,0 +1,248 @@ +package com.web.web_assignment; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.faces.application.FacesMessage; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.SessionScoped; +import javax.faces.context.FacesContext; +import java.io.Serializable; +import java.sql.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@ManagedBean +@SessionScoped +public class ProjectBean implements Serializable { + private final DatabaseService databaseService = new DatabaseService(); + private List projects; // List to store all projects + private Project project; // Current project being worked on + private String username = "admin"; + private String password; + public String projectKeywords = ""; // String to hold project keywords + public String projectCollaborators = ""; // String to hold project collaborators + + public List allProjectsKeywords; // List of all unique keywords from all projects + + public List selectedKeywords; // List of selected keywords for the current project + + public List getSelectedKeywords() { + return selectedKeywords; + } + + public void setSelectedKeywords(List selectedKeywords) { + this.selectedKeywords = selectedKeywords; + } + + private static String getJDBCurl() { + return "jdbc:derby:testDB;create=true"; + } + + @PostConstruct + public void init() { + loadProjects(); // Load projects from the database + System.out.println("Projects loaded: " + projects.size()); + if (projects.isEmpty()) { +// loadFakeProjects(); // Load fake projects if no projects are found + saveProjects(); // Save the fake projects to the database + } + loadAllKeywords(); // Load all unique keywords from all projects + setProject(projects.get(0)); // Set the first project as the current project + } + + @PreDestroy + public void destroy() { + databaseService.close(); + } + + public void loadProjects() { + projects = databaseService.getProjectsByUser(Objects.requireNonNullElse(username, "admin")); + } + + /** + * Loads all unique keywords from all projects into the allProjectsKeywords list. + */ + + public void loadAllKeywords() { + allProjectsKeywords = projects.stream() + .flatMap(project -> project.getKeywords().stream()) + .distinct() + .collect(Collectors.toList()); + } + + public List getProjects() { + return projects; + } + + public void setProjects(List projects) { + this.projects = projects; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + this.projectKeywords = getKeywordsAsString(); // Update keywords string + this.projectCollaborators = getCollaboratorsAsString(); + this.selectedKeywords = new ArrayList<>(project.getKeywords()); + } + + public String loadProject(String title) { + project = projects.stream().filter(p -> p.getTitle().equals(title)).findFirst().orElse(null); + return "project.xhtml?faces-redirect=true"; + } + + public String saveProject() { + FacesContext context = FacesContext.getCurrentInstance(); + + // Check for validation errors + if (context.getMessages().hasNext()) { + // Validation errors exist, do not save data +// context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Validation errors exist. Please fix them before saving.", null)); + return "edit"; + } + + project.setCollaborators(Arrays.asList(projectCollaborators.split(", "))); + project.setKeywords(new ArrayList<>(selectedKeywords)); + + try { + Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); + Connection conn = DriverManager.getConnection(getJDBCurl()); + + // Iterate over all projects and save to the database + for (Project project : projects) { + // Check if the project already exists + String checkSql = "SELECT COUNT(*) FROM projects WHERE title = ?"; + PreparedStatement checkStmt = conn.prepareStatement(checkSql); + checkStmt.setString(1, project.getTitle()); + ResultSet rs = checkStmt.executeQuery(); + rs.next(); + int count = rs.getInt(1); + + if (count > 0) { + // Project exists, perform update + String updateSql = "UPDATE projects SET summary = ?, description = ?, keywords = ?, type = ?, collaborators = ?, link = ?, time = ? WHERE title = ?"; + PreparedStatement updateStmt = conn.prepareStatement(updateSql); + updateStmt.setString(1, project.getSummary()); + updateStmt.setString(2, project.getDescription()); + updateStmt.setString(3, String.join(", ", project.getKeywords())); + updateStmt.setString(4, project.getType()); + updateStmt.setString(5, String.join(", ", project.getCollaborators())); + updateStmt.setString(6, project.getLink()); + updateStmt.setString(7, project.getTime()); + updateStmt.setString(8, project.getTitle()); + updateStmt.executeUpdate(); + } else { + // Project does not exist, perform insert + String insertSql = "INSERT INTO projects (title, summary, description, keywords, type, collaborators, link, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + PreparedStatement insertStmt = conn.prepareStatement(insertSql); + insertStmt.setString(1, project.getTitle()); + insertStmt.setString(2, project.getSummary()); + insertStmt.setString(3, project.getDescription()); + insertStmt.setString(4, String.join(", ", project.getKeywords())); + insertStmt.setString(5, project.getType()); + insertStmt.setString(6, String.join(", ", project.getCollaborators())); + insertStmt.setString(7, project.getLink()); + insertStmt.setString(8, project.getTime()); + insertStmt.executeUpdate(); + } + } + conn.close(); + context.addMessage("saveButton", new FacesMessage(FacesMessage.SEVERITY_INFO, "Submission Succeeded", null)); + } catch (SQLException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + return "project"; + } + + public void saveProjects() { + try { + Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); + Connection conn = DriverManager.getConnection(getJDBCurl()); + + // Iterate over all projects and save to the database + for (Project project : projects) { + // Check if the project already exists + String checkSql = "SELECT COUNT(*) FROM projects WHERE title = ?"; + PreparedStatement checkStmt = conn.prepareStatement(checkSql); + checkStmt.setString(1, project.getTitle()); + ResultSet rs = checkStmt.executeQuery(); + rs.next(); + int count = rs.getInt(1); + + if (count > 0) { + // Project exist, perform update + String updateSql = "UPDATE projects SET summary = ?, description = ?, keywords = ?, type = ?, collaborators = ?, link = ?, time = ? WHERE title = ?"; + PreparedStatement updateStmt = conn.prepareStatement(updateSql); + updateStmt.setString(1, project.getSummary()); + updateStmt.setString(2, project.getDescription()); + updateStmt.setString(3, String.join(", ", project.getKeywords())); + updateStmt.setString(4, project.getType()); + updateStmt.setString(5, String.join(", ", project.getCollaborators())); + updateStmt.setString(6, project.getLink()); + updateStmt.setString(7, project.getTime()); + updateStmt.setString(8, project.getTitle()); + updateStmt.executeUpdate(); + } else { + // Project does not exist, perform insert + String insertSql = "INSERT INTO projects (title, summary, description, keywords, type, collaborators, link, time) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + PreparedStatement insertStmt = conn.prepareStatement(insertSql); + insertStmt.setString(1, project.getTitle()); + insertStmt.setString(2, project.getSummary()); + insertStmt.setString(3, project.getDescription()); + insertStmt.setString(4, String.join(", ", project.getKeywords())); + insertStmt.setString(5, project.getType()); + insertStmt.setString(6, String.join(", ", project.getCollaborators())); + insertStmt.setString(7, project.getLink()); + insertStmt.setString(8, project.getTime()); + insertStmt.executeUpdate(); + } + } + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + public String getKeywordsAsString() { + return project != null ? String.join(", ", project.getKeywords()) : ""; + } + + public String getCollaboratorsAsString() { + return project != null ? String.join(", ", project.getCollaborators()) : ""; + } + + public String getProjectKeywords() { + return projectKeywords; + } + + public void setProjectKeywords(String projectKeywords) { + this.projectKeywords = projectKeywords; + } + + public String getProjectCollaborators() { + return projectCollaborators; + } + + public void setProjectCollaborators(String projectCollaborators) { + this.projectCollaborators = projectCollaborators; + } + + public List getAllProjectsKeywords() { + return allProjectsKeywords; + } + + public void setAllProjectsKeywords(List allProjectsKeywords) { + this.allProjectsKeywords = allProjectsKeywords; + } +} diff --git a/src/main/resources/META-INF/beans.xml b/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..ebf8679 --- /dev/null +++ b/src/main/resources/META-INF/beans.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..e18040c --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/main/webapp/WEB-INF/beans.xml b/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000..ebf8679 --- /dev/null +++ b/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..06f6af7 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,35 @@ + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 1 + + + Faces Servlet + *.jsf + + + javax.faces.PROJECT_STAGE + Development + + + State saving method: 'client' or 'server' (default). See JSF Specification section 2.5.2 + + javax.faces.STATE_SAVING_METHOD + client + + + + index.jsf + + + + org.jboss.weld.environment.servlet.Listener + + \ No newline at end of file diff --git a/src/main/webapp/edit.xhtml b/src/main/webapp/edit.xhtml new file mode 100644 index 0000000..c98e63d --- /dev/null +++ b/src/main/webapp/edit.xhtml @@ -0,0 +1,121 @@ + + + + + Edit Projects - My Portfolio + + + + +
+ + +
+

Select Project to Edit

+ + + + + + +
+
+ +
+

Edit Project

+
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ +
+
+ + + + + +
+ + +
+
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+
+
+ +
+ + + + +
+
+
+ +
+
+
+ diff --git a/src/main/webapp/footer.xhtml b/src/main/webapp/footer.xhtml new file mode 100644 index 0000000..9df4118 --- /dev/null +++ b/src/main/webapp/footer.xhtml @@ -0,0 +1,9 @@ + + + +
+

© 2024 Ryan Goodwill. All rights reserved.

+
+
+ diff --git a/src/main/webapp/header.xhtml b/src/main/webapp/header.xhtml new file mode 100644 index 0000000..6632392 --- /dev/null +++ b/src/main/webapp/header.xhtml @@ -0,0 +1,25 @@ + + + + + + + <h:outputText value="#{(not empty requestScope.pageTitle) ? requestScope.pageTitle : 'My Portfolio'}"/> + + + + +
+

Welcome to My Portfolio

+ +
+
+ diff --git a/src/main/webapp/index.xhtml b/src/main/webapp/index.xhtml new file mode 100644 index 0000000..de6e118 --- /dev/null +++ b/src/main/webapp/index.xhtml @@ -0,0 +1,49 @@ + + + + + + Home - My Portfolio + + + + + + +
+
+

About Me

+

Hello! I'm Ryan Goodwill, a passionate programmer. I'm interested in various AI models and their + applications, Raspberry Pi projects, playing the piano, playing tennis, and cycling.

+

I have experience in programming since elementary school, initially starting with Pascal and later mastering + C++ and Python. My project experiences include developing a novel network novel crawler and a mental abacus + calculation practice tool using Python during high school.

+

During my university studies, I learned Java and accomplished an assignment about a project management system + named "Cloud Factory Management". In my Android course, I developed In my Android course, I developed a + weather forecast application.

+

To understand some communication technologies, I developed a simple protocol and corresponding + drivers for infrared communication using a Raspberry Pi with Python. I also created a plant care box for the + Raspberry Pi, which utilizes sensors to maintain a stable environment for plants through control of a fan, + stepper motor, and water pump. Additionally, I used Django to build a simple control webpage with features + for remote hardware control and RTMP video streaming to monitor plants remotely.

+

Recently, I have locally deployed and tested multiple Large Language Models (LLM) projects, including + ChatGLM-6B, llama2, llama3, ChatGLM3-6B, Qwen1, Qwen1.5, Qwen2, Phi3-mini, and several versions of Stable + Diffusion for AI image generation projects. I have also worked on AI voice synthesis projects such as + so-vits-svc and GPT-SoVITS.

+

Currently, I am working on a project that allows me to download videos from user-specified websites, perform + OCR and ASR locally, correct errors, vectorize the data into SVG, and store it for local LLM queries.

+

Skills: Programming in Python, C++, Java, and Pascal; Web development using Django; Raspberry Pi project + design and implementation; AI model experimentation and application; Sensor integration and control system + development; Remote hardware control and video streaming; Communication protocol development.

+

Career Goal: To work in an internet company for a few years before starting my own business.

+
+
+
+ +
+
+ diff --git a/src/main/webapp/project.xhtml b/src/main/webapp/project.xhtml new file mode 100644 index 0000000..bc7b74e --- /dev/null +++ b/src/main/webapp/project.xhtml @@ -0,0 +1,84 @@ + + + + + + Project Details - My Portfolio + + + + + +
+

Click to go back to the home page

+ +
+

Project List

+ + + + + + + +
+
+

+ +

+
+

+ +

+
+
+

+ +

+
+
+

+ Keywords: + +

+
+
+

+ Type: + +

+
+
+

+ Collaborators: + +

+
+
+

+ Link: + + + +

+
+
+

+ Time: + +

+
+
+
+ +
+ +
+
+ + diff --git a/src/main/webapp/resources/css/styles.css b/src/main/webapp/resources/css/styles.css new file mode 100644 index 0000000..17a103e --- /dev/null +++ b/src/main/webapp/resources/css/styles.css @@ -0,0 +1,324 @@ +/* General body styling */ +html, body { + font-family: Arial, sans-serif; /* Sets the default font to Arial, with a sans-serif fallback */ + margin: 0; /* Removes default margin */ + padding: 0; /* Removes default padding */ + background-color: #f4f4f4; /* Sets a light grey background color for the body */ + height: 100%; + display: flex; + flex-direction: column; +} + +/* Header styling */ +header { + background-color: #333; /* Dark background color for the header */ + color: #fff; /* White text color for the header */ + padding: 1em 0; /* Adds vertical padding to the header */ + text-align: center; /* Centers the text within the header */ +} + +/* Navigation list styling */ +nav ul { + list-style-type: none; /* Removes bullet points from the list */ + padding: 0; /* Removes padding from the list */ +} + +/* Navigation list item styling */ +nav ul li { + display: inline; /* Displays list items in a horizontal line */ + margin: 0 1em; /* Adds margin between list items */ +} + +/* Styling for links within the navigation list */ +nav ul li a { + color: #fff; /* White text color for the links */ + text-decoration: none; /* Removes underline from the links */ +} + +/* Main content area styling */ +main { + padding: 2em; /* Adds padding around the main content */ + flex: 1; +} + +/* Footer styling */ +footer { + background-color: #333; /* Dark background color for the footer */ + color: #fff; /* White text color for the footer */ + text-align: center; /* Centers the text within the footer */ + padding: 1em 0; /* Adds vertical padding to the footer */ + width: 100%; /* Ensures the footer spans the full width of the page */ + /* position: absolute; */ + /* bottom: 0; */ +} + +/* Project list styling */ +.project-list { + list-style: none; + padding: 0; + margin: 0; +} + +.project-list li, .liButton { + background-color: #fff; + border: 1px solid #ddd; + margin-bottom: 5px; + padding: 10px; + cursor: pointer; + transition: background-color 0.3s ease; + text-align: center; +} + +.project-list li:hover, .liButton:hover { + background-color: #f0f0f0; +} + +/* Project form styling */ +/*.project-form {*/ +/* background-color: #fff;*/ +/* padding: 20px;*/ +/* border: 1px solid #ddd;*/ +/*}*/ + +.project-form label { + display: block; + margin-bottom: 10px; +} + +.project-form input, .project-form textarea { + width: 100%; + padding: 10px; + margin-top: 5px; + margin-bottom: 20px; + border: 1px solid #ddd; + border-radius: 4px; +} + +.project-form textarea { + resize: vertical; +} + +.btn { + background-color: #333; + color: #fff; + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.btn:hover { + background-color: #555; +} + +/* Save button styling */ +.save_btn { + background-color: #4CAF50; /* Green background color */ + color: white; /* White text color */ + padding: 10px 20px; /* Padding for the button */ + border: none; /* Remove default border */ + border-radius: 5px; /* Rounded corners */ + cursor: pointer; /* Pointer cursor on hover */ + font-size: 16px; /* Font size */ + transition: background-color 0.3s ease; /* Smooth transition for background color */ +} + +.save_btn:hover { + background-color: #45a049; /* Darker green on hover */ +} + +/* Project list item styling */ +#project-list { + font-family: Arial, sans-serif; + background-color: #f9f9f9; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + max-width: 80%; /* 修改为百分比宽度,自适应屏幕 */ + margin: 20px auto; + text-align: center; +} + + +#project-list h1 { + color: #333; + margin-bottom: 20px; +} + +.project-button { + background-color: #fff; + border: 1px solid #ddd; + margin: 5px; + padding: 10px; + cursor: pointer; + transition: background-color 0.3s ease; + text-align: center; + display: inline-block; + width: auto; /* 调整按钮宽度,使其不占满整行 */ +} + +.project-button:hover { + background-color: #f0f0f0; +} + +#project-details { + font-family: Arial, sans-serif; + background-color: #f9f9f9; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + max-width: 80%; /* 修改为百分比宽度,自适应屏幕 */ + margin: 20px auto; +} + +#project-details h2 { + text-align: center; + color: #333; + margin-bottom: 20px; +} + +.detail-item { + margin-bottom: 15px; +} + +.detail-item p { + margin: 0; + color: #555; +} + +.detail-item strong { + color: #333; +} + +.detail-item a { + color: #007bff; + text-decoration: none; +} + +.detail-item a:hover { + text-decoration: underline; +} + +/* 通用样式 */ +.project-form { + font-family: Arial, sans-serif; + background-color: #f9f9f9; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0,0,0,0.1); + max-width: 80%; /* 修改为百分比宽度,自适应屏幕 */ + margin: 20px auto; +} + +.project-form h2 { + text-align: center; + color: #333; + margin-bottom: 20px; +} + +.form-group { + margin-bottom: 10px; +} + +.form-group input, .form-group textarea, .form-group select { + width: 100%; + padding: 10px; + border: 1px solid #ddd; + border-radius: 5px; + box-sizing: border-box; +} + +.form-group label { + display: block; + margin-bottom: 5px; + color: #333; +} + +.form-group-right { + display: inline-block; + width: calc(50% - 10px); + margin-left: 10px; + vertical-align: top; +} + +/* 关键字样式 */ +.form-group-container { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.form-group-keywords { + display: inline-block; + width: calc(50% - 10px); + vertical-align: top; +} + +.keywords-listbox { + width: 100%; + box-sizing: border-box; + text-align: center; /* 使列表框内的文本居中 */ +} + +.keywords-listbox option { + text-align: center; /* 使每个选项内的文本居中 */ +} + + +/* 按钮样式 */ +.project-button { + background-color: #fff; + border: 1px solid #ddd; + margin: 5px; + padding: 10px; + cursor: pointer; + transition: background-color 0.3s ease; + text-align: center; + display: inline-block; + width: auto; +} + +.project-button:hover { + background-color: #f0f0f0; +} + +/* 保存按钮样式 */ +#saveButton { + background-color: #007bff; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; +} + +#saveButton:hover { + background-color: #0056b3; +} + +/* Section styling for About Me */ +#about-me { + background-color: #fff; /* 白色背景 */ + padding: 20px; /* 内边距 */ + border-radius: 10px; /* 圆角边框 */ + box-shadow: 0 0 10px rgba(0,0,0,0.1); /* 盒子阴影 */ + max-width: 80%; /* 设置最大宽度 */ + margin: 20px auto; /* 垂直外边距和水平居中 */ +} + +/* Heading styling for About Me */ +#about-me h1 { + color: #333; /* 文字颜色 */ + text-align: center; /* 居中对齐 */ + margin-bottom: 20px; /* 底部外边距 */ +} + +/* Paragraph styling for About Me */ +#about-me p { + line-height: 1.6; /* 行高 */ + margin-bottom: 15px; /* 底部外边距 */ + text-align: justify; /* 文本对齐 */ + color: #555; /* 文字颜色 */ +} \ No newline at end of file