Fixed database errors!
This commit is contained in:
parent
73ef29e2df
commit
2bfa4a8c50
9 changed files with 987 additions and 958 deletions
501
.gitignore
vendored
501
.gitignore
vendored
|
@ -1,250 +1,251 @@
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
[Rr]elease/
|
[Rr]elease/
|
||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
#wwwroot/
|
#wwwroot/
|
||||||
|
|
||||||
# MSTest test Results
|
# MSTest test Results
|
||||||
[Tt]est[Rr]esult*/
|
[Tt]est[Rr]esult*/
|
||||||
[Bb]uild[Ll]og.*
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
# NUNIT
|
# NUNIT
|
||||||
*.VisualState.xml
|
*.VisualState.xml
|
||||||
TestResult.xml
|
TestResult.xml
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
# Build Results of an ATL Project
|
||||||
[Dd]ebugPS/
|
[Dd]ebugPS/
|
||||||
[Rr]eleasePS/
|
[Rr]eleasePS/
|
||||||
dlldata.c
|
dlldata.c
|
||||||
|
|
||||||
# DNX
|
# DNX
|
||||||
project.lock.json
|
project.lock.json
|
||||||
artifacts/
|
artifacts/
|
||||||
|
|
||||||
*_i.c
|
*_i.c
|
||||||
*_p.c
|
*_p.c
|
||||||
*_i.h
|
*_i.h
|
||||||
*.ilk
|
*.ilk
|
||||||
*.meta
|
*.meta
|
||||||
*.obj
|
*.obj
|
||||||
*.pch
|
*.pch
|
||||||
*.pdb
|
*.pdb
|
||||||
*.pgc
|
*.pgc
|
||||||
*.pgd
|
*.pgd
|
||||||
*.rsp
|
*.rsp
|
||||||
*.sbr
|
*.sbr
|
||||||
*.tlb
|
*.tlb
|
||||||
*.tli
|
*.tli
|
||||||
*.tlh
|
*.tlh
|
||||||
*.tmp
|
*.tmp
|
||||||
*.tmp_proj
|
*.tmp_proj
|
||||||
*.log
|
*.log
|
||||||
*.vspscc
|
*.vspscc
|
||||||
*.vssscc
|
*.vssscc
|
||||||
.builds
|
.builds
|
||||||
*.pidb
|
*.pidb
|
||||||
*.svclog
|
*.svclog
|
||||||
*.scc
|
*.scc
|
||||||
|
|
||||||
# Chutzpah Test files
|
# Chutzpah Test files
|
||||||
_Chutzpah*
|
_Chutzpah*
|
||||||
|
|
||||||
# Visual C++ cache files
|
# Visual C++ cache files
|
||||||
ipch/
|
ipch/
|
||||||
*.aps
|
*.aps
|
||||||
*.ncb
|
*.ncb
|
||||||
*.opendb
|
*.opendb
|
||||||
*.opensdf
|
*.opensdf
|
||||||
*.sdf
|
*.sdf
|
||||||
*.cachefile
|
*.cachefile
|
||||||
|
|
||||||
# Visual Studio profiler
|
# Visual Studio profiler
|
||||||
*.psess
|
*.psess
|
||||||
*.vsp
|
*.vsp
|
||||||
*.vspx
|
*.vspx
|
||||||
*.sap
|
*.sap
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
# TFS 2012 Local Workspace
|
||||||
$tf/
|
$tf/
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
# Guidance Automation Toolkit
|
||||||
*.gpState
|
*.gpState
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
# ReSharper is a .NET coding add-in
|
||||||
_ReSharper*/
|
_ReSharper*/
|
||||||
*.[Rr]e[Ss]harper
|
*.[Rr]e[Ss]harper
|
||||||
*.DotSettings.user
|
*.DotSettings.user
|
||||||
|
|
||||||
# JustCode is a .NET coding add-in
|
# JustCode is a .NET coding add-in
|
||||||
.JustCode
|
.JustCode
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
# TeamCity is a build add-in
|
||||||
_TeamCity*
|
_TeamCity*
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
# DotCover is a Code Coverage Tool
|
||||||
*.dotCover
|
*.dotCover
|
||||||
|
|
||||||
# NCrunch
|
# NCrunch
|
||||||
_NCrunch_*
|
_NCrunch_*
|
||||||
.*crunch*.local.xml
|
.*crunch*.local.xml
|
||||||
nCrunchTemp_*
|
nCrunchTemp_*
|
||||||
|
|
||||||
# MightyMoose
|
# MightyMoose
|
||||||
*.mm.*
|
*.mm.*
|
||||||
AutoTest.Net/
|
AutoTest.Net/
|
||||||
|
|
||||||
# Web workbench (sass)
|
# Web workbench (sass)
|
||||||
.sass-cache/
|
.sass-cache/
|
||||||
|
|
||||||
# Installshield output folder
|
# Installshield output folder
|
||||||
[Ee]xpress/
|
[Ee]xpress/
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
# DocProject is a documentation generator add-in
|
||||||
DocProject/buildhelp/
|
DocProject/buildhelp/
|
||||||
DocProject/Help/*.HxT
|
DocProject/Help/*.HxT
|
||||||
DocProject/Help/*.HxC
|
DocProject/Help/*.HxC
|
||||||
DocProject/Help/*.hhc
|
DocProject/Help/*.hhc
|
||||||
DocProject/Help/*.hhk
|
DocProject/Help/*.hhk
|
||||||
DocProject/Help/*.hhp
|
DocProject/Help/*.hhp
|
||||||
DocProject/Help/Html2
|
DocProject/Help/Html2
|
||||||
DocProject/Help/html
|
DocProject/Help/html
|
||||||
|
|
||||||
# Click-Once directory
|
# Click-Once directory
|
||||||
publish/
|
publish/
|
||||||
|
|
||||||
# Publish Web Output
|
# Publish Web Output
|
||||||
*.[Pp]ublish.xml
|
*.[Pp]ublish.xml
|
||||||
*.azurePubxml
|
*.azurePubxml
|
||||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
*.pubxml
|
*.pubxml
|
||||||
*.publishproj
|
*.publishproj
|
||||||
|
|
||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
# The packages folder can be ignored because of Package Restore
|
# The packages folder can be ignored because of Package Restore
|
||||||
**/packages/*
|
**/packages/*
|
||||||
# except build/, which is used as an MSBuild target.
|
# except build/, which is used as an MSBuild target.
|
||||||
!**/packages/build/
|
!**/packages/build/
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
#!**/packages/repositories.config
|
#!**/packages/repositories.config
|
||||||
# NuGet v3's project.json files produces more ignoreable files
|
# NuGet v3's project.json files produces more ignoreable files
|
||||||
*.nuget.props
|
*.nuget.props
|
||||||
*.nuget.targets
|
*.nuget.targets
|
||||||
|
|
||||||
# Microsoft Azure Build Output
|
# Microsoft Azure Build Output
|
||||||
csx/
|
csx/
|
||||||
*.build.csdef
|
*.build.csdef
|
||||||
|
|
||||||
# Microsoft Azure Emulator
|
# Microsoft Azure Emulator
|
||||||
ecf/
|
ecf/
|
||||||
rcf/
|
rcf/
|
||||||
|
|
||||||
# Windows Store app package directories and files
|
# Windows Store app package directories and files
|
||||||
AppPackages/
|
AppPackages/
|
||||||
BundleArtifacts/
|
BundleArtifacts/
|
||||||
Package.StoreAssociation.xml
|
Package.StoreAssociation.xml
|
||||||
_pkginfo.txt
|
_pkginfo.txt
|
||||||
|
|
||||||
# Visual Studio cache files
|
# Visual Studio cache files
|
||||||
# files ending in .cache can be ignored
|
# files ending in .cache can be ignored
|
||||||
*.[Cc]ache
|
*.[Cc]ache
|
||||||
# but keep track of directories ending in .cache
|
# but keep track of directories ending in .cache
|
||||||
!*.[Cc]ache/
|
!*.[Cc]ache/
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
ClientBin/
|
ClientBin/
|
||||||
~$*
|
~$*
|
||||||
*~
|
*~
|
||||||
*.dbmdl
|
*.dbmdl
|
||||||
*.dbproj.schemaview
|
*.dbproj.schemaview
|
||||||
*.pfx
|
*.pfx
|
||||||
*.publishsettings
|
*.publishsettings
|
||||||
node_modules/
|
node_modules/
|
||||||
orleans.codegen.cs
|
orleans.codegen.cs
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
#bower_components/
|
#bower_components/
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
# RIA/Silverlight projects
|
||||||
Generated_Code/
|
Generated_Code/
|
||||||
|
|
||||||
# Backup & report files from converting an old project file
|
# Backup & report files from converting an old project file
|
||||||
# to a newer Visual Studio version. Backup files are not needed,
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
# because we have git ;-)
|
# because we have git ;-)
|
||||||
_UpgradeReport_Files/
|
_UpgradeReport_Files/
|
||||||
Backup*/
|
Backup*/
|
||||||
UpgradeLog*.XML
|
UpgradeLog*.XML
|
||||||
UpgradeLog*.htm
|
UpgradeLog*.htm
|
||||||
|
|
||||||
# SQL Server files
|
# SQL Server files
|
||||||
*.mdf
|
*.mdf
|
||||||
*.ldf
|
*.ldf
|
||||||
|
|
||||||
# Business Intelligence projects
|
# Business Intelligence projects
|
||||||
*.rdl.data
|
*.rdl.data
|
||||||
*.bim.layout
|
*.bim.layout
|
||||||
*.bim_*.settings
|
*.bim_*.settings
|
||||||
|
|
||||||
# Microsoft Fakes
|
# Microsoft Fakes
|
||||||
FakesAssemblies/
|
FakesAssemblies/
|
||||||
|
|
||||||
# GhostDoc plugin setting file
|
# GhostDoc plugin setting file
|
||||||
*.GhostDoc.xml
|
*.GhostDoc.xml
|
||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
# Node.js Tools for Visual Studio
|
||||||
.ntvs_analysis.dat
|
.ntvs_analysis.dat
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
# Visual Studio 6 build log
|
||||||
*.plg
|
*.plg
|
||||||
|
|
||||||
# Visual Studio 6 workspace options file
|
# Visual Studio 6 workspace options file
|
||||||
*.opt
|
*.opt
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
# Visual Studio LightSwitch build output
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
**/*.DesktopClient/ModelManifest.xml
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
**/*.Server/GeneratedArtifacts
|
**/*.Server/GeneratedArtifacts
|
||||||
**/*.Server/ModelManifest.xml
|
**/*.Server/ModelManifest.xml
|
||||||
_Pvt_Extensions
|
_Pvt_Extensions
|
||||||
|
|
||||||
# Paket dependency manager
|
# Paket dependency manager
|
||||||
.paket/paket.exe
|
.paket/paket.exe
|
||||||
paket-files/
|
paket-files/
|
||||||
|
|
||||||
# FAKE - F# Make
|
# FAKE - F# Make
|
||||||
.fake/
|
.fake/
|
||||||
|
|
||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
.idea/
|
.idea/
|
||||||
*.sln.imlasd
|
*.sln.imlasd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
target/classes/*
|
target/classes/*
|
||||||
|
/target/
|
||||||
|
|
|
@ -1,12 +1,27 @@
|
||||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
version="2.0">
|
version="2.0">
|
||||||
<persistence-unit name="ChatServerPU">
|
<persistence-unit name="ChatServerPU">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
|
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:chatserver;create=true" /><property
|
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:chatserver;create=true" />
|
||||||
name="hibernate.hbm2ddl.auto" value="update"/>
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
</properties>
|
|
||||||
</persistence-unit>
|
<!-- c3p0 config http://www.hibernate.org/214.html -->
|
||||||
|
<!-- <property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"
|
||||||
|
/> <property name="hibernate.c3p0.acquire_increment" value="1" /> <property
|
||||||
|
name="hibernate.c3p0.idle_test_period" value="60" /> <property name="hibernate.c3p0.min_size"
|
||||||
|
value="1" /> <property name="hibernate.c3p0.max_size" value="2" /> <property
|
||||||
|
name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.timeout"
|
||||||
|
value="0" /> <property name="hibernate.c3p0.acquireRetryAttempts" value="1"
|
||||||
|
/> <property name="hibernate.c3p0.acquireRetryDelay" value="250" /> -->
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
<property name="hibernate.use_sql_comments" value="true" />
|
||||||
|
<property name="hibernate.transaction.factory_class"
|
||||||
|
value="org.hibernate.transaction.JDBCTransactionFactory" />
|
||||||
|
<property name="hibernate.current_session_context_class"
|
||||||
|
value="thread" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
160
pom.xml
160
pom.xml
|
@ -1,78 +1,84 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>ChatServer</groupId>
|
<groupId>ChatServer</groupId>
|
||||||
<artifactId>ChatServer</artifactId>
|
<artifactId>ChatServer</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.5.1</version>
|
<version>3.5.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.derby</groupId>
|
<groupId>org.apache.derby</groupId>
|
||||||
<artifactId>derby</artifactId>
|
<artifactId>derby</artifactId>
|
||||||
<version>10.12.1.1</version>
|
<version>10.12.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.derby</groupId>
|
<groupId>org.apache.derby</groupId>
|
||||||
<artifactId>derbyclient</artifactId>
|
<artifactId>derbyclient</artifactId>
|
||||||
<version>10.12.1.1</version>
|
<version>10.12.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
|
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
<version>5.2.1.Final</version>
|
<version>5.2.1.Final</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
|
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.5</version>
|
<version>2.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.reflections</groupId>
|
<groupId>org.reflections</groupId>
|
||||||
<artifactId>reflections</artifactId>
|
<artifactId>reflections</artifactId>
|
||||||
<version>0.9.10</version>
|
<version>0.9.10</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
|
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>jsoup</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
<version>1.9.2</version>
|
<version>1.9.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
|
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-core</artifactId>
|
<artifactId>log4j-core</artifactId>
|
||||||
<version>2.6.2</version>
|
<version>2.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
|
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-api</artifactId>
|
<artifactId>log4j-api</artifactId>
|
||||||
<version>2.6.2</version>
|
<version>2.6.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.json/json -->
|
<!-- https://mvnrepository.com/artifact/org.json/json -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>20160212</version>
|
<version>20160212</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
|
||||||
<properties>
|
<dependency>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<groupId>org.hibernate</groupId>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<artifactId>hibernate-c3p0</artifactId>
|
||||||
</properties>
|
<version>5.2.1.Final</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -1,178 +1,182 @@
|
||||||
package io.github.norbipeti.chat.server;
|
package io.github.norbipeti.chat.server;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Period;
|
import java.time.Period;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
|
||||||
import io.github.norbipeti.chat.server.db.DataProvider;
|
import io.github.norbipeti.chat.server.db.DataProvider;
|
||||||
import io.github.norbipeti.chat.server.db.domain.User;
|
import io.github.norbipeti.chat.server.db.domain.User;
|
||||||
import io.github.norbipeti.chat.server.page.Page;
|
import io.github.norbipeti.chat.server.page.Page;
|
||||||
|
|
||||||
public class IOHelper {
|
public class IOHelper {
|
||||||
public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException {
|
public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException {
|
||||||
exchange.sendResponseHeaders(code, content.length());
|
exchange.sendResponseHeaders(code, content.length());
|
||||||
IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8);
|
IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8);
|
||||||
exchange.getResponseBody().close();
|
exchange.getResponseBody().close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException {
|
public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException {
|
||||||
String content = GetPage(page, exchange);
|
String content = GetPage(page, exchange);
|
||||||
SendResponse(code, content, exchange);
|
SendResponse(code, content, exchange);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String GetPage(Page page, HttpExchange exchange) throws IOException {
|
public static String GetPage(Page page, HttpExchange exchange) throws IOException {
|
||||||
File file = new File(page.GetHTMLPath());
|
File file = new File(page.GetHTMLPath());
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
SendResponse(501,
|
SendResponse(501,
|
||||||
"<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>",
|
"<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>",
|
||||||
exchange);
|
exchange);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ReadFile(file);
|
return ReadFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String ReadFile(File file) throws FileNotFoundException, IOException {
|
public static String ReadFile(File file) throws FileNotFoundException, IOException {
|
||||||
FileInputStream inputStream = new FileInputStream(file);
|
FileInputStream inputStream = new FileInputStream(file);
|
||||||
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
|
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException {
|
public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException {
|
||||||
if (exchange.getRequestBody().available() == 0)
|
if (exchange.getRequestBody().available() == 0)
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
try {
|
try {
|
||||||
String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&");
|
String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&");
|
||||||
HashMap<String, String> vars = new HashMap<>();
|
HashMap<String, String> vars = new HashMap<>();
|
||||||
for (String var : content) {
|
for (String var : content) {
|
||||||
String[] spl = var.split("\\=");
|
String[] spl = var.split("\\=");
|
||||||
if (spl.length == 1)
|
if (spl.length == 1)
|
||||||
vars.put(spl[0], "");
|
vars.put(spl[0], "");
|
||||||
else
|
else
|
||||||
vars.put(spl[0], spl[1]);
|
vars.put(spl[0], spl[1]);
|
||||||
}
|
}
|
||||||
return vars;
|
return vars;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
|
public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
|
||||||
if (exchange.getRequestBody().available() == 0)
|
if (exchange.getRequestBody().available() == 0)
|
||||||
return null;
|
return null;
|
||||||
try {
|
try {
|
||||||
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1);
|
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1);
|
||||||
JSONObject obj = new JSONObject(content);
|
JSONObject obj = new JSONObject(content);
|
||||||
return obj;
|
return obj;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc,
|
public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc,
|
||||||
HttpExchange exchange) throws IOException {
|
HttpExchange exchange) throws IOException {
|
||||||
String content = GetPage(page, exchange);
|
String content = GetPage(page, exchange);
|
||||||
if (content == null)
|
if (content == null)
|
||||||
return false;
|
return false;
|
||||||
Document doc = Jsoup.parse(content);
|
Document doc = Jsoup.parse(content);
|
||||||
doc = modifyfunc.apply(doc);
|
doc = modifyfunc.apply(doc);
|
||||||
SendResponse(200, doc.html(), exchange);
|
SendResponse(200, doc.html(), exchange);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
|
public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
|
||||||
provider.SetValues(() -> user.setSessionid(UUID.randomUUID()));
|
System.out.println("Logging in user: " + user);
|
||||||
System.out.println("Logging in user: " + user);
|
// provider.SetValues(() ->
|
||||||
ZonedDateTime expiretime = ZonedDateTime.now(ZoneId.of("GMT")).plus(Period.of(2, 0, 0));
|
// user.setSessionid(UUID.randomUUID().toString()));
|
||||||
exchange.getResponseHeaders().add("Set-Cookie",
|
user.setSessionid(UUID.randomUUID().toString());
|
||||||
"user_id=" + user.getId() + "; expires=" + expiretime.format(DateTimeFormatter.RFC_1123_DATE_TIME));
|
provider.saveUser(user);
|
||||||
exchange.getResponseHeaders().add("Set-Cookie",
|
System.out.println("Session ID set to " + user.getSessionid());
|
||||||
"session_id=" + user.getSessionid() + "; expires=" + expiretime);
|
ZonedDateTime expiretime = ZonedDateTime.now(ZoneId.of("GMT")).plus(Period.of(2, 0, 0));
|
||||||
}
|
exchange.getResponseHeaders().add("Set-Cookie",
|
||||||
|
"user_id=" + user.getId() + "; expires=" + expiretime.format(DateTimeFormatter.RFC_1123_DATE_TIME));
|
||||||
public static void LogoutUser(HttpExchange exchange, User user) {
|
exchange.getResponseHeaders().add("Set-Cookie",
|
||||||
user.setSessionid(new UUID(0, 0));
|
"session_id=" + user.getSessionid() + "; expires=" + expiretime);
|
||||||
SendLogoutHeaders(exchange);
|
}
|
||||||
}
|
|
||||||
|
public static void LogoutUser(HttpExchange exchange, User user) {
|
||||||
private static void SendLogoutHeaders(HttpExchange exchange) {
|
user.setSessionid(new UUID(0, 0).toString());
|
||||||
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT";
|
SendLogoutHeaders(exchange);
|
||||||
exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime);
|
}
|
||||||
exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
|
|
||||||
}
|
private static void SendLogoutHeaders(HttpExchange exchange) {
|
||||||
|
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT";
|
||||||
public static void Redirect(String url, HttpExchange exchange) throws IOException {
|
exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime);
|
||||||
exchange.getResponseHeaders().add("Location", url);
|
exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
|
||||||
IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange);
|
}
|
||||||
}
|
|
||||||
|
public static void Redirect(String url, HttpExchange exchange) throws IOException {
|
||||||
public static HashMap<String, String> GetCookies(HttpExchange exchange) {
|
exchange.getResponseHeaders().add("Location", url);
|
||||||
if (!exchange.getRequestHeaders().containsKey("Cookie"))
|
IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange);
|
||||||
return new HashMap<>();
|
}
|
||||||
HashMap<String, String> map = new HashMap<>();
|
|
||||||
for (String cheader : exchange.getRequestHeaders().get("Cookie")) {
|
public static HashMap<String, String> GetCookies(HttpExchange exchange) {
|
||||||
String[] spl = cheader.split("\\;\\s*");
|
if (!exchange.getRequestHeaders().containsKey("Cookie"))
|
||||||
for (String s : spl) {
|
return new HashMap<>();
|
||||||
String[] kv = s.split("\\=");
|
HashMap<String, String> map = new HashMap<>();
|
||||||
if (kv.length < 2)
|
for (String cheader : exchange.getRequestHeaders().get("Cookie")) {
|
||||||
continue;
|
String[] spl = cheader.split("\\;\\s*");
|
||||||
map.put(kv[0], kv[1]);
|
for (String s : spl) {
|
||||||
}
|
String[] kv = s.split("\\=");
|
||||||
}
|
if (kv.length < 2)
|
||||||
return map;
|
continue;
|
||||||
}
|
map.put(kv[0], kv[1]);
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* Get logged in user. It may also send logout headers if the cookies are
|
return map;
|
||||||
* invalid.
|
}
|
||||||
*
|
|
||||||
* @param exchange
|
/**
|
||||||
* @return The logged in user or null if not logged in.
|
* Get logged in user. It may also send logout headers if the cookies are
|
||||||
*/
|
* invalid.
|
||||||
public static User GetLoggedInUser(HttpExchange exchange) {
|
*
|
||||||
HashMap<String, String> cookies = GetCookies(exchange);
|
* @param exchange
|
||||||
System.out.println("Cookies: " + cookies);
|
* @return The logged in user or null if not logged in.
|
||||||
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
|
*/
|
||||||
return null;
|
public static User GetLoggedInUser(HttpExchange exchange) {
|
||||||
System.out.println("Cookies found");
|
HashMap<String, String> cookies = GetCookies(exchange);
|
||||||
try (DataProvider provider = new DataProvider()) {
|
System.out.println("Cookies: " + cookies);
|
||||||
User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
|
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
|
||||||
System.out.println("User: " + user);
|
return null;
|
||||||
System.out.println("session_id: " + cookies.get("session_id"));
|
System.out.println("Cookies found");
|
||||||
if (user != null)
|
try (DataProvider provider = new DataProvider()) {
|
||||||
System.out.println("Equals: " + UUID.fromString(cookies.get("session_id")).equals(user.getSessionid()));
|
User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
|
||||||
if (user != null && cookies.get("session_id") != null
|
System.out.println("User: " + user);
|
||||||
&& UUID.fromString(cookies.get("session_id")).equals(user.getSessionid()))
|
System.out.println("session_id: " + cookies.get("session_id"));
|
||||||
return user;
|
if (user != null)
|
||||||
else
|
System.out.println("Equals: " + cookies.get("session_id").equals(user.getSessionid()));
|
||||||
SendLogoutHeaders(exchange);
|
if (user != null && cookies.get("session_id") != null
|
||||||
}
|
&& cookies.get("session_id").equals(user.getSessionid()))
|
||||||
return null;
|
return user;
|
||||||
}
|
else
|
||||||
|
SendLogoutHeaders(exchange);
|
||||||
public static void SendResponse(int code, Function<Document, Document> action, HttpExchange exchange)
|
}
|
||||||
throws IOException {
|
return null;
|
||||||
Document doc = new Document("");
|
}
|
||||||
doc = action.apply(doc);
|
|
||||||
SendResponse(200, doc.html(), exchange);
|
public static void SendResponse(int code, Function<Document, Document> action, HttpExchange exchange)
|
||||||
}
|
throws IOException {
|
||||||
}
|
Document doc = new Document("");
|
||||||
|
doc = action.apply(doc);
|
||||||
|
SendResponse(200, doc.html(), exchange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,109 +1,108 @@
|
||||||
package io.github.norbipeti.chat.server;
|
package io.github.norbipeti.chat.server;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.Date;
|
||||||
import java.util.Date;
|
import java.util.List;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
import java.util.Set;
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.core.LoggerContext;
|
||||||
import org.apache.logging.log4j.core.LoggerContext;
|
import org.apache.logging.log4j.core.config.Configuration;
|
||||||
import org.apache.logging.log4j.core.config.Configuration;
|
import org.apache.logging.log4j.core.config.LoggerConfig;
|
||||||
import org.apache.logging.log4j.core.config.LoggerConfig;
|
import org.reflections.Reflections;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.scanners.SubTypesScanner;
|
||||||
import org.reflections.scanners.SubTypesScanner;
|
import org.reflections.util.ClasspathHelper;
|
||||||
import org.reflections.util.ClasspathHelper;
|
import org.reflections.util.ConfigurationBuilder;
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
import com.sun.net.httpserver.HttpServer;
|
import io.github.norbipeti.chat.server.db.*;
|
||||||
import io.github.norbipeti.chat.server.db.*;
|
import io.github.norbipeti.chat.server.db.domain.*;
|
||||||
import io.github.norbipeti.chat.server.db.domain.*;
|
import io.github.norbipeti.chat.server.page.*;
|
||||||
import io.github.norbipeti.chat.server.page.*;
|
|
||||||
|
public class Main {
|
||||||
public class Main {
|
// public static final HashMap<String, Page> Pages = new HashMap<String,
|
||||||
// public static final HashMap<String, Page> Pages = new HashMap<String,
|
// Page>();
|
||||||
// Page>();
|
|
||||||
|
public static void main(String[] args) { // http://stackoverflow.com/questions/9266632/access-restriction-is-not-accessible-due-to-restriction-on-required-library/10642163#10642163
|
||||||
public static void main(String[] args) { // http://stackoverflow.com/questions/9266632/access-restriction-is-not-accessible-due-to-restriction-on-required-library/10642163#10642163
|
try { // rt.jar Javadoc:
|
||||||
try { // rt.jar Javadoc:
|
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
|
||||||
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
|
// https://docs.oracle.com/javase/8/docs/api/
|
||||||
// https://docs.oracle.com/javase/8/docs/api/
|
System.out.println(System.getProperty("java.class.path")); // TODO:
|
||||||
System.out.println(System.getProperty("java.class.path")); // TODO:
|
// log4j
|
||||||
// log4j
|
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
||||||
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
|
Configuration config = ctx.getConfiguration();
|
||||||
Configuration config = ctx.getConfiguration();
|
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
||||||
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
|
loggerConfig.setLevel(Level.WARN);
|
||||||
loggerConfig.setLevel(Level.WARN);
|
ctx.updateLoggers(); // This causes all Loggers to refetch
|
||||||
ctx.updateLoggers(); // This causes all Loggers to refetch
|
// information from their LoggerConfig.
|
||||||
// information from their LoggerConfig.
|
System.out.println("Loading database...");
|
||||||
System.out.println("Loading database...");
|
try (DataProvider provider = new DataProvider()) {
|
||||||
try (DataProvider provider = new DataProvider()) {
|
User user = new User();
|
||||||
User user = new User();
|
user.setName("asd");
|
||||||
user.setName("asd");
|
user.setEmail("test@test.com");
|
||||||
user.setEmail("test@test.com");
|
User user2 = new User();
|
||||||
User user2 = new User();
|
user2.setName("Teszt");
|
||||||
user2.setName("Teszt");
|
user2.setEmail("test2@test.com");
|
||||||
user2.setEmail("test2@test.com");
|
user2.getContacts().add(user);
|
||||||
user2.getContacts().add(user);
|
provider.saveUser(user);
|
||||||
provider.addUser(user);
|
List<User> users = provider.getUsers();
|
||||||
List<User> users = provider.getUsers();
|
user = users.get(0);
|
||||||
user = users.get(0);
|
user.getContacts().add(user2);
|
||||||
user.getContacts().add(user2);
|
provider.saveUser(user2);
|
||||||
provider.addUser(user2);
|
users = provider.getUsers();
|
||||||
users = provider.getUsers();
|
user2 = users.get(1);
|
||||||
user2 = users.get(1);
|
System.out.println(users);
|
||||||
System.out.println(users);
|
System.out.println("1st's contact: " + user.getContacts().get(0));
|
||||||
System.out.println("1st's contact: " + user.getContacts().get(0));
|
System.out.println("2nd's contact: " + user2.getContacts().get(0));
|
||||||
System.out.println("2nd's contact: " + user2.getContacts().get(0));
|
Conversation convo = new Conversation();
|
||||||
Conversation convo = new Conversation();
|
convo.getUsers().add(user);
|
||||||
convo.getUsers().add(user);
|
convo.getUsers().add(user2);
|
||||||
convo.getUsers().add(user2);
|
Message msg = new Message();
|
||||||
Message msg = new Message();
|
msg.setSender(user);
|
||||||
msg.setSender(user);
|
msg.setTime(new Date());
|
||||||
msg.setTime(new Date());
|
msg.setMessage("Teszt 1");
|
||||||
msg.setMessage("Teszt 1");
|
convo.getMesssages().add(msg);
|
||||||
convo.getMesssages().add(msg);
|
Message msg2 = new Message();
|
||||||
Message msg2 = new Message();
|
msg2.setSender(user2);
|
||||||
msg2.setSender(user2);
|
msg2.setTime(new Date());
|
||||||
msg2.setTime(new Date());
|
msg2.setMessage("Teszt 2");
|
||||||
msg2.setMessage("Teszt 2");
|
convo.getMesssages().add(msg2);
|
||||||
convo.getMesssages().add(msg2);
|
provider.saveConversation(convo);
|
||||||
provider.addConversation(convo);
|
}
|
||||||
}
|
System.out.println("Starting webserver...");
|
||||||
System.out.println("Starting webserver...");
|
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
|
||||||
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
|
Reflections rf = new Reflections(
|
||||||
Reflections rf = new Reflections(
|
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
|
||||||
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
|
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
|
||||||
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
|
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
|
||||||
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
|
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
|
||||||
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
|
for (Class<? extends Page> page : pages) {
|
||||||
for (Class<? extends Page> page : pages) {
|
try {
|
||||||
try {
|
if (Modifier.isAbstract(page.getModifiers()))
|
||||||
if (Modifier.isAbstract(page.getModifiers()))
|
continue;
|
||||||
continue;
|
Page p = page.newInstance();
|
||||||
Page p = page.newInstance();
|
addPage(server, p);
|
||||||
addPage(server, p);
|
} catch (InstantiationException e) {
|
||||||
} catch (InstantiationException e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
} catch (IllegalAccessException e) {
|
||||||
} catch (IllegalAccessException e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
}
|
||||||
}
|
server.start();
|
||||||
server.start();
|
System.out.println("Ready... Press Enter to stop.");
|
||||||
System.out.println("Ready... Press Enter to stop.");
|
System.in.read();
|
||||||
System.in.read();
|
System.out.println("Stopping...");
|
||||||
System.out.println("Stopping...");
|
server.stop(1);
|
||||||
server.stop(1);
|
} catch (Exception e) {
|
||||||
} catch (Exception e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
}
|
||||||
}
|
System.out.println("Stopped");
|
||||||
System.out.println("Stopped");
|
}
|
||||||
}
|
|
||||||
|
private static void addPage(HttpServer server, Page page) {
|
||||||
private static void addPage(HttpServer server, Page page) {
|
server.createContext("/" + page.GetName(), page);
|
||||||
server.createContext("/" + page.GetName(), page);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,87 +1,100 @@
|
||||||
package io.github.norbipeti.chat.server.db;
|
package io.github.norbipeti.chat.server.db;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.Persistence;
|
import javax.persistence.Persistence;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import io.github.norbipeti.chat.server.db.domain.*;
|
import org.hibernate.Session;
|
||||||
|
|
||||||
public class DataProvider implements AutoCloseable {
|
import io.github.norbipeti.chat.server.db.domain.*;
|
||||||
private EntityManagerFactory emf;
|
|
||||||
|
public class DataProvider implements AutoCloseable {
|
||||||
public DataProvider() {
|
private EntityManagerFactory emf;
|
||||||
emf = Persistence.createEntityManagerFactory("ChatServerPU");
|
|
||||||
}
|
public DataProvider() {
|
||||||
|
emf = Persistence.createEntityManagerFactory("ChatServerPU");
|
||||||
public void addUser(User user) {
|
}
|
||||||
save(user);
|
|
||||||
}
|
public void saveUser(User user) {
|
||||||
|
save(user);
|
||||||
public void addConversation(Conversation convo) {
|
}
|
||||||
save(convo);
|
|
||||||
}
|
public void saveConversation(Conversation convo) {
|
||||||
|
save(convo);
|
||||||
private void save(Object object) {
|
}
|
||||||
EntityManager em = emf.createEntityManager();
|
|
||||||
em.getTransaction().begin();
|
private void save(Object object) {
|
||||||
em.persist(object);
|
EntityManager em = emf.createEntityManager();
|
||||||
em.getTransaction().commit();
|
em.getTransaction().begin();
|
||||||
em.close();
|
Session s = em.unwrap(Session.class);
|
||||||
}
|
s.saveOrUpdate(object);
|
||||||
|
em.persist(object);
|
||||||
public List<User> getUsers() {
|
em.getTransaction().commit();
|
||||||
return get(User.class);
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Message> getMessages() {
|
public List<User> getUsers() {
|
||||||
return get(Message.class);
|
return get(User.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Conversation> getConversations() {
|
public List<Message> getMessages() {
|
||||||
return get(Conversation.class);
|
return get(Message.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> List<T> get(Class<T> cl) {
|
public List<Conversation> getConversations() {
|
||||||
EntityManager em = emf.createEntityManager();
|
return get(Conversation.class);
|
||||||
TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl);
|
}
|
||||||
List<T> results = query.getResultList();
|
|
||||||
em.close();
|
private <T> List<T> get(Class<T> cl) {
|
||||||
return results;
|
EntityManager em = emf.createEntityManager();
|
||||||
}
|
TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl);
|
||||||
|
List<T> results = query.getResultList();
|
||||||
public void removeUser(User user) {
|
em.close();
|
||||||
EntityManager em = emf.createEntityManager();
|
return results;
|
||||||
em.getTransaction().begin();
|
}
|
||||||
User managedUser = em.find(User.class, user.getId());
|
|
||||||
em.remove(managedUser);
|
public void removeUser(User user) {
|
||||||
em.getTransaction().commit();
|
EntityManager em = emf.createEntityManager();
|
||||||
em.close();
|
em.getTransaction().begin();
|
||||||
}
|
User managedUser = em.find(User.class, user.getId());
|
||||||
|
em.remove(managedUser);
|
||||||
public User getUser(Long id) {
|
em.getTransaction().commit();
|
||||||
return get(User.class, id);
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T get(Class<T> cl, Long id) {
|
public User getUser(Long id) {
|
||||||
EntityManager em = emf.createEntityManager();
|
return get(User.class, id);
|
||||||
T result = em.find(cl, id);
|
}
|
||||||
em.close();
|
|
||||||
return result;
|
private <T> T get(Class<T> cl, Long id) {
|
||||||
}
|
EntityManager em = emf.createEntityManager();
|
||||||
|
T result = em.find(cl, id);
|
||||||
public void SetValues(Runnable action) {
|
em.close();
|
||||||
EntityManager em = emf.createEntityManager();
|
return result;
|
||||||
em.getTransaction().begin();
|
}
|
||||||
action.run();
|
|
||||||
em.getTransaction().commit();
|
@Deprecated
|
||||||
em.close();
|
public void SetValues(Runnable action) {
|
||||||
}
|
EntityManager em = emf.createEntityManager();
|
||||||
|
em.getTransaction().begin();
|
||||||
@Override
|
action.run();
|
||||||
public void close() {
|
em.flush();
|
||||||
if (emf != null)
|
em.getTransaction().commit();
|
||||||
emf.close();
|
em.close();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (emf != null)
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEntityManaged(Object entity) {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
boolean ret = em.contains(entity);
|
||||||
|
em.close();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,115 +1,113 @@
|
||||||
package io.github.norbipeti.chat.server.db.domain;
|
package io.github.norbipeti.chat.server.db.domain;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import javax.persistence.*;
|
||||||
|
|
||||||
import javax.persistence.*;
|
@Entity
|
||||||
|
@Table(name = "\"User\"")
|
||||||
@Entity
|
public class User {
|
||||||
@Table(name = "\"User\"")
|
@Id
|
||||||
public class User {
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Id
|
@Column(name = "id", unique = true, nullable = false)
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
private Long id;
|
||||||
@Column(name = "id", unique = true, nullable = false)
|
private String name;
|
||||||
private Long id;
|
private String email;
|
||||||
private String name;
|
private String password;
|
||||||
private String email;
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
private String password;
|
private List<User> contacts;
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
private String salt;
|
||||||
private List<User> contacts;
|
//@Column(columnDefinition = "CHAR(16) FOR BIT DATA")
|
||||||
private String salt;
|
@Column(columnDefinition="VARCHAR(64)")
|
||||||
@Column(columnDefinition = "CHAR(16) FOR BIT DATA")
|
private String sessionid;
|
||||||
private UUID sessionid;
|
@Version
|
||||||
@Version
|
@GeneratedValue
|
||||||
@GeneratedValue
|
private int Version;
|
||||||
private int Version;
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
@ManyToMany(cascade = CascadeType.ALL)
|
||||||
@ManyToMany(cascade = CascadeType.ALL)
|
public List<Conversation> conversations;
|
||||||
public List<Conversation> conversations;
|
|
||||||
|
public List<User> getContacts() {
|
||||||
public List<User> getContacts() {
|
if (contacts == null)
|
||||||
if (contacts == null)
|
contacts = new ArrayList<>();
|
||||||
contacts = new ArrayList<>();
|
return contacts;
|
||||||
return contacts;
|
}
|
||||||
}
|
|
||||||
|
public void setContacts(List<User> contacts) {
|
||||||
public void setContacts(List<User> contacts) {
|
this.contacts = contacts;
|
||||||
this.contacts = contacts;
|
}
|
||||||
}
|
|
||||||
|
public String getName() {
|
||||||
public String getName() {
|
return name;
|
||||||
return name;
|
}
|
||||||
}
|
|
||||||
|
public void setName(String name) {
|
||||||
public void setName(String name) {
|
this.name = name;
|
||||||
this.name = name;
|
}
|
||||||
}
|
|
||||||
|
public String getEmail() {
|
||||||
public String getEmail() {
|
return email;
|
||||||
return email;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String toString() {
|
||||||
public String toString() {
|
List<String> c = null;
|
||||||
List<String> c = null;
|
if (contacts != null) {
|
||||||
if (contacts != null) {
|
c = new ArrayList<>();
|
||||||
c = new ArrayList<>();
|
for (User u : contacts)
|
||||||
for (User u : contacts)
|
c.add(u.name);
|
||||||
c.add(u.name);
|
}
|
||||||
}
|
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
|
||||||
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
|
+ ", sessionid=" + sessionid + "]";
|
||||||
+ ", sessionid=" + sessionid + "]"; // TODO: SessionID null
|
}
|
||||||
// after getting from db
|
|
||||||
}
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
public void setEmail(String email) {
|
}
|
||||||
this.email = email;
|
|
||||||
}
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
public String getPassword() {
|
}
|
||||||
return password;
|
|
||||||
}
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
public void setPassword(String password) {
|
}
|
||||||
this.password = password;
|
|
||||||
}
|
public Long getId() {
|
||||||
|
return id;
|
||||||
public Long getId() {
|
}
|
||||||
return id;
|
|
||||||
}
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
public void setId(Long id) {
|
}
|
||||||
this.id = id;
|
|
||||||
}
|
public String getSalt() {
|
||||||
|
return salt;
|
||||||
public String getSalt() {
|
}
|
||||||
return salt;
|
|
||||||
}
|
public void setSalt(String salt) {
|
||||||
|
this.salt = salt;
|
||||||
public void setSalt(String salt) {
|
}
|
||||||
this.salt = salt;
|
|
||||||
}
|
public String getSessionid() {
|
||||||
|
return sessionid;
|
||||||
public UUID getSessionid() {
|
}
|
||||||
return sessionid;
|
|
||||||
}
|
public void setSessionid(String sessionid) {
|
||||||
|
this.sessionid = sessionid;
|
||||||
public void setSessionid(UUID sessionid) {
|
}
|
||||||
this.sessionid = sessionid;
|
|
||||||
}
|
public List<Conversation> getConversations() {
|
||||||
|
if (conversations == null)
|
||||||
public List<Conversation> getConversations() {
|
conversations = new ArrayList<>();
|
||||||
if (conversations == null)
|
return conversations;
|
||||||
conversations = new ArrayList<>();
|
}
|
||||||
return conversations;
|
|
||||||
}
|
public void setConversations(List<Conversation> conversations) {
|
||||||
|
this.conversations = conversations;
|
||||||
public void setConversations(List<Conversation> conversations) {
|
}
|
||||||
this.conversations = conversations;
|
|
||||||
}
|
public User() {
|
||||||
|
|
||||||
public User() {
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,60 +1,53 @@
|
||||||
package io.github.norbipeti.chat.server.page;
|
package io.github.norbipeti.chat.server.page;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
import com.sun.net.ssl.internal.ssl.Provider;
|
import io.github.norbipeti.chat.server.IOHelper;
|
||||||
|
import io.github.norbipeti.chat.server.db.DataProvider;
|
||||||
import io.github.norbipeti.chat.server.IOHelper;
|
import io.github.norbipeti.chat.server.db.domain.User;
|
||||||
import io.github.norbipeti.chat.server.db.DataProvider;
|
|
||||||
import io.github.norbipeti.chat.server.db.domain.Conversation;
|
public class IndexPage extends Page {
|
||||||
import io.github.norbipeti.chat.server.db.domain.Message;
|
|
||||||
import io.github.norbipeti.chat.server.db.domain.User;
|
@Override
|
||||||
|
public void handlePage(HttpExchange exchange) throws IOException {
|
||||||
public class IndexPage extends Page {
|
final User user = IOHelper.GetLoggedInUser(exchange);
|
||||||
|
/*final User user = new User();
|
||||||
@Override
|
user.setEmail("test@test.com");
|
||||||
public void handlePage(HttpExchange exchange) throws IOException {
|
user.setName("Norbi");
|
||||||
// final User user = IOHelper.GetLoggedInUser(exchange); - TODO
|
user.setId(3L);*/
|
||||||
final User user = new User();
|
if (user == null)
|
||||||
user.setEmail("test@test.com");
|
IOHelper.SendModifiedPage(200, this, (doc) -> {
|
||||||
user.setName("Norbi");
|
doc.getElementById("userbox").remove();
|
||||||
user.setId(3L);
|
doc.getElementById("usercontent").remove();
|
||||||
if (user == null)
|
return doc;
|
||||||
IOHelper.SendModifiedPage(200, this, (doc) -> {
|
}, exchange);
|
||||||
doc.getElementById("userbox").remove();
|
else
|
||||||
doc.getElementById("usercontent").remove();
|
IOHelper.SendModifiedPage(200, this, (doc) -> {
|
||||||
return doc;
|
doc.getElementById("loginbox").remove();
|
||||||
}, exchange);
|
doc.getElementById("registerbox").remove();
|
||||||
else
|
Element userbox = doc.getElementById("userbox");
|
||||||
IOHelper.SendModifiedPage(200, this, (doc) -> {
|
userbox.html(userbox.html().replace("<username />", user.getName()));
|
||||||
doc.getElementById("loginbox").remove();
|
Element channelmessages = doc.getElementById("channelmessages");
|
||||||
doc.getElementById("registerbox").remove();
|
try (DataProvider provider = new DataProvider()) {
|
||||||
Element userbox = doc.getElementById("userbox");
|
/*Conversation convo = provider.getConversations().get(0); // TODO
|
||||||
userbox.html(userbox.html().replace("<username />", user.getName()));
|
for (Message message : convo.getMesssages()) {
|
||||||
Element channelmessages = doc.getElementById("channelmessages");
|
Element msgelement = channelmessages.appendElement("div");
|
||||||
try (DataProvider provider = new DataProvider()) {
|
Element header = msgelement.appendElement("p");
|
||||||
Conversation convo = provider.getConversations().get(0); //TODO
|
header.text(message.getSender().getName() + " - " + message.getTime());
|
||||||
for (Message message : convo.getMesssages()) {
|
Element body = msgelement.appendElement("p");
|
||||||
Element msgelement = channelmessages.appendElement("div");
|
body.text(message.getMessage());
|
||||||
Element header = msgelement.appendElement("p");
|
}*/
|
||||||
header.text(message.getSender().getName() + " - " + message.getTime());
|
}
|
||||||
Element body = msgelement.appendElement("p");
|
return doc;
|
||||||
body.text(message.getMessage());
|
}, exchange);
|
||||||
}
|
} // TODO: Validation at registration (no special chars, etc.)
|
||||||
}
|
|
||||||
return doc;
|
@Override
|
||||||
}, exchange);
|
public String GetName() {
|
||||||
} // TODO:
|
return "";
|
||||||
// Validation
|
}
|
||||||
// at
|
|
||||||
// registration
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String GetName() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,72 +1,72 @@
|
||||||
package io.github.norbipeti.chat.server.page;
|
package io.github.norbipeti.chat.server.page;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.mindrot.jbcrypt.BCrypt;
|
import org.mindrot.jbcrypt.BCrypt;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
|
||||||
import io.github.norbipeti.chat.server.IOHelper;
|
import io.github.norbipeti.chat.server.IOHelper;
|
||||||
import io.github.norbipeti.chat.server.db.DataProvider;
|
import io.github.norbipeti.chat.server.db.DataProvider;
|
||||||
import io.github.norbipeti.chat.server.db.domain.User;
|
import io.github.norbipeti.chat.server.db.domain.User;
|
||||||
|
|
||||||
public class RegisterPage extends Page {
|
public class RegisterPage extends Page {
|
||||||
@Override
|
@Override
|
||||||
public void handlePage(HttpExchange exchange) throws IOException {
|
public void handlePage(HttpExchange exchange) throws IOException {
|
||||||
JSONObject post = IOHelper.GetPOSTJSON(exchange);
|
JSONObject post = IOHelper.GetPOSTJSON(exchange);
|
||||||
if (post != null) {
|
if (post != null) {
|
||||||
String errormsg = CheckValues(post, "name", "email", "pass", "pass2");
|
String errormsg = CheckValues(post, "name", "email", "pass", "pass2");
|
||||||
if (errormsg.length() > 0) {
|
if (errormsg.length() > 0) {
|
||||||
final String msg = errormsg;
|
final String msg = errormsg;
|
||||||
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
|
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
|
||||||
return; // TODO: Use JavaScript too, for error checks
|
return; // TODO: Use JavaScript too, for error checks
|
||||||
}
|
}
|
||||||
try (DataProvider provider = new DataProvider()) {
|
try (DataProvider provider = new DataProvider()) {
|
||||||
for (User user : provider.getUsers()) {
|
for (User user : provider.getUsers()) {
|
||||||
if (post.get("email").equals(user.getEmail())) {
|
if (post.get("email").equals(user.getEmail())) {
|
||||||
errormsg += "<p>An user with this name already exists</p>";
|
errormsg += "<p>An user with this name already exists</p>";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!post.get("pass").equals(post.get("pass2")))
|
if (!post.get("pass").equals(post.get("pass2")))
|
||||||
errormsg += "<p>The passwords don't match</p>";
|
errormsg += "<p>The passwords don't match</p>";
|
||||||
if (errormsg.length() > 0) {
|
if (errormsg.length() > 0) {
|
||||||
final String msg = errormsg;
|
final String msg = errormsg;
|
||||||
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
|
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setName(post.getString("name"));
|
user.setName(post.getString("name"));
|
||||||
user.setEmail(post.getString("email"));
|
user.setEmail(post.getString("email"));
|
||||||
user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/
|
user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/
|
||||||
user.setPassword(BCrypt.hashpw(post.getString("pass"), user.getSalt()));
|
user.setPassword(BCrypt.hashpw(post.getString("pass"), user.getSalt()));
|
||||||
provider.addUser(user);
|
provider.saveUser(user);
|
||||||
User managedUser = provider.getUser(user.getId());
|
User managedUser = provider.getUser(user.getId());
|
||||||
IOHelper.LoginUser(exchange, managedUser, provider);
|
IOHelper.LoginUser(exchange, managedUser, provider);
|
||||||
IOHelper.SendResponse(200, "Success", exchange);
|
IOHelper.SendResponse(200, "Success", exchange);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IOHelper.Redirect("/", exchange);
|
IOHelper.Redirect("/", exchange);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String CheckValues(JSONObject post, String... values) {
|
private String CheckValues(JSONObject post, String... values) {
|
||||||
String errormsg = "";
|
String errormsg = "";
|
||||||
for (String value : values)
|
for (String value : values)
|
||||||
if (!CheckValue(post.getString(value)))
|
if (!CheckValue(post.getString(value)))
|
||||||
errormsg += "<p>" + value + " can't be empty</p>";
|
errormsg += "<p>" + value + " can't be empty</p>";
|
||||||
return errormsg;
|
return errormsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean CheckValue(String val) {
|
private boolean CheckValue(String val) {
|
||||||
return val != null && val.length() > 0;
|
return val != null && val.length() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String GetName() {
|
public String GetName() {
|
||||||
return "register";
|
return "register";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue