Compare commits
No commits in common. "2ae9509782aa71e7a05fe775280d7de4eafdec58" and "4cc569678883ce49872227d34d8a80b42ec0f329" have entirely different histories.
2ae9509782
...
4cc5696788
@ -1,198 +0,0 @@
|
|||||||
# 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
|
|
||||||
#
|
|
||||||
# http://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.
|
|
||||||
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# List of comma-separated paths defining the contents of the "common"
|
|
||||||
# classloader. Prefixes should be used to define what is the repository type.
|
|
||||||
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
|
|
||||||
# If left as blank,the JVM system loader will be used as Catalina's "common"
|
|
||||||
# loader.
|
|
||||||
# Examples:
|
|
||||||
# "foo": Add this folder as a class repository
|
|
||||||
# "foo/*.jar": Add all the JARs of the specified folder as class
|
|
||||||
# repositories
|
|
||||||
# "foo/bar.jar": Add bar.jar as a class repository
|
|
||||||
#
|
|
||||||
# Note: Values are enclosed in double quotes ("...") in case either the
|
|
||||||
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
|
||||||
# Because double quotes are used for quoting, the double quote character
|
|
||||||
# may not appear in a path.
|
|
||||||
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
|
|
||||||
|
|
||||||
#
|
|
||||||
# List of comma-separated paths defining the contents of the "server"
|
|
||||||
# classloader. Prefixes should be used to define what is the repository type.
|
|
||||||
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
|
|
||||||
# If left as blank, the "common" loader will be used as Catalina's "server"
|
|
||||||
# loader.
|
|
||||||
# Examples:
|
|
||||||
# "foo": Add this folder as a class repository
|
|
||||||
# "foo/*.jar": Add all the JARs of the specified folder as class
|
|
||||||
# repositories
|
|
||||||
# "foo/bar.jar": Add bar.jar as a class repository
|
|
||||||
#
|
|
||||||
# Note: Values may be enclosed in double quotes ("...") in case either the
|
|
||||||
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
|
||||||
# Because double quotes are used for quoting, the double quote character
|
|
||||||
# may not appear in a path.
|
|
||||||
server.loader=
|
|
||||||
|
|
||||||
#
|
|
||||||
# List of comma-separated paths defining the contents of the "shared"
|
|
||||||
# classloader. Prefixes should be used to define what is the repository type.
|
|
||||||
# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
|
|
||||||
# the "common" loader will be used as Catalina's "shared" loader.
|
|
||||||
# Examples:
|
|
||||||
# "foo": Add this folder as a class repository
|
|
||||||
# "foo/*.jar": Add all the JARs of the specified folder as class
|
|
||||||
# repositories
|
|
||||||
# "foo/bar.jar": Add bar.jar as a class repository
|
|
||||||
# Please note that for single jars, e.g. bar.jar, you need the URL form
|
|
||||||
# starting with file:.
|
|
||||||
#
|
|
||||||
# Note: Values may be enclosed in double quotes ("...") in case either the
|
|
||||||
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
|
||||||
# Because double quotes are used for quoting, the double quote character
|
|
||||||
# may not appear in a path.
|
|
||||||
shared.loader=
|
|
||||||
|
|
||||||
# Default list of JAR files that should not be scanned using the JarScanner
|
|
||||||
# functionality. This is typically used to scan JARs for configuration
|
|
||||||
# information. JARs that do not contain such information may be excluded from
|
|
||||||
# the scan to speed up the scanning process. This is the default list. JARs on
|
|
||||||
# this list are excluded from all scans. The list must be a comma separated list
|
|
||||||
# of JAR file names.
|
|
||||||
# The list of JARs to skip may be over-ridden at a Context level for individual
|
|
||||||
# scan types by configuring a JarScanner with a nested JarScanFilter.
|
|
||||||
# The JARs listed below include:
|
|
||||||
# - Tomcat Bootstrap JARs
|
|
||||||
# - Tomcat API JARs
|
|
||||||
# - Catalina JARs
|
|
||||||
# - Jasper JARs
|
|
||||||
# - Tomcat JARs
|
|
||||||
# - Common non-Tomcat JARs
|
|
||||||
# - Test JARs (JUnit, Cobertura and dependencies)
|
|
||||||
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\
|
|
||||||
annotations-api.jar,\
|
|
||||||
ant-junit*.jar,\
|
|
||||||
ant-launcher*.jar,\
|
|
||||||
ant*.jar,\
|
|
||||||
asm-*.jar,\
|
|
||||||
aspectj*.jar,\
|
|
||||||
bcel*.jar,\
|
|
||||||
biz.aQute.bnd*.jar,\
|
|
||||||
bootstrap.jar,\
|
|
||||||
catalina-ant.jar,\
|
|
||||||
catalina-ha.jar,\
|
|
||||||
catalina-ssi.jar,\
|
|
||||||
catalina-storeconfig.jar,\
|
|
||||||
catalina-tribes.jar,\
|
|
||||||
catalina.jar,\
|
|
||||||
cglib-*.jar,\
|
|
||||||
cobertura-*.jar,\
|
|
||||||
commons-beanutils*.jar,\
|
|
||||||
commons-codec*.jar,\
|
|
||||||
commons-collections*.jar,\
|
|
||||||
commons-compress*.jar,\
|
|
||||||
commons-daemon.jar,\
|
|
||||||
commons-dbcp*.jar,\
|
|
||||||
commons-digester*.jar,\
|
|
||||||
commons-fileupload*.jar,\
|
|
||||||
commons-httpclient*.jar,\
|
|
||||||
commons-io*.jar,\
|
|
||||||
commons-lang*.jar,\
|
|
||||||
commons-logging*.jar,\
|
|
||||||
commons-math*.jar,\
|
|
||||||
commons-pool*.jar,\
|
|
||||||
derby-*.jar,\
|
|
||||||
dom4j-*.jar,\
|
|
||||||
easymock-*.jar,\
|
|
||||||
ecj-*.jar,\
|
|
||||||
el-api.jar,\
|
|
||||||
geronimo-spec-jaxrpc*.jar,\
|
|
||||||
h2*.jar,\
|
|
||||||
ha-api-*.jar,\
|
|
||||||
hamcrest-*.jar,\
|
|
||||||
hibernate*.jar,\
|
|
||||||
httpclient*.jar,\
|
|
||||||
icu4j-*.jar,\
|
|
||||||
jakartaee-migration-*.jar,\
|
|
||||||
jasper-el.jar,\
|
|
||||||
jasper.jar,\
|
|
||||||
jaspic-api.jar,\
|
|
||||||
jaxb-*.jar,\
|
|
||||||
jaxen-*.jar,\
|
|
||||||
jaxws-rt-*.jar,\
|
|
||||||
jdom-*.jar,\
|
|
||||||
jetty-*.jar,\
|
|
||||||
jmx-tools.jar,\
|
|
||||||
jmx.jar,\
|
|
||||||
jsp-api.jar,\
|
|
||||||
jstl.jar,\
|
|
||||||
jta*.jar,\
|
|
||||||
junit-*.jar,\
|
|
||||||
junit.jar,\
|
|
||||||
log4j*.jar,\
|
|
||||||
mail*.jar,\
|
|
||||||
objenesis-*.jar,\
|
|
||||||
oraclepki.jar,\
|
|
||||||
org.hamcrest.core_*.jar,\
|
|
||||||
org.junit_*.jar,\
|
|
||||||
oro-*.jar,\
|
|
||||||
servlet-api-*.jar,\
|
|
||||||
servlet-api.jar,\
|
|
||||||
slf4j*.jar,\
|
|
||||||
taglibs-standard-spec-*.jar,\
|
|
||||||
tagsoup-*.jar,\
|
|
||||||
tomcat-api.jar,\
|
|
||||||
tomcat-coyote.jar,\
|
|
||||||
tomcat-coyote-ffm.jar,\
|
|
||||||
tomcat-dbcp.jar,\
|
|
||||||
tomcat-i18n-*.jar,\
|
|
||||||
tomcat-jdbc.jar,\
|
|
||||||
tomcat-jni.jar,\
|
|
||||||
tomcat-juli-adapters.jar,\
|
|
||||||
tomcat-juli.jar,\
|
|
||||||
tomcat-util-scan.jar,\
|
|
||||||
tomcat-util.jar,\
|
|
||||||
tomcat-websocket.jar,\
|
|
||||||
tools.jar,\
|
|
||||||
unboundid-ldapsdk-*.jar,\
|
|
||||||
websocket-api.jar,\
|
|
||||||
websocket-client-api.jar,\
|
|
||||||
wsdl4j*.jar,\
|
|
||||||
xercesImpl.jar,\
|
|
||||||
xml-apis.jar,\
|
|
||||||
xmlParserAPIs-*.jar,\
|
|
||||||
xmlParserAPIs.jar,\
|
|
||||||
xom-*.jar
|
|
||||||
|
|
||||||
# Default list of JAR files that should be scanned that overrides the default
|
|
||||||
# jarsToSkip list above. This is typically used to include a specific JAR that
|
|
||||||
# has been excluded by a broad file name pattern in the jarsToSkip list.
|
|
||||||
# The list of JARs to scan may be over-ridden at a Context level for individual
|
|
||||||
# scan types by configuring a JarScanner with a nested JarScanFilter.
|
|
||||||
tomcat.util.scan.StandardJarScanFilter.jarsToScan=\
|
|
||||||
log4j-taglib*.jar,\
|
|
||||||
log4j-jakarta-web*.jar,\
|
|
||||||
log4javascript*.jar,\
|
|
||||||
slf4j-taglib*.jar
|
|
||||||
|
|
||||||
# String cache configuration.
|
|
||||||
tomcat.util.buf.StringCache.byte.enabled=true
|
|
||||||
#tomcat.util.buf.StringCache.char.enabled=true
|
|
||||||
#tomcat.util.buf.StringCache.trainThreshold=500000
|
|
||||||
#tomcat.util.buf.StringCache.cacheSize=5000
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<!-- The contents of this file will be loaded for each web application -->
|
|
||||||
<Context>
|
|
||||||
|
|
||||||
<!-- Default set of monitored resources. If one of these changes, the -->
|
|
||||||
<!-- web application will be reloaded. -->
|
|
||||||
<WatchedResource>WEB-INF/web.xml</WatchedResource>
|
|
||||||
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
|
|
||||||
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
|
|
||||||
|
|
||||||
<!-- Uncomment this to enable session persistence across Tomcat restarts -->
|
|
||||||
<!--
|
|
||||||
<Manager pathname="SESSIONS.ser" />
|
|
||||||
-->
|
|
||||||
</Context>
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<jaspic-providers xmlns="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://tomcat.apache.org/xml jaspic-providers.xsd"
|
|
||||||
version="1.0">
|
|
||||||
<!-- No JASPIC providers configured by default -->
|
|
||||||
</jaspic-providers>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema"
|
|
||||||
targetNamespace="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:jaspic="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
||||||
elementFormDefault="qualified"
|
|
||||||
attributeFormDefault="unqualified"
|
|
||||||
version="1.0">
|
|
||||||
<xs:element name="jaspic-providers">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:sequence>
|
|
||||||
<xs:element name="provider" minOccurs="0" maxOccurs="unbounded">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:sequence>
|
|
||||||
<xs:element name="property" minOccurs="0" maxOccurs="unbounded">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:attribute name="name" use="required" type="jaspic:propertyname" />
|
|
||||||
<xs:attribute name="value" use="required" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:sequence>
|
|
||||||
<xs:attribute name="className" type="xs:string" />
|
|
||||||
<xs:attribute name="layer" type="xs:string" />
|
|
||||||
<xs:attribute name="appContext" type="xs:string" />
|
|
||||||
<xs:attribute name="description" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:sequence>
|
|
||||||
<xs:attribute name="version" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:simpleType name="propertyname">
|
|
||||||
<xs:restriction base="xs:string">
|
|
||||||
<xs:minLength value="1"/>
|
|
||||||
</xs:restriction>
|
|
||||||
</xs:simpleType>
|
|
||||||
</xs:schema>
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
# 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
|
|
||||||
#
|
|
||||||
# http://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.
|
|
||||||
|
|
||||||
handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
|
|
||||||
|
|
||||||
.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Handler specific properties.
|
|
||||||
# Describes specific configuration info for Handlers.
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
1catalina.org.apache.juli.AsyncFileHandler.level = ALL
|
|
||||||
1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
|
||||||
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
|
|
||||||
1catalina.org.apache.juli.AsyncFileHandler.maxDays = 90
|
|
||||||
1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
|
||||||
|
|
||||||
2localhost.org.apache.juli.AsyncFileHandler.level = ALL
|
|
||||||
2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
|
||||||
2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
|
|
||||||
2localhost.org.apache.juli.AsyncFileHandler.maxDays = 90
|
|
||||||
2localhost.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
|
||||||
|
|
||||||
3manager.org.apache.juli.AsyncFileHandler.level = ALL
|
|
||||||
3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
|
||||||
3manager.org.apache.juli.AsyncFileHandler.prefix = manager.
|
|
||||||
3manager.org.apache.juli.AsyncFileHandler.maxDays = 90
|
|
||||||
3manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
|
||||||
|
|
||||||
4host-manager.org.apache.juli.AsyncFileHandler.level = ALL
|
|
||||||
4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
|
||||||
4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.
|
|
||||||
4host-manager.org.apache.juli.AsyncFileHandler.maxDays = 90
|
|
||||||
4host-manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
|
||||||
|
|
||||||
java.util.logging.ConsoleHandler.level = ALL
|
|
||||||
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
|
|
||||||
java.util.logging.ConsoleHandler.encoding = UTF-8
|
|
||||||
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
# Facility specific properties.
|
|
||||||
# Provides extra control for each logger.
|
|
||||||
############################################################
|
|
||||||
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler
|
|
||||||
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler
|
|
||||||
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
|
|
||||||
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler
|
|
||||||
|
|
||||||
# For example, set the org.apache.catalina.util.LifecycleBase logger to log
|
|
||||||
# each component that extends LifecycleBase changing state:
|
|
||||||
#org.apache.catalina.util.LifecycleBase.level = FINE
|
|
||||||
|
|
||||||
# To see debug messages for HTTP/2 handling, uncomment the following line:
|
|
||||||
#org.apache.coyote.http2.level = FINE
|
|
||||||
|
|
||||||
# To see debug messages for WebSocket handling, uncomment the following line:
|
|
||||||
#org.apache.tomcat.websocket.level = FINE
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<!-- Note: A "Server" is not itself a "Container", so you may not
|
|
||||||
define subcomponents such as "Valves" at this level.
|
|
||||||
Documentation at /docs/config/server.html
|
|
||||||
-->
|
|
||||||
<Server port="8005" shutdown="SHUTDOWN">
|
|
||||||
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
|
|
||||||
<!-- Security listener. Documentation at /docs/config/listeners.html
|
|
||||||
<Listener className="org.apache.catalina.security.SecurityListener" />
|
|
||||||
-->
|
|
||||||
<!-- OpenSSL support using Tomcat Native -->
|
|
||||||
<Listener className="org.apache.catalina.core.AprLifecycleListener" />
|
|
||||||
<!-- OpenSSL support using FFM API from Java 22 -->
|
|
||||||
<!-- <Listener className="org.apache.catalina.core.OpenSSLLifecycleListener" /> -->
|
|
||||||
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
|
|
||||||
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
|
|
||||||
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
|
|
||||||
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
|
|
||||||
|
|
||||||
<!-- Global JNDI resources
|
|
||||||
Documentation at /docs/jndi-resources-howto.html
|
|
||||||
-->
|
|
||||||
<GlobalNamingResources>
|
|
||||||
<!-- Editable user database that can also be used by
|
|
||||||
UserDatabaseRealm to authenticate users
|
|
||||||
-->
|
|
||||||
<Resource name="UserDatabase" auth="Container"
|
|
||||||
type="org.apache.catalina.UserDatabase"
|
|
||||||
description="User database that can be updated and saved"
|
|
||||||
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
|
|
||||||
pathname="conf/tomcat-users.xml" />
|
|
||||||
</GlobalNamingResources>
|
|
||||||
|
|
||||||
<!-- A "Service" is a collection of one or more "Connectors" that share
|
|
||||||
a single "Container" Note: A "Service" is not itself a "Container",
|
|
||||||
so you may not define subcomponents such as "Valves" at this level.
|
|
||||||
Documentation at /docs/config/service.html
|
|
||||||
-->
|
|
||||||
<Service name="Catalina">
|
|
||||||
|
|
||||||
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
|
|
||||||
<!--
|
|
||||||
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
|
|
||||||
maxThreads="150" minSpareThreads="4"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- A "Connector" represents an endpoint by which requests are received
|
|
||||||
and responses are returned. Documentation at :
|
|
||||||
HTTP Connector: /docs/config/http.html
|
|
||||||
AJP Connector: /docs/config/ajp.html
|
|
||||||
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
|
|
||||||
-->
|
|
||||||
<Connector port="8080" protocol="HTTP/1.1"
|
|
||||||
connectionTimeout="20000"
|
|
||||||
redirectPort="8443" />
|
|
||||||
<!-- A "Connector" using the shared thread pool-->
|
|
||||||
<!--
|
|
||||||
<Connector executor="tomcatThreadPool"
|
|
||||||
port="8080" protocol="HTTP/1.1"
|
|
||||||
connectionTimeout="20000"
|
|
||||||
redirectPort="8443" />
|
|
||||||
-->
|
|
||||||
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
|
|
||||||
This connector uses the NIO implementation. The default
|
|
||||||
SSLImplementation will depend on the presence of the APR/native
|
|
||||||
library and the useOpenSSL attribute of the AprLifecycleListener.
|
|
||||||
Either JSSE or OpenSSL style configuration may be used regardless of
|
|
||||||
the SSLImplementation selected. JSSE style configuration is used below.
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
|
|
||||||
maxThreads="150" SSLEnabled="true">
|
|
||||||
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
|
|
||||||
<SSLHostConfig>
|
|
||||||
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
|
|
||||||
certificateKeystorePassword="changeit" type="RSA" />
|
|
||||||
</SSLHostConfig>
|
|
||||||
</Connector>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Define an AJP 1.3 Connector on port 8009 -->
|
|
||||||
<!--
|
|
||||||
<Connector protocol="AJP/1.3"
|
|
||||||
address="::1"
|
|
||||||
port="8009"
|
|
||||||
redirectPort="8443" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- An Engine represents the entry point (within Catalina) that processes
|
|
||||||
every request. The Engine implementation for Tomcat stand alone
|
|
||||||
analyzes the HTTP headers included with the request, and passes them
|
|
||||||
on to the appropriate Host (virtual host).
|
|
||||||
Documentation at /docs/config/engine.html -->
|
|
||||||
|
|
||||||
<!-- You should set jvmRoute to support load-balancing via AJP ie :
|
|
||||||
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
|
|
||||||
-->
|
|
||||||
<Engine name="Catalina" defaultHost="localhost">
|
|
||||||
|
|
||||||
<!--For clustering, please take a look at documentation at:
|
|
||||||
/docs/cluster-howto.html (simple how to)
|
|
||||||
/docs/config/cluster.html (reference documentation) -->
|
|
||||||
<!--
|
|
||||||
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
|
|
||||||
via a brute-force attack -->
|
|
||||||
<Realm className="org.apache.catalina.realm.LockOutRealm">
|
|
||||||
<!-- This Realm uses the UserDatabase configured in the global JNDI
|
|
||||||
resources under the key "UserDatabase". Any edits
|
|
||||||
that are performed against this UserDatabase are immediately
|
|
||||||
available for use by the Realm. -->
|
|
||||||
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
|
|
||||||
resourceName="UserDatabase"/>
|
|
||||||
</Realm>
|
|
||||||
|
|
||||||
<Host name="localhost" appBase="webapps"
|
|
||||||
unpackWARs="true" autoDeploy="true">
|
|
||||||
|
|
||||||
<!-- SingleSignOn valve, share authentication between web applications
|
|
||||||
Documentation at: /docs/config/valve.html -->
|
|
||||||
<!--
|
|
||||||
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Access log processes all example.
|
|
||||||
Documentation at: /docs/config/valve.html
|
|
||||||
Note: The pattern used is equivalent to using pattern="common" -->
|
|
||||||
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
|
|
||||||
prefix="localhost_access_log" suffix=".txt"
|
|
||||||
pattern="%h %l %u %t "%r" %s %b" />
|
|
||||||
|
|
||||||
</Host>
|
|
||||||
</Engine>
|
|
||||||
</Service>
|
|
||||||
</Server>
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<tomcat-users xmlns="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
|
|
||||||
version="1.0">
|
|
||||||
<!--
|
|
||||||
By default, no user is included in the "manager-gui" role required
|
|
||||||
to operate the "/manager/html" web application. If you wish to use this app,
|
|
||||||
you must define such a user - the username and password are arbitrary.
|
|
||||||
|
|
||||||
Built-in Tomcat manager roles:
|
|
||||||
- manager-gui - allows access to the HTML GUI and the status pages
|
|
||||||
- manager-script - allows access to the HTTP API and the status pages
|
|
||||||
- manager-jmx - allows access to the JMX proxy and the status pages
|
|
||||||
- manager-status - allows access to the status pages only
|
|
||||||
|
|
||||||
The users below are wrapped in a comment and are therefore ignored. If you
|
|
||||||
wish to configure one or more of these users for use with the manager web
|
|
||||||
application, do not forget to remove the <!.. ..> that surrounds them. You
|
|
||||||
will also need to set the passwords to something appropriate.
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<user username="admin" password="<must-be-changed>" roles="manager-gui"/>
|
|
||||||
<user username="robot" password="<must-be-changed>" roles="manager-script"/>
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
The sample user and role entries below are intended for use with the
|
|
||||||
examples web application. They are wrapped in a comment and thus are ignored
|
|
||||||
when reading this file. If you wish to configure these users for use with the
|
|
||||||
examples web application, do not forget to remove the <!.. ..> that surrounds
|
|
||||||
them. You will also need to set the passwords to something appropriate.
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<role rolename="tomcat"/>
|
|
||||||
<role rolename="role1"/>
|
|
||||||
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
|
|
||||||
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
|
|
||||||
<user username="role1" password="<must-be-changed>" roles="role1"/>
|
|
||||||
-->
|
|
||||||
</tomcat-users>
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema"
|
|
||||||
targetNamespace="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:users="http://tomcat.apache.org/xml"
|
|
||||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
||||||
elementFormDefault="qualified"
|
|
||||||
attributeFormDefault="unqualified"
|
|
||||||
version="1.0">
|
|
||||||
<xs:element name="tomcat-users">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
|
||||||
<xs:element name="role">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:attribute name="rolename" use="required" type="users:entityname" />
|
|
||||||
<xs:attribute name="description" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:element name="group">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:attribute name="groupname" use="required" type="users:entityname" />
|
|
||||||
<xs:attribute name="description" type="xs:string" />
|
|
||||||
<xs:attribute name="roles" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:element name="user">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:attribute name="username" use="required" type="users:entityname" />
|
|
||||||
<xs:attribute name="fullname" type="xs:string" />
|
|
||||||
<xs:attribute name="password" type="xs:string" />
|
|
||||||
<xs:attribute name="roles" type="xs:string" />
|
|
||||||
<xs:attribute name="groups" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:choice>
|
|
||||||
<xs:attribute name="version" type="xs:string" />
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:simpleType name="entityname">
|
|
||||||
<xs:restriction base="xs:string">
|
|
||||||
<xs:minLength value="1"/>
|
|
||||||
</xs:restriction>
|
|
||||||
</xs:simpleType>
|
|
||||||
</xs:schema>
|
|
||||||
110
README.md
@ -1,110 +0,0 @@
|
|||||||
# Tinder Clone
|
|
||||||
|
|
||||||
Образовательный проект - клон приложения Tinder, реализованный на Java с использованием Jakarta Servlet API.
|
|
||||||
|
|
||||||
## Описание проекта
|
|
||||||
|
|
||||||
Это веб-приложение, имитирующее функциональность популярного приложения для знакомств Tinder. Проект разработан в учебных целях для демонстрации навыков разработки на Java EE/Jakarta EE.
|
|
||||||
|
|
||||||
## Основной функционал
|
|
||||||
|
|
||||||
- **Регистрация и аутентификация пользователей**
|
|
||||||
- **Управление профилями** (создание, просмотр, редактирование)
|
|
||||||
- **Система ролей** (ADMIN, USER)
|
|
||||||
- **Мультиязычность** (поддержка русского и английского языков)
|
|
||||||
- **Фильтрация и безопасность** (AuthFilter, ErrorFilter)
|
|
||||||
- **Валидация данных**
|
|
||||||
|
|
||||||
## Технологический стек
|
|
||||||
|
|
||||||
- **Java 17+**
|
|
||||||
- **Jakarta Servlet API**
|
|
||||||
- **JSP (JavaServer Pages)**
|
|
||||||
- **JSTL (Jakarta Standard Tag Library)**
|
|
||||||
- **Lombok** (для генерации кода)
|
|
||||||
- **SLF4J** (для логирования)
|
|
||||||
- **Maven/Gradle** (сборка проекта)
|
|
||||||
|
|
||||||
## Архитектура проекта
|
|
||||||
|
|
||||||
Проект следует многослойной архитектуре:
|
|
||||||
|
|
||||||
```
|
|
||||||
src/ru/charm/back/
|
|
||||||
├── controller/ # Контроллеры и фильтры
|
|
||||||
├── dao/ # Объекты доступа к данным (in-memory storage)
|
|
||||||
├── dto/ # Объекты передачи данных
|
|
||||||
├── mapper/ # Мапперы между сущностями
|
|
||||||
├── model/ # Модели данных и исключения
|
|
||||||
├── service/ # Бизнес-логика
|
|
||||||
├── utils/ # Утилитные классы
|
|
||||||
└── validator/ # Валидаторы
|
|
||||||
```
|
|
||||||
|
|
||||||
## Основные компоненты
|
|
||||||
|
|
||||||
### Модели данных
|
|
||||||
- **Profile** - основная сущность пользователя
|
|
||||||
- **Gender** - enum (MALE, FEMALE)
|
|
||||||
- **Role** - enum (ADMIN, USER)
|
|
||||||
- **Status** - enum (ACTIVE, INACTIVE)
|
|
||||||
|
|
||||||
### Контроллеры
|
|
||||||
- **RegistrationController** - регистрация новых пользователей
|
|
||||||
- **LoginController** - аутентификация
|
|
||||||
- **ProfileController** - управление профилями
|
|
||||||
- **CredentialsController** - управление учетными данными
|
|
||||||
- **ContentController** - контент приложения
|
|
||||||
- **LanguageController** - переключение языков
|
|
||||||
|
|
||||||
### Фильтры
|
|
||||||
- **AuthFilter** - фильтр аутентификации
|
|
||||||
- **ErrorFilter** - обработка ошибок
|
|
||||||
- **HiddenHttpMethodFilter** - поддержка HTTP методов
|
|
||||||
- **LanguageFilter** - фильтр языковых настроек
|
|
||||||
|
|
||||||
## Установка и запуск
|
|
||||||
|
|
||||||
### Требования
|
|
||||||
- JDK 17 или выше
|
|
||||||
- Apache Tomcat 10+
|
|
||||||
- IDE (IntelliJ IDEA рекомендуется)
|
|
||||||
|
|
||||||
### Запуск проекта
|
|
||||||
1. Клонировать репозиторий
|
|
||||||
2. Открыть проект в IDE
|
|
||||||
3. Настроить Tomcat Server
|
|
||||||
4. Развернуть проект на сервере
|
|
||||||
5. Открыть `http://localhost:8080/Tinder_Clone/` в браузере
|
|
||||||
|
|
||||||
## Структура данных
|
|
||||||
|
|
||||||
Проект использует in-memory хранилище на основе `ConcurrentHashMap` для хранения профилей пользователей. При запуске создаются два тестовых пользователя:
|
|
||||||
|
|
||||||
- **Admin**: ivanov@mail.ru / 123
|
|
||||||
- **User**: sidorova@mail.ru / 456
|
|
||||||
|
|
||||||
## Особенности реализации
|
|
||||||
|
|
||||||
- **Singleton паттерн** для DAO и Service слоев
|
|
||||||
- **Функциональное программирование** с использованием Stream API
|
|
||||||
- **Безопасность** через фильтры и валидацию
|
|
||||||
- **Интернационализация** через resource bundles
|
|
||||||
- **RESTful подход** в контроллерах
|
|
||||||
|
|
||||||
## Возможности для развития
|
|
||||||
|
|
||||||
- Интеграция с реальной базой данных (PostgreSQL, MySQL)
|
|
||||||
- Добавление WebSocket для real-time функциональности
|
|
||||||
- Реализация системы лайков и мэтчей
|
|
||||||
- Добавление загрузки фотографий
|
|
||||||
- Интеграция с социальными сетями
|
|
||||||
- Разработка мобильного приложения
|
|
||||||
|
|
||||||
## Автор
|
|
||||||
|
|
||||||
Проект разработан в образовательных целях как часть курса по веб-разработке на Java.
|
|
||||||
|
|
||||||
## Лицензия
|
|
||||||
|
|
||||||
Этот проект предназначен только для образовательных целей.
|
|
||||||
BIN
lib/lombok.jar
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
@ -1,54 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Email</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<h3 style="color: red">${wordBundle.getWord("email-warning")}</h3>
|
|
||||||
<table>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<form method="post" action="/email?id=${profile.id}" enctype="multipart/form-data">
|
|
||||||
<input type="hidden" name="_method" value="put"/>
|
|
||||||
<input type="hidden" name="id" value="${profile.id}">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("email")}</h3></td>
|
|
||||||
<td><input type="email" name="email" value="${profile.email}"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<td>
|
|
||||||
<input type="image" src="content/app/img/floppy-disk.png" width="75" alt="submit"
|
|
||||||
class="icon"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</tr>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<div style="color: red">
|
|
||||||
<c:forEach var="error" items="${errors}">
|
|
||||||
<span>${wordBundle.getWord(error)}</span>
|
|
||||||
<br>
|
|
||||||
</c:forEach>
|
|
||||||
</div>
|
|
||||||
</tr>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<form method="post" action="/registration">
|
|
||||||
<input type="hidden" name="_method" value="delete"/>
|
|
||||||
<input type="hidden" name="id" value="${profile.id}">
|
|
||||||
<input type="image" src="content/app/img/cross.png" width="75" alt="submit" class="icon"/>
|
|
||||||
</form>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Unexpected Error</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<h3 style="color: red">500 - ${requestScope.wordBundle.getWord("unexpected-error")}</h3>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Bad Request</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<h3>400 - ${requestScope.wordBundle.getWord("page-bad-request")}</h3>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Not Found</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<h3>404 - ${requestScope.wordBundle.getWord("page-not-found")}</h3>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<div>
|
|
||||||
<hr>
|
|
||||||
<small>${requestScope.wordBundle.getWord("all-rights-reserved")} 2024</small>
|
|
||||||
</div>
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<div>
|
|
||||||
<table>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<td>
|
|
||||||
<a href="/"><img src="content/app/img/heart.png" width="75"></a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<form method="post" action="/lang">
|
|
||||||
<button type="submit" name="lang" value="ru" class="langButton">
|
|
||||||
<img src="content/app/img/ru.png" class="langImg">
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<form method="post" action="/lang">
|
|
||||||
<button type="submit" name="lang" value="en" class="langButton">
|
|
||||||
<img src="content/app/img/en.png" class="langImg">
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<c:if test="${sessionScope.userDetails == null}">
|
|
||||||
<a href="/login"><img src="content/app/img/key.png" width="75"></a>
|
|
||||||
</c:if>
|
|
||||||
<c:if test="${sessionScope.userDetails != null}">
|
|
||||||
<form method="post" action="/logout">
|
|
||||||
<input type="image" src="content/app/img/key.png" width="75" alt="submit" class="icon"
|
|
||||||
onclick="return confirm()"/>
|
|
||||||
</form>
|
|
||||||
</c:if>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<hr>
|
|
||||||
</div>
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Login</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<form method="post" action="/login">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("email")}</h3></td>
|
|
||||||
<td><input type="email" name="email" placeholder="user@charm.ru"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("password")}</h3></td>
|
|
||||||
<td><input type="password" name="password"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<td>
|
|
||||||
<a href="/registration"><img src="content/app/img/pencil.png" width="75"></a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input type="image" src="content/app/img/arrow-right.png" width="75" alt="submit"
|
|
||||||
class="icon"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
<div style="color: red">
|
|
||||||
<c:forEach var="error" items="${errors}">
|
|
||||||
<span>${wordBundle.getWord(error)}</span>
|
|
||||||
<br>
|
|
||||||
</c:forEach>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Profile</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<form method="post" action="/profile?id=${profile.id}" enctype="multipart/form-data">
|
|
||||||
<input type="hidden" name="_method" value="put"/>
|
|
||||||
<input type="hidden" name="id" value="${profile.id}">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("name")}</h3></td>
|
|
||||||
<td><input type="text" name="name" value="${profile.name}"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("surname")}</h3></td>
|
|
||||||
<td><input type="text" name="surname" value="${profile.surname}"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("birth-date")}</h3></td>
|
|
||||||
<td><input type="date" name="birthDate" value="${profile.birthDate}"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("about")}</h3></td>
|
|
||||||
<td><textarea name="about" cols="100" maxlength="1000" rows="5" wrap="soft">${profile.about}</textarea></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("gender")}</h3></td>
|
|
||||||
<td>
|
|
||||||
<select name="gender">
|
|
||||||
<option value="${profile.gender}" selected hidden>
|
|
||||||
${wordBundle.getWord(profile.gender)}
|
|
||||||
</option>
|
|
||||||
<c:forEach var="gender" items="${applicationScope.genders}">
|
|
||||||
<option value="${gender}">${wordBundle.getWord(gender)}</option>
|
|
||||||
</c:forEach>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${wordBundle.getWord("photo")}</h3></td>
|
|
||||||
<td>
|
|
||||||
<c:if test="${profile.photo != null}">
|
|
||||||
<img src="content/profiles/${requestScope.profile.id}/${requestScope.profile.photo}" alt="" height="300">
|
|
||||||
</c:if>
|
|
||||||
<br>
|
|
||||||
<input type="button" value="${wordBundle.getWord('update')}" onclick="document.getElementById('file').click();" />
|
|
||||||
<input type="file" name="photo" id="file" style="display:none;">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<table>
|
|
||||||
<tr class="hiddenRow">
|
|
||||||
<td>
|
|
||||||
<input type="image" src="content/app/img/floppy-disk.png" width="75" alt="submit" class="icon" />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="/email?id=${profile.id}"><img src="content/app/img/key.png" alt="" width="75"></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
<div style="color: red">
|
|
||||||
<c:forEach var="error" items="${errors}">
|
|
||||||
<span>${wordBundle.getWord(error)}</span>
|
|
||||||
<br>
|
|
||||||
</c:forEach>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Profiles</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><h3>id</h3></td>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("email")}</h3></td>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("name")}</h3></td>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("surname")}</h3></td>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("age")}</h3></td>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("status")}</h3></td>
|
|
||||||
</tr>
|
|
||||||
<c:forEach var="profile" items="${requestScope.profiles}">
|
|
||||||
<tr>
|
|
||||||
<td><h4>${profile.id}</h4></td>
|
|
||||||
<td><h4>${profile.email}</h4></td>
|
|
||||||
<td><h4>${profile.name}</h4></td>
|
|
||||||
<td><h4>${profile.surname}</h4></td>
|
|
||||||
<td><h4>${profile.age}</h4></td>
|
|
||||||
<td>
|
|
||||||
<form action="/profile" method="post">
|
|
||||||
<input type="hidden" name="_method" value="put"/>
|
|
||||||
<input type="hidden" name="id" value="${profile.id}">
|
|
||||||
<select name="status">
|
|
||||||
<option value="${profile.status}" selected hidden>
|
|
||||||
${requestScope.wordBundle.getWord(profile.status)}
|
|
||||||
</option>
|
|
||||||
<c:forEach var="status" items="${applicationScope.statuses}">
|
|
||||||
<option value="${status}">${requestScope.wordBundle.getWord(status)}</option>
|
|
||||||
</c:forEach>
|
|
||||||
</select>
|
|
||||||
<button type="submit">${requestScope.wordBundle.getWord("save")}</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</c:forEach>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Charm Registration</title>
|
|
||||||
<%@ include file="style.html" %>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<%@ include file="header.jsp" %>
|
|
||||||
<div>
|
|
||||||
<form method="post" action="/registration">
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("email")}</h3></td>
|
|
||||||
<td><input type="email" name="email" placeholder="user@charm.ru"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><h3>${requestScope.wordBundle.getWord("password")}</h3></td>
|
|
||||||
<td><input type="password" name="password"></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<button type="submit">${requestScope.wordBundle.getWord("save")}</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div style="color: red">
|
|
||||||
<c:forEach var="error" items="${errors}">
|
|
||||||
<span>${wordBundle.getWord(error)}</span>
|
|
||||||
<br>
|
|
||||||
</c:forEach>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<%@ include file="footer.jsp" %>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<style>
|
|
||||||
.icon {
|
|
||||||
width: 75px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.langButton {
|
|
||||||
padding: 0px;
|
|
||||||
border: none;
|
|
||||||
background: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.langImg {
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 500px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
width: 500px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 500px;
|
|
||||||
max-height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo {
|
|
||||||
max-width: 300px;
|
|
||||||
max-height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: none;
|
|
||||||
width: 500px;
|
|
||||||
font-size: 15px;
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
div {
|
|
||||||
text-align: center;
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
text-align: left;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr {
|
|
||||||
text-align: center;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid;
|
|
||||||
border-top: none;
|
|
||||||
border-left: none;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hiddenRow {
|
|
||||||
text-align: center;
|
|
||||||
padding: 0px;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</html>
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
|
|
||||||
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
|
||||||
version="6.0">
|
|
||||||
|
|
||||||
<error-page>
|
|
||||||
<error-code>404</error-code>
|
|
||||||
<location>/WEB-INF/jsp/error404.jsp</location>
|
|
||||||
</error-page>
|
|
||||||
<error-page>
|
|
||||||
<error-code>400</error-code>
|
|
||||||
<location>/WEB-INF/jsp/error400.jsp</location>
|
|
||||||
</error-page>
|
|
||||||
<error-page>
|
|
||||||
<exception-type>java.lang.Exception</exception-type>
|
|
||||||
<location>/WEB-INF/jsp/error.jsp</location>
|
|
||||||
</error-page>
|
|
||||||
</web-app>
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
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
|
|
||||||
|
|
||||||
http://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.
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Charm</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h3>Hello from Charm!</H3>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
org.slf4j.simpleLogger.defaultLogLevel=info
|
|
||||||
org.slf4j.simpleLogger.showDateTime=true
|
|
||||||
org.slf4j.simpleLogger.dateTimeFormat=dd-MM-yyyy HH:mm:ss:SSS
|
|
||||||
org.slf4j.simpleLogger.logFile=System.out
|
|
||||||
org.slf4j.simpleLogger.levelInBrackets=true
|
|
||||||
org.slf4j.simpleLogger.showLogName=true
|
|
||||||
org.slf4j.simpleLogger.showShortLogName=false
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
about=About
|
|
||||||
active=Active
|
|
||||||
age=Age
|
|
||||||
all-rights-reserved=All rights reserved
|
|
||||||
birth-date=Birth date
|
|
||||||
confirm-password=Confirm password
|
|
||||||
delete=Delete
|
|
||||||
email=Email
|
|
||||||
email-warning=Changing your mail may have negative effects
|
|
||||||
error.age.invalid=Age must be between 18 and 100 years old
|
|
||||||
error.email.exist=This email already exists
|
|
||||||
error.email.invalid=Invalid email
|
|
||||||
error.password.invalid=Invalid password
|
|
||||||
female=Female
|
|
||||||
gender=Gender
|
|
||||||
inactive=Inactive
|
|
||||||
male=Male
|
|
||||||
name=Name
|
|
||||||
other=Other
|
|
||||||
page-bad-request=Bad request
|
|
||||||
page-not-found=Page not found
|
|
||||||
password=Password
|
|
||||||
photo=Photo
|
|
||||||
save=Save
|
|
||||||
status=Status
|
|
||||||
surname=Surname
|
|
||||||
unexpected-error=Unexpected error
|
|
||||||
update=Update
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
about=About
|
|
||||||
active=Active
|
|
||||||
age=Age
|
|
||||||
all-rights-reserved=All rights reserved
|
|
||||||
birth-date=Birth date
|
|
||||||
confirm-password=Confirm password
|
|
||||||
delete=Delete
|
|
||||||
email=Email
|
|
||||||
email-warning=Changing your mail may have negative effects
|
|
||||||
error.age.invalid=Age must be between 18 and 100 years old
|
|
||||||
error.email.exist=This email already exists
|
|
||||||
error.email.invalid=Invalid email
|
|
||||||
error.password.invalid=Invalid password
|
|
||||||
female=Female
|
|
||||||
gender=Gender
|
|
||||||
inactive=Inactive
|
|
||||||
male=Male
|
|
||||||
name=Name
|
|
||||||
other=Other
|
|
||||||
page-bad-request=Bad request
|
|
||||||
page-not-found=Page not found
|
|
||||||
password=Password
|
|
||||||
photo=Photo
|
|
||||||
save=Save
|
|
||||||
status=Status
|
|
||||||
surname=Surname
|
|
||||||
unexpected-error=Unexpected error
|
|
||||||
update=Update
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
about=\u041E \u0441\u0435\u0431\u0435
|
|
||||||
active=\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0439
|
|
||||||
age=\u0412\u043E\u0437\u0440\u0430\u0441\u0442
|
|
||||||
all-rights-reserved=\u0412\u0441\u0435 \u043F\u0440\u0430\u0432\u0430 \u0437\u0430\u0449\u0438\u0449\u0435\u043D\u044B
|
|
||||||
birth-date=\u0414\u0430\u0442\u0430 \u0440\u043E\u0436\u0434\u0435\u043D\u0438\u044F
|
|
||||||
confirm-password=\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043F\u0430\u0440\u043E\u043B\u044C
|
|
||||||
delete=\u0423\u0434\u0430\u043B\u0438\u0442\u044C
|
|
||||||
email=\u041F\u043E\u0447\u0442\u0430
|
|
||||||
email-warning=\u0421\u043C\u0435\u043D\u0430 \u043F\u043E\u0447\u0442\u044B \u043C\u043E\u0436\u0435\u0442 \u043F\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043A \u043D\u0435\u0436\u0435\u043B\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u043C \u043F\u043E\u0441\u043B\u0435\u0434\u0441\u0442\u0432\u0438\u044F\u043C
|
|
||||||
error.age.invalid=\u0412\u043E\u0437\u0440\u0430\u0441\u0442 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0442 18 \u0434\u043E 100 \u043B\u0435\u0442
|
|
||||||
error.email.exist=\u0422\u0430\u043A\u0430\u044F \u043F\u043E\u0447\u0442\u0430 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
|
|
||||||
error.email.invalid=\u041D\u0435\u0432\u0435\u0440\u043D\u0430\u044F \u043F\u043E\u0447\u0442\u0430
|
|
||||||
error.password.invalid=\u041D\u0435\u043F\u043E\u0434\u0445\u043E\u0434\u044F\u0449\u0438\u0439 \u043F\u0430\u0440\u043E\u043B\u044C
|
|
||||||
female=\u0416\u0435\u043D\u0449\u0438\u043D\u0430
|
|
||||||
gender=\u041F\u043E\u043B
|
|
||||||
inactive=\u041D\u0435\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439
|
|
||||||
male=\u041C\u0443\u0436\u0447\u0438\u043D\u0430
|
|
||||||
name=\u0418\u043C\u044F
|
|
||||||
other=\u0414\u0440\u0443\u0433\u043E\u0435
|
|
||||||
page-bad-request=\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 \u0437\u0430\u043F\u0440\u043E\u0441
|
|
||||||
page-not-found=\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u0430
|
|
||||||
password=\u041F\u0430\u0440\u043E\u043B\u044C
|
|
||||||
photo=\u0424\u043E\u0442\u043E
|
|
||||||
save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
|
|
||||||
status=\u0421\u0442\u0430\u0442\u0443\u0441
|
|
||||||
surname=\u0424\u0430\u043C\u0438\u043B\u0438\u044F
|
|
||||||
unexpected-error=\u041D\u0435\u043F\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043D\u043D\u0430\u044F \u043E\u0448\u0438\u0431\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
|
|
||||||
update=\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C
|
|
||||||
27
src/ru/charm/back/CharmBackClientRunner.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package ru.charm.back;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class CharmBackClientRunner {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
try (
|
||||||
|
Socket socket = new Socket("localhost", 8080);
|
||||||
|
DataInputStream rsStream = new DataInputStream(socket.getInputStream());
|
||||||
|
DataOutputStream rqStream = new DataOutputStream(socket.getOutputStream());
|
||||||
|
Scanner scanner = new Scanner(System.in)
|
||||||
|
) {
|
||||||
|
while (scanner.hasNextLine()) {
|
||||||
|
System.out.println("Client: ");
|
||||||
|
String request = scanner.nextLine();
|
||||||
|
rqStream.writeUTF(request);
|
||||||
|
|
||||||
|
String response = rsStream.readUTF();
|
||||||
|
System.out.println("Server: " + response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
src/ru/charm/back/CharmBackServerRunner.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ru.charm.back;
|
||||||
|
|
||||||
|
import ru.charm.back.controller.ProfileController;
|
||||||
|
import ru.charm.back.dao.ProfileDao;
|
||||||
|
import ru.charm.back.model.Command;
|
||||||
|
import ru.charm.back.service.ProfileService;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class CharmBackServerRunner {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
ProfileController controller = new ProfileController(new ProfileService(new ProfileDao()));
|
||||||
|
|
||||||
|
try (
|
||||||
|
ServerSocket serverSocket = new ServerSocket(8080);
|
||||||
|
Socket socket = serverSocket.accept();
|
||||||
|
DataInputStream rqStream = new DataInputStream(socket.getInputStream());
|
||||||
|
DataOutputStream rsStream = new DataOutputStream(socket.getOutputStream());
|
||||||
|
) {
|
||||||
|
String request = rqStream.readUTF();
|
||||||
|
String response;
|
||||||
|
|
||||||
|
while (!request.equals("stop")) {
|
||||||
|
if (request.startsWith(Command.SAVE.getPrefix())) {
|
||||||
|
response = controller.save(request.split("save ")[1]);
|
||||||
|
} else if (request.startsWith(Command.FIND_BY_ID.getPrefix())) {
|
||||||
|
response = controller.findById(request.split("findById ")[1]);
|
||||||
|
} else if (request.startsWith(Command.FIND_ALL.getPrefix())) {
|
||||||
|
response = controller.findAll();
|
||||||
|
} else if (request.startsWith(Command.UPDATE.getPrefix())) {
|
||||||
|
response = controller.update(request.split("update ")[1]);
|
||||||
|
} else if (request.startsWith(Command.DELETE.getPrefix())) {
|
||||||
|
response = controller.delete(request.split("delete ")[1]);
|
||||||
|
} else {
|
||||||
|
response = "Unsupported method";
|
||||||
|
}
|
||||||
|
|
||||||
|
rsStream.writeUTF(response);
|
||||||
|
request = rqStream.readUTF();
|
||||||
|
|
||||||
|
System.out.println("Server: " + request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.service.ContentService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
|
||||||
|
|
||||||
@WebServlet("/content/*")
|
|
||||||
@Slf4j
|
|
||||||
public class ContentController extends HttpServlet {
|
|
||||||
|
|
||||||
private final ContentService service = ContentService.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
try {
|
|
||||||
String contentPath = req.getRequestURI().replace("/content", "");
|
|
||||||
log.info("Content download request: {} {}", req.getRequestURI(), contentPath);
|
|
||||||
resp.setContentType("application/octet-stream");
|
|
||||||
service.download(contentPath, resp.getOutputStream());
|
|
||||||
log.info("Content successfully downloaded: {}", req);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Content download failed: {}", e.getMessage());
|
|
||||||
resp.sendError(SC_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.MultipartConfig;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.dto.ProfileUpdateDto;
|
|
||||||
import ru.charm.back.mapper.RequestToProfileUpdateDtoMapper;
|
|
||||||
import ru.charm.back.model.exception.DuplicateEmailException;
|
|
||||||
import ru.charm.back.service.ProfileService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
|
||||||
|
|
||||||
@WebServlet("/credentials")
|
|
||||||
@Slf4j
|
|
||||||
@MultipartConfig
|
|
||||||
public class CredentialsController extends HttpServlet {
|
|
||||||
private final ProfileService service = ProfileService.getInstance();
|
|
||||||
private final RequestToProfileUpdateDtoMapper requestToProfileUpdateDtoMapper = RequestToProfileUpdateDtoMapper.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
|
|
||||||
String sId = req.getParameter("id");
|
|
||||||
String forwardUri = "/notFound";
|
|
||||||
if (sId != null) {
|
|
||||||
Optional<ProfileGetDto> optProfileGetDto = service.findById(Long.parseLong(sId));
|
|
||||||
if (optProfileGetDto.isPresent()) {
|
|
||||||
req.setAttribute("profile", optProfileGetDto.get());
|
|
||||||
forwardUri = "/WEB-INF/jsp/email.jsp";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.getRequestDispatcher(forwardUri).forward(req, resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPut (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
ProfileUpdateDto dto = requestToProfileUpdateDtoMapper.map(req, new ProfileUpdateDto());
|
|
||||||
try {
|
|
||||||
service.update(dto);
|
|
||||||
log.info("Email {} was changed in profile with id = {}", dto.getEmail(), dto.getId());
|
|
||||||
resp.sendRedirect(String.format("/profile?id=%s", dto.getId()));
|
|
||||||
} catch (DuplicateEmailException e) {
|
|
||||||
resp.sendError(SC_BAD_REQUEST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@WebServlet("/forward")
|
|
||||||
public class ForwardController extends HttpServlet {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
|
||||||
resp.sendRedirect("https://ya.ru");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.Cookie;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@WebServlet("/lang")
|
|
||||||
public class LanguageController extends HttpServlet {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
String lang = req.getParameter("lang");
|
|
||||||
|
|
||||||
System.out.println("Cookie header" + req.getHeader("Cookie"));
|
|
||||||
|
|
||||||
Cookie cookie = new Cookie("lang", "en");
|
|
||||||
if ("ru".equals(lang)) {
|
|
||||||
cookie.setValue("ru");
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.addCookie(cookie);
|
|
||||||
|
|
||||||
String referer = req.getHeader("Referer");
|
|
||||||
resp.sendRedirect(referer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.dto.LoginDto;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
import ru.charm.back.mapper.RequestToLoginDtoMapper;
|
|
||||||
import ru.charm.back.mapper.RequestToRegistrationDtoMapper;
|
|
||||||
import ru.charm.back.service.ProfileService;
|
|
||||||
import ru.charm.back.validator.RegistrationValidator;
|
|
||||||
import ru.charm.back.validator.ValidationResult;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@WebServlet("/login")
|
|
||||||
@Slf4j
|
|
||||||
public class LoginController extends HttpServlet {
|
|
||||||
private final ProfileService service = ProfileService.getInstance();
|
|
||||||
|
|
||||||
private final RequestToLoginDtoMapper requestTologinDtoMapper = RequestToLoginDtoMapper.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
req.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(req, resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
|
|
||||||
LoginDto dto = requestTologinDtoMapper.map(req);
|
|
||||||
Optional<ProfileGetDto> userDetailOpt = service.login(dto);
|
|
||||||
|
|
||||||
if (userDetailOpt.isPresent()) {
|
|
||||||
req.getSession().setAttribute("userDetails", userDetailOpt.get());
|
|
||||||
|
|
||||||
resp.sendRedirect(String.format("/profile?id=%s", userDetailOpt.get().getId()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resp.sendRedirect("/login");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.dto.LoginDto;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.mapper.RequestToLoginDtoMapper;
|
|
||||||
import ru.charm.back.service.ProfileService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@WebServlet("/logout")
|
|
||||||
public class LogoutController extends HttpServlet {
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
|
||||||
req.getSession().invalidate();
|
|
||||||
resp.sendRedirect("/login");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,55 +1,112 @@
|
|||||||
package ru.charm.back.controller;
|
package ru.charm.back.controller;
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
import ru.charm.back.model.Profile;
|
||||||
import jakarta.servlet.annotation.MultipartConfig;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.dto.ProfileUpdateDto;
|
|
||||||
import ru.charm.back.mapper.RequestToProfileUpdateDtoMapper;
|
|
||||||
import ru.charm.back.service.ProfileService;
|
import ru.charm.back.service.ProfileService;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
public class ProfileController {
|
||||||
|
private final ProfileService service;
|
||||||
|
|
||||||
@WebServlet("/profile")
|
public ProfileController(ProfileService service) {
|
||||||
@MultipartConfig
|
this.service = service;
|
||||||
public class ProfileController extends HttpServlet {
|
|
||||||
private final ProfileService service = ProfileService.getInstance();
|
|
||||||
|
|
||||||
private final RequestToProfileUpdateDtoMapper requestToProfileUpdateDtoMapper = RequestToProfileUpdateDtoMapper.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
String sId = req.getParameter("id");
|
|
||||||
String forwardUri = null;
|
|
||||||
if (sId != null) {
|
|
||||||
Optional<ProfileGetDto> optProfileDto = service.findById(Long.parseLong(sId));
|
|
||||||
System.out.println("Optional profile" + optProfileDto.toString());
|
|
||||||
if (optProfileDto.isPresent()) {
|
|
||||||
req.setAttribute("profile", optProfileDto.get());
|
|
||||||
forwardUri = "/WEB-INF/jsp/profile.jsp";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req.setAttribute("profiles", service.findAll());
|
|
||||||
forwardUri = "/WEB-INF/jsp/profiles.jsp";
|
|
||||||
}
|
|
||||||
if (forwardUri == null) {
|
|
||||||
resp.sendError(SC_NOT_FOUND);
|
|
||||||
} else {
|
|
||||||
req.getRequestDispatcher(forwardUri).forward(req, resp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String work(String request) {
|
||||||
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
return "";
|
||||||
ProfileUpdateDto dto = requestToProfileUpdateDtoMapper.map(req);
|
|
||||||
service.update(dto);
|
|
||||||
String referer = req.getHeader("referer");
|
|
||||||
resp.sendRedirect(referer);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public String save(String save) {
|
||||||
|
String[] params = save.split(",");
|
||||||
|
|
||||||
|
if (params.length != 4) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile profile = new Profile();
|
||||||
|
profile.setEmail(params[0]);
|
||||||
|
profile.setName(params[1]);
|
||||||
|
profile.setSurname(params[2]);
|
||||||
|
profile.setAbout(params[3]);
|
||||||
|
|
||||||
|
return service.save(profile).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findById(String request) {
|
||||||
|
String[] params = request.split(",");
|
||||||
|
|
||||||
|
if (params.length != 1) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
long id;
|
||||||
|
try {
|
||||||
|
id = Long.parseLong(params[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Profile> maybeProfile = service.findById(id);
|
||||||
|
|
||||||
|
if (maybeProfile.isEmpty()) {
|
||||||
|
return "Not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
return maybeProfile.get().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findAll() {
|
||||||
|
return service.findAll().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String update(String request) {
|
||||||
|
String[] params = request.split(",");
|
||||||
|
|
||||||
|
if (params.length != 5) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
long id;
|
||||||
|
try {
|
||||||
|
id = Long.parseLong(params[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
Profile profile = new Profile();
|
||||||
|
profile.setId(id);
|
||||||
|
profile.setEmail(params[1]);
|
||||||
|
profile.setName(params[2]);
|
||||||
|
profile.setSurname(params[3]);
|
||||||
|
profile.setAbout(params[4]);
|
||||||
|
|
||||||
|
service.update(profile);
|
||||||
|
|
||||||
|
return "Update success\n" + profile.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String delete(String request) {
|
||||||
|
String[] params = request.split(",");
|
||||||
|
|
||||||
|
if (params.length != 1) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
long id;
|
||||||
|
try {
|
||||||
|
id = Long.parseLong(params[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Bad request";
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Profile> maybeProfile = service.findById(id);
|
||||||
|
|
||||||
|
if (maybeProfile.isEmpty()) {
|
||||||
|
return "Not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
service.delete(id);
|
||||||
|
|
||||||
|
return "Delete success";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
package ru.charm.back.controller;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.annotation.WebServlet;
|
|
||||||
import jakarta.servlet.http.HttpServlet;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
import ru.charm.back.mapper.RequestToRegistrationDtoMapper;
|
|
||||||
import ru.charm.back.service.ProfileService;
|
|
||||||
import ru.charm.back.validator.RegistrationValidator;
|
|
||||||
import ru.charm.back.validator.ValidationResult;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@WebServlet("/registration")
|
|
||||||
@Slf4j
|
|
||||||
public class RegistrationController extends HttpServlet {
|
|
||||||
private final ProfileService service = ProfileService.getInstance();
|
|
||||||
|
|
||||||
private final RequestToRegistrationDtoMapper requestToRegistrationDtoMapper = RequestToRegistrationDtoMapper.getInstance();
|
|
||||||
private final RegistrationValidator validator = RegistrationValidator.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
|
||||||
req.getRequestDispatcher("/WEB-INF/jsp/registration.jsp").forward(req, resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
|
|
||||||
RegistrationDto dto = requestToRegistrationDtoMapper.map(req);
|
|
||||||
|
|
||||||
ValidationResult validationResult = validator.validate(dto);
|
|
||||||
if (!validationResult.isValid()) {
|
|
||||||
req.setAttribute("errors", validationResult.getErrors());
|
|
||||||
doGet(req, resp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Long id = service.save(dto);
|
|
||||||
log.info("Profile with the email address {} has been registered with id {}", dto.getEmail(), id);
|
|
||||||
resp.sendRedirect(String.format("/profile?id=%s", id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
|
|
||||||
String sId = req.getParameter("id");
|
|
||||||
boolean success = false;
|
|
||||||
if (!sId.isBlank()) {
|
|
||||||
success = service.delete(Long.parseLong(sId));
|
|
||||||
}
|
|
||||||
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
|
|
||||||
if (success) {
|
|
||||||
log.info("Profile with id {} has been deleted", sId);
|
|
||||||
}
|
|
||||||
resp.sendRedirect("/registration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package ru.charm.back.controller.filter;
|
|
||||||
|
|
||||||
import jakarta.servlet.*;
|
|
||||||
import jakarta.servlet.annotation.WebFilter;
|
|
||||||
import jakarta.servlet.http.Cookie;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.model.Role;
|
|
||||||
import ru.charm.back.service.WordBundle;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@WebFilter("/*")
|
|
||||||
@Slf4j
|
|
||||||
public class AuthFilter implements Filter {
|
|
||||||
private final Set<String> PRIVATE_PATHS = Set.of("/profile", "/credentials");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
|
||||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
|
||||||
|
|
||||||
if (PRIVATE_PATHS.contains(req.getRequestURI())) {
|
|
||||||
ProfileGetDto userDetails = (ProfileGetDto) req.getSession().getAttribute("userDetails");
|
|
||||||
log.info("User {} is trying to access {}", userDetails, req.getRequestURI());
|
|
||||||
if (userDetails == null) {
|
|
||||||
res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
|
||||||
} else if (userDetails.getRole() == Role.ADMIN || userDetails.getId().toString().equals( req.getParameter("id"))) {
|
|
||||||
filterChain.doFilter(req, res);
|
|
||||||
} else {
|
|
||||||
res.sendError(HttpServletResponse.SC_FORBIDDEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
filterChain.doFilter(req, res);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package ru.charm.back.controller.filter;
|
|
||||||
|
|
||||||
import jakarta.servlet.*;
|
|
||||||
import jakarta.servlet.annotation.WebFilter;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static jakarta.servlet.RequestDispatcher.ERROR_EXCEPTION;
|
|
||||||
|
|
||||||
@WebFilter(value = "/*", dispatcherTypes = DispatcherType.ERROR)
|
|
||||||
@Slf4j
|
|
||||||
public class ErrorFilter implements Filter {
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
|
||||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
|
||||||
|
|
||||||
Throwable throwable = (Throwable) req.getAttribute(ERROR_EXCEPTION);
|
|
||||||
|
|
||||||
if (res.getStatus() >= 500) {
|
|
||||||
log.error("Error 500", throwable);
|
|
||||||
} else {
|
|
||||||
log.warn("Exception code {}", res.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
filterChain.doFilter(servletRequest, servletResponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
package ru.charm.back.controller.filter;
|
|
||||||
|
|
||||||
import jakarta.servlet.*;
|
|
||||||
import jakarta.servlet.annotation.WebFilter;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import ru.charm.back.model.Gender;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
@WebFilter("/*")
|
|
||||||
public class HiddenHttpMethodFilter implements Filter {
|
|
||||||
public static final String METHOD_PARAM = "_method";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(FilterConfig filterConfig) {
|
|
||||||
ServletContext servletContext = filterConfig.getServletContext();
|
|
||||||
if (servletContext.getAttribute("genders") == null) {
|
|
||||||
servletContext.setAttribute("genders", Gender.values());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
|
||||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
|
||||||
String paramValue = request.getParameter(METHOD_PARAM);
|
|
||||||
|
|
||||||
if ("POST".equals(request.getMethod()) && paramValue != null && !paramValue.isBlank()) {
|
|
||||||
String method = paramValue.toUpperCase(Locale.ENGLISH);
|
|
||||||
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
|
|
||||||
filterChain.doFilter(wrapper, response);
|
|
||||||
} else {
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
public final String method;
|
|
||||||
|
|
||||||
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
|
|
||||||
super(request);
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package ru.charm.back.controller.filter;
|
|
||||||
|
|
||||||
import jakarta.servlet.*;
|
|
||||||
import jakarta.servlet.annotation.WebFilter;
|
|
||||||
import jakarta.servlet.http.Cookie;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import ru.charm.back.service.WordBundle;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@WebFilter("/*")
|
|
||||||
public class LanguageFilter implements Filter {
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
|
||||||
HttpServletRequest req = (HttpServletRequest) servletRequest;
|
|
||||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
|
||||||
|
|
||||||
Cookie[] cookies = req.getCookies() != null ? req.getCookies() : new Cookie[]{};
|
|
||||||
|
|
||||||
String lang = Arrays.stream(cookies)
|
|
||||||
.filter(cookie -> "lang".equals(cookie.getName()))
|
|
||||||
.map(Cookie::getValue)
|
|
||||||
.findFirst()
|
|
||||||
.orElse("en");
|
|
||||||
|
|
||||||
WordBundle wordBundle = new WordBundle(lang);
|
|
||||||
|
|
||||||
req.setAttribute("wordBundle", wordBundle);
|
|
||||||
|
|
||||||
filterChain.doFilter(req, res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,92 +1,47 @@
|
|||||||
package ru.charm.back.dao;
|
package ru.charm.back.dao;
|
||||||
|
|
||||||
import ru.charm.back.model.Gender;
|
|
||||||
import ru.charm.back.model.Profile;
|
import ru.charm.back.model.Profile;
|
||||||
import ru.charm.back.model.Role;
|
|
||||||
import ru.charm.back.model.Status;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ProfileDao {
|
public class ProfileDao {
|
||||||
|
|
||||||
private static final ProfileDao INSTANCE = new ProfileDao();
|
|
||||||
|
|
||||||
private final AtomicLong idStorage;
|
|
||||||
private final ConcurrentHashMap<Long, Profile> storage;
|
private final ConcurrentHashMap<Long, Profile> storage;
|
||||||
|
private final AtomicLong idStorage;
|
||||||
|
|
||||||
private ProfileDao() {
|
public ProfileDao() {
|
||||||
this.storage = new ConcurrentHashMap<>();
|
this.storage = new ConcurrentHashMap<>();
|
||||||
Profile profile = new Profile();
|
this.idStorage = new AtomicLong();
|
||||||
profile.setId(1L);
|
|
||||||
profile.setEmail("ivanov@mail.ru");
|
|
||||||
profile.setPassword("123");
|
|
||||||
profile.setName("Ivan");
|
|
||||||
profile.setSurname("Ivanov");
|
|
||||||
profile.setBirthDate(LocalDate.parse("2001-12-03"));
|
|
||||||
profile.setAbout("I am QA");
|
|
||||||
profile.setGender(Gender.MALE);
|
|
||||||
profile.setStatus(Status.ACTIVE);
|
|
||||||
profile.setRole(Role.ADMIN);
|
|
||||||
this.storage.put(1L, profile);
|
|
||||||
Profile profile1 = new Profile();
|
|
||||||
profile1.setId(2L);
|
|
||||||
profile1.setEmail("sidorova@mail.ru");
|
|
||||||
profile1.setPassword("456");
|
|
||||||
profile1.setName("Elena");
|
|
||||||
profile1.setSurname("Sidorova");
|
|
||||||
profile1.setBirthDate(LocalDate.parse("1999-09-01"));
|
|
||||||
profile1.setAbout("I am Java Dev");
|
|
||||||
profile1.setGender(Gender.FEMALE);
|
|
||||||
profile1.setStatus(Status.INACTIVE);
|
|
||||||
profile1.setRole(Role.USER);
|
|
||||||
this.storage.put(2L, profile1);
|
|
||||||
this.idStorage = new AtomicLong(3L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileDao getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Profile save(Profile profile) {
|
public Profile save(Profile profile) {
|
||||||
profile.setId(idStorage.getAndIncrement());
|
long id = idStorage.incrementAndGet();
|
||||||
storage.put(profile.getId(), profile);
|
profile.setId(id);
|
||||||
|
storage.put(id, profile);
|
||||||
|
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Profile> findById(Long id) {
|
public Optional<Profile> findById(Long id) {
|
||||||
if (id == null) return Optional.empty();
|
|
||||||
return Optional.ofNullable(storage.get(id));
|
return Optional.ofNullable(storage.get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(Profile profile) {
|
||||||
|
Long id = profile.getId();
|
||||||
|
if (id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
storage.put(id, profile);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Profile> findAll() {
|
public List<Profile> findAll() {
|
||||||
return new ArrayList<>(storage.values());
|
return new ArrayList<>(storage.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(Profile profile) {
|
public Boolean delete(Long id) {
|
||||||
Long id = profile.getId();
|
|
||||||
if (id == null) return;
|
|
||||||
storage.put(id, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean delete(Long id) {
|
|
||||||
if (id == null) return false;
|
|
||||||
return storage.remove(id) != null;
|
return storage.remove(id) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getAllEmails() {
|
|
||||||
return storage.values().stream().map(Profile::getEmail).collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<Profile> findByEmail(String email) {
|
|
||||||
if (email == null) return Optional.empty();
|
|
||||||
|
|
||||||
return storage.values().stream().filter(profile -> profile.getEmail().equals(email)).findFirst();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
package ru.charm.back.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class LoginDto {
|
|
||||||
private String email;
|
|
||||||
private String password;
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package ru.charm.back.dto;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.experimental.FieldDefaults;
|
|
||||||
import ru.charm.back.model.Gender;
|
|
||||||
import ru.charm.back.model.Role;
|
|
||||||
import ru.charm.back.model.Status;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
|
||||||
public class ProfileGetDto {
|
|
||||||
Long id;
|
|
||||||
String email;
|
|
||||||
String name;
|
|
||||||
String surname;
|
|
||||||
LocalDate birthDate;
|
|
||||||
Integer age;
|
|
||||||
String about;
|
|
||||||
Gender gender;
|
|
||||||
Status status;
|
|
||||||
String photo;
|
|
||||||
Role role;
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
package ru.charm.back.dto;
|
|
||||||
|
|
||||||
|
|
||||||
import jakarta.servlet.http.Part;
|
|
||||||
import lombok.Data;
|
|
||||||
import ru.charm.back.model.Gender;
|
|
||||||
import ru.charm.back.model.Status;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class ProfileUpdateDto {
|
|
||||||
private Long id;
|
|
||||||
private String email;
|
|
||||||
private String password;
|
|
||||||
private String name;
|
|
||||||
private String surname;
|
|
||||||
private LocalDate birthDate;
|
|
||||||
private String about;
|
|
||||||
private Gender gender;
|
|
||||||
private Status status;
|
|
||||||
private Part photo;
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package ru.charm.back.dto;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class RegistrationDto {
|
|
||||||
private String email;
|
|
||||||
private String password;
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
public interface Mapper<From, To> {
|
|
||||||
|
|
||||||
To map(From from);
|
|
||||||
To map(From from, To to);
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.model.Profile;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
|
|
||||||
public class ProfileToProfileGetDtoMapper implements Mapper<Profile, ProfileGetDto> {
|
|
||||||
|
|
||||||
private static final ProfileToProfileGetDtoMapper INSTANCE = new ProfileToProfileGetDtoMapper();
|
|
||||||
|
|
||||||
private ProfileToProfileGetDtoMapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileToProfileGetDtoMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProfileGetDto map(Profile profile) {
|
|
||||||
return map(profile, new ProfileGetDto());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProfileGetDto map(Profile profile, ProfileGetDto dto) {
|
|
||||||
dto.setId(profile.getId());
|
|
||||||
dto.setEmail(profile.getEmail());
|
|
||||||
dto.setName(profile.getName());
|
|
||||||
dto.setSurname(profile.getSurname());
|
|
||||||
dto.setBirthDate(profile.getBirthDate());
|
|
||||||
if (profile.getBirthDate() != null) {
|
|
||||||
dto.setAge(Math.toIntExact(ChronoUnit.YEARS.between(profile.getBirthDate(), LocalDate.now())));
|
|
||||||
}
|
|
||||||
dto.setAbout(profile.getAbout());
|
|
||||||
dto.setGender(profile.getGender());
|
|
||||||
dto.setStatus(profile.getStatus());
|
|
||||||
dto.setPhoto(profile.getPhoto());
|
|
||||||
dto.setRole(profile.getRole());
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
|
|
||||||
import ru.charm.back.dto.ProfileUpdateDto;
|
|
||||||
import ru.charm.back.model.Profile;
|
|
||||||
|
|
||||||
public class ProfileUpdateDtoToProfileMapper implements Mapper<ProfileUpdateDto, Profile> {
|
|
||||||
|
|
||||||
private static final ProfileUpdateDtoToProfileMapper INSTANCE = new ProfileUpdateDtoToProfileMapper();
|
|
||||||
|
|
||||||
private ProfileUpdateDtoToProfileMapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProfileUpdateDtoToProfileMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Profile map(ProfileUpdateDto dto) {
|
|
||||||
return map(dto, new Profile());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Profile map(ProfileUpdateDto dto, Profile profile) {
|
|
||||||
profile.setId(dto.getId());
|
|
||||||
if (dto.getEmail() != null) {
|
|
||||||
profile.setEmail(dto.getEmail());
|
|
||||||
}
|
|
||||||
if (dto.getName() != null) {
|
|
||||||
profile.setName(dto.getName());
|
|
||||||
}
|
|
||||||
if (dto.getSurname() != null) {
|
|
||||||
profile.setSurname(dto.getSurname());
|
|
||||||
}
|
|
||||||
if (dto.getBirthDate() != null) {
|
|
||||||
profile.setBirthDate(dto.getBirthDate());
|
|
||||||
}
|
|
||||||
if (dto.getAbout() != null) {
|
|
||||||
profile.setAbout(dto.getAbout());
|
|
||||||
}
|
|
||||||
if (dto.getGender() != null) {
|
|
||||||
profile.setGender(dto.getGender());
|
|
||||||
}
|
|
||||||
if (dto.getStatus() != null) {
|
|
||||||
profile.setStatus(dto.getStatus());
|
|
||||||
}
|
|
||||||
if (dto.getPhoto() != null) {
|
|
||||||
profile.setPhoto(dto.getPhoto().getSubmittedFileName());
|
|
||||||
}
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
import ru.charm.back.model.Profile;
|
|
||||||
import ru.charm.back.model.Role;
|
|
||||||
import ru.charm.back.model.Status;
|
|
||||||
|
|
||||||
public class RegistrationDtoToProfileMapper implements Mapper<RegistrationDto, Profile> {
|
|
||||||
|
|
||||||
private static final RegistrationDtoToProfileMapper INSTANCE = new RegistrationDtoToProfileMapper();
|
|
||||||
|
|
||||||
private RegistrationDtoToProfileMapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RegistrationDtoToProfileMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Profile map(RegistrationDto dto) {
|
|
||||||
return map(dto, new Profile());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Profile map(RegistrationDto dto, Profile profile) {
|
|
||||||
profile.setEmail(dto.getEmail());
|
|
||||||
profile.setPassword(dto.getPassword());
|
|
||||||
profile.setStatus(Status.INACTIVE);
|
|
||||||
profile.setRole(Role.USER);
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import ru.charm.back.dto.LoginDto;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
|
|
||||||
public class RequestToLoginDtoMapper implements Mapper<HttpServletRequest, LoginDto> {
|
|
||||||
|
|
||||||
private static final RequestToLoginDtoMapper INSTANCE = new RequestToLoginDtoMapper();
|
|
||||||
|
|
||||||
private RequestToLoginDtoMapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RequestToLoginDtoMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginDto map(HttpServletRequest req) {
|
|
||||||
return map(req, new LoginDto());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginDto map(HttpServletRequest req, LoginDto dto) {
|
|
||||||
dto.setEmail(req.getParameter("email"));
|
|
||||||
dto.setPassword(req.getParameter("password"));
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import ru.charm.back.dto.ProfileUpdateDto;
|
|
||||||
import ru.charm.back.model.Gender;
|
|
||||||
import ru.charm.back.model.Status;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
import static ru.charm.back.utils.StringUtils.isBlank;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class RequestToProfileUpdateDtoMapper implements Mapper<HttpServletRequest, ProfileUpdateDto> {
|
|
||||||
|
|
||||||
private static final RequestToProfileUpdateDtoMapper INSTANCE = new RequestToProfileUpdateDtoMapper();
|
|
||||||
public static RequestToProfileUpdateDtoMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProfileUpdateDto map(HttpServletRequest req) {
|
|
||||||
return map(req, new ProfileUpdateDto());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
@Override
|
|
||||||
public ProfileUpdateDto map(HttpServletRequest req, ProfileUpdateDto dto) {
|
|
||||||
String id = req.getParameter("id");
|
|
||||||
if (!isBlank(id)) {
|
|
||||||
dto.setId(Long.parseLong(id));
|
|
||||||
}
|
|
||||||
String email = req.getParameter("email");
|
|
||||||
if (!isBlank(email)) {
|
|
||||||
dto.setEmail(email);
|
|
||||||
}
|
|
||||||
dto.setName(req.getParameter("name"));
|
|
||||||
dto.setSurname(req.getParameter("surname"));
|
|
||||||
String birthDate = req.getParameter("birthDate");
|
|
||||||
if (!isBlank(birthDate)) {
|
|
||||||
dto.setBirthDate(LocalDate.parse(birthDate));
|
|
||||||
}
|
|
||||||
dto.setAbout(req.getParameter("about"));
|
|
||||||
String gender = req.getParameter("gender");
|
|
||||||
if (!isBlank(gender)) {
|
|
||||||
dto.setGender(Gender.valueOf(gender));
|
|
||||||
}
|
|
||||||
String status = req.getParameter("status");
|
|
||||||
if (!isBlank(status)) {
|
|
||||||
dto.setStatus(Status.valueOf(status));
|
|
||||||
}
|
|
||||||
dto.setPhoto(req.getPart("photo"));
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package ru.charm.back.mapper;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
|
|
||||||
public class RequestToRegistrationDtoMapper implements Mapper<HttpServletRequest, RegistrationDto> {
|
|
||||||
|
|
||||||
private static final RequestToRegistrationDtoMapper INSTANCE = new RequestToRegistrationDtoMapper();
|
|
||||||
|
|
||||||
private RequestToRegistrationDtoMapper() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RequestToRegistrationDtoMapper getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegistrationDto map(HttpServletRequest req) {
|
|
||||||
return map(req, new RegistrationDto());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RegistrationDto map(HttpServletRequest req, RegistrationDto dto) {
|
|
||||||
dto.setEmail(req.getParameter("email"));
|
|
||||||
dto.setPassword(req.getParameter("password"));
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package ru.charm.back.model;
|
|
||||||
|
|
||||||
public enum Gender {
|
|
||||||
MALE,
|
|
||||||
FEMALE
|
|
||||||
}
|
|
||||||
@ -1,21 +1,60 @@
|
|||||||
package ru.charm.back.model;
|
package ru.charm.back.model;
|
||||||
|
|
||||||
import jakarta.servlet.http.Part;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class Profile {
|
public class Profile {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String email;
|
private String email;
|
||||||
private String password;
|
|
||||||
private String name;
|
private String name;
|
||||||
private String surname;
|
private String surname;
|
||||||
private LocalDate birthDate;
|
|
||||||
private String about;
|
private String about;
|
||||||
private Gender gender;
|
|
||||||
private Status status;
|
public Long getId() {
|
||||||
private String photo;
|
return id;
|
||||||
private Role role;
|
}
|
||||||
}
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAbout() {
|
||||||
|
return about;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAbout(String about) {
|
||||||
|
this.about = about;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Profile{" +
|
||||||
|
"id=" + id +
|
||||||
|
", email='" + email + '\'' +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", surname='" + surname + '\'' +
|
||||||
|
", about='" + about + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
package ru.charm.back.model;
|
|
||||||
|
|
||||||
public enum Role {
|
|
||||||
ADMIN,
|
|
||||||
USER
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package ru.charm.back.model;
|
|
||||||
|
|
||||||
public enum Status {
|
|
||||||
ACTIVE, INACTIVE
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
package ru.charm.back.model.exception;
|
|
||||||
|
|
||||||
public class DuplicateEmailException extends RuntimeException {
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
package ru.charm.back.service;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletOutputStream;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
import static java.nio.file.StandardOpenOption.CREATE;
|
|
||||||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
@Slf4j
|
|
||||||
public class ContentService {
|
|
||||||
private static final ContentService INSTANCE = new ContentService();
|
|
||||||
public static ContentService getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String BASE_PATH = "/Users/ksv741/Project/education/YouTube/tinder-clone/Tinder Clone/media";
|
|
||||||
|
|
||||||
public void upload(String contentPath, InputStream inputStream) throws IOException {
|
|
||||||
Path contentFullPath = getAbsolutePath(contentPath);
|
|
||||||
OutputStream outputStream = Files.exists(contentFullPath.getParent())
|
|
||||||
? Files.newOutputStream(contentFullPath, CREATE, TRUNCATE_EXISTING)
|
|
||||||
: null;
|
|
||||||
if (outputStream == null) {
|
|
||||||
throw new FileNotFoundException();
|
|
||||||
}
|
|
||||||
writeContent(inputStream, outputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void download(String contentPath, ServletOutputStream outputStream) throws IOException {
|
|
||||||
InputStream inputStream;
|
|
||||||
if (contentPath.startsWith("/app/")) {
|
|
||||||
String appPath = "/WEB-INF" + contentPath.replaceFirst("/app", "");
|
|
||||||
inputStream = ContentService.class.getClassLoader().getResourceAsStream(appPath);
|
|
||||||
} else {
|
|
||||||
Path contentFullPath = getAbsolutePath(contentPath);
|
|
||||||
inputStream = Files.exists(contentFullPath) ? Files.newInputStream(contentFullPath) : null;
|
|
||||||
}
|
|
||||||
if (inputStream == null) {
|
|
||||||
throw new FileNotFoundException();
|
|
||||||
}
|
|
||||||
writeContent(inputStream, outputStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeContent(InputStream inputStream, OutputStream outputStream) throws IOException {
|
|
||||||
try (inputStream; outputStream) {
|
|
||||||
int currentByte;
|
|
||||||
while ((currentByte = inputStream.read()) != -1) {
|
|
||||||
outputStream.write(currentByte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Path getAbsolutePath(String contentPath) {
|
|
||||||
return Path.of(BASE_PATH, contentPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,76 +1,43 @@
|
|||||||
package ru.charm.back.service;
|
package ru.charm.back.service;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import ru.charm.back.dao.ProfileDao;
|
import ru.charm.back.dao.ProfileDao;
|
||||||
import ru.charm.back.dto.LoginDto;
|
|
||||||
import ru.charm.back.dto.ProfileGetDto;
|
|
||||||
import ru.charm.back.dto.ProfileUpdateDto;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
import ru.charm.back.mapper.ProfileToProfileGetDtoMapper;
|
|
||||||
import ru.charm.back.mapper.ProfileUpdateDtoToProfileMapper;
|
|
||||||
import ru.charm.back.mapper.RegistrationDtoToProfileMapper;
|
|
||||||
import ru.charm.back.model.Profile;
|
import ru.charm.back.model.Profile;
|
||||||
import ru.charm.back.model.exception.DuplicateEmailException;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class ProfileService {
|
public class ProfileService {
|
||||||
|
private ProfileDao dao;
|
||||||
|
|
||||||
private static final ProfileService INSTANCE = new ProfileService();
|
public ProfileService(ProfileDao dao) {
|
||||||
|
this.dao = dao;
|
||||||
private final ProfileDao dao = ProfileDao.getInstance();
|
|
||||||
|
|
||||||
private final ContentService contentService = ContentService.getInstance();
|
|
||||||
|
|
||||||
private final ProfileToProfileGetDtoMapper profileToProfileGetDtoMapper = ProfileToProfileGetDtoMapper.getInstance();
|
|
||||||
|
|
||||||
private final ProfileUpdateDtoToProfileMapper profileUpdateDtoToProfileMapper = ProfileUpdateDtoToProfileMapper.getInstance();
|
|
||||||
|
|
||||||
private final RegistrationDtoToProfileMapper registrationDtoToProfileMapper = RegistrationDtoToProfileMapper.getInstance();
|
|
||||||
|
|
||||||
public static ProfileService getInstance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long save(RegistrationDto dto) {
|
public Profile save(Profile profile) {
|
||||||
return dao.save(registrationDtoToProfileMapper.map(dto)).getId();
|
return dao.save(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ProfileGetDto> findById(Long id) {
|
public Optional<Profile> findById(Long id) {
|
||||||
return dao.findById(id).map(profileToProfileGetDtoMapper::map);
|
if (id == null) {
|
||||||
}
|
return Optional.empty();
|
||||||
|
|
||||||
public List<ProfileGetDto> findAll() {
|
|
||||||
return dao.findAll().stream().map(profileToProfileGetDtoMapper::map).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public void update(ProfileUpdateDto dto) {
|
|
||||||
Optional<Profile> optionalProfile = dao.findById(dto.getId());
|
|
||||||
if (optionalProfile.isPresent()) {
|
|
||||||
if (dto.getPhoto() != null) {
|
|
||||||
contentService.upload(
|
|
||||||
"/profiles/" + dto.getId() + "/" + dto.getPhoto().getSubmittedFileName(),
|
|
||||||
dto.getPhoto().getInputStream()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
dao.update(profileUpdateDtoToProfileMapper.map(dto, optionalProfile.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dao.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean delete(Long id) {
|
public Boolean delete(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return dao.delete(id);
|
return dao.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ProfileGetDto> login(LoginDto dto) {
|
public void update(Profile profile) {
|
||||||
return dao.findByEmail(dto.getEmail())
|
dao.update(profile);
|
||||||
.filter(profile -> profile.getPassword().equals(dto.getPassword()))
|
|
||||||
.map(profileToProfileGetDtoMapper::map);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public List<Profile> findAll() {
|
||||||
|
return dao.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
package ru.charm.back.service;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.MissingResourceException;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
|
|
||||||
public class WordBundle {
|
|
||||||
private final ResourceBundle resourceBundle;
|
|
||||||
|
|
||||||
public WordBundle(String lang) {
|
|
||||||
Locale locale = Locale.of("en");
|
|
||||||
if ("ru".equals(lang)) {
|
|
||||||
locale = Locale.of("ru");
|
|
||||||
}
|
|
||||||
this.resourceBundle = ResourceBundle.getBundle("words", locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWord(String key) {
|
|
||||||
String result;
|
|
||||||
try {
|
|
||||||
result = resourceBundle.getString(key.toLowerCase());
|
|
||||||
} catch (MissingResourceException | ClassCastException e) {
|
|
||||||
String[] pathArray = key.split("\\.");
|
|
||||||
result = pathArray[pathArray.length - 1];
|
|
||||||
} catch (Exception e) {
|
|
||||||
return "* empty *";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package ru.charm.back.utils;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class StringUtils {
|
|
||||||
public static final Pattern VALID_EMAIL_ADDRESS_REGEX =
|
|
||||||
Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);
|
|
||||||
|
|
||||||
public static boolean isBlank(String str) {
|
|
||||||
return str == null || str.isBlank();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package ru.charm.back.validator;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import ru.charm.back.dao.ProfileDao;
|
|
||||||
import ru.charm.back.dto.RegistrationDto;
|
|
||||||
import ru.charm.back.mapper.ProfileUpdateDtoToProfileMapper;
|
|
||||||
|
|
||||||
import static ru.charm.back.utils.StringUtils.VALID_EMAIL_ADDRESS_REGEX;
|
|
||||||
import static ru.charm.back.utils.StringUtils.isBlank;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class RegistrationValidator implements Validator<RegistrationDto> {
|
|
||||||
private static final RegistrationValidator INSTANCE = new RegistrationValidator();
|
|
||||||
public static RegistrationValidator getInstance() { return INSTANCE; }
|
|
||||||
|
|
||||||
private final ProfileDao dao = ProfileDao.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ValidationResult validate(RegistrationDto dto) {
|
|
||||||
ValidationResult validationResult = new ValidationResult();
|
|
||||||
|
|
||||||
if (isBlank(dto.getEmail()) || !VALID_EMAIL_ADDRESS_REGEX.matcher(dto.getEmail()).matches()) {
|
|
||||||
validationResult.addError("error.email.invalid");
|
|
||||||
} else if (dao.getAllEmails().contains(dto.getEmail())) {
|
|
||||||
validationResult.addError("error.email.exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isBlank(dto.getPassword())) {
|
|
||||||
validationResult.addError("error.password.invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
return validationResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package ru.charm.back.validator;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ValidationResult {
|
|
||||||
private final List<String> errors = new ArrayList<>();
|
|
||||||
|
|
||||||
public boolean isValid() {
|
|
||||||
return errors.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addError(String code) {
|
|
||||||
errors.add(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getErrors() {
|
|
||||||
return new ArrayList<>(errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package ru.charm.back.validator;
|
|
||||||
|
|
||||||
public interface Validator<T> {
|
|
||||||
ValidationResult validate(T object);
|
|
||||||
}
|
|
||||||