Compare commits
3 Commits
LabWork4
...
LabWork6(M
| Author | SHA1 | Date | |
|---|---|---|---|
| 475875c357 | |||
| 9d4f79f1ae | |||
| 4f574dbb18 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,12 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'com.h2database:h2:2.1.214'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
|
||||
implementation 'junit:junit:4.13.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
|
||||
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
534
data.trace.db
534
data.trace.db
@@ -358,3 +358,537 @@ select genre0_.id as id1_2_, genre0_.name as name2_2_ from genre genre0_ where g
|
||||
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
|
||||
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
|
||||
at java.base/java.lang.Thread.run(Thread.java:833)
|
||||
2023-06-15 17:40:19 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$logDataSources$0(H2ConsoleAutoConfiguration.java:77)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
|
||||
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
|
||||
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:83)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:70)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:86)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53)
|
||||
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
|
||||
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
|
||||
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:478)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 99 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 93 more
|
||||
2023-06-15 17:40:21 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
|
||||
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
|
||||
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
|
||||
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173)
|
||||
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 66 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 60 more
|
||||
2023-06-15 17:40:23 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
|
||||
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
|
||||
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
|
||||
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:387)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:371)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:246)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:156)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:128)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:114)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:153)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
|
||||
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
|
||||
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 66 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 60 more
|
||||
2023-06-15 17:48:12 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$logDataSources$0(H2ConsoleAutoConfiguration.java:77)
|
||||
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
|
||||
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
|
||||
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
|
||||
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
|
||||
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
|
||||
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
|
||||
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
|
||||
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:83)
|
||||
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:70)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
|
||||
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97)
|
||||
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:86)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53)
|
||||
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
|
||||
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
|
||||
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
|
||||
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
|
||||
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
|
||||
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
|
||||
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
|
||||
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
|
||||
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
|
||||
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:478)
|
||||
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 99 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 93 more
|
||||
2023-06-15 17:48:14 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
|
||||
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
|
||||
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
|
||||
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
|
||||
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173)
|
||||
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 66 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 60 more
|
||||
2023-06-15 17:48:15 database: flush
|
||||
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.get(DbException.java:212)
|
||||
at org.h2.message.DbException.convert(DbException.java:395)
|
||||
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
|
||||
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
|
||||
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
|
||||
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
|
||||
at org.h2.mvstore.db.Store.<init>(Store.java:136)
|
||||
at org.h2.engine.Database.<init>(Database.java:324)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:92)
|
||||
at org.h2.engine.Engine.openSession(Engine.java:222)
|
||||
at org.h2.engine.Engine.createSession(Engine.java:201)
|
||||
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
|
||||
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
|
||||
at org.h2.Driver.connect(Driver.java:59)
|
||||
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
|
||||
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
|
||||
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
|
||||
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
|
||||
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
|
||||
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
|
||||
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
|
||||
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
|
||||
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
|
||||
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
|
||||
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:387)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:371)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:246)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:156)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:128)
|
||||
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:114)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:153)
|
||||
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
|
||||
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
|
||||
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
|
||||
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
|
||||
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
|
||||
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
|
||||
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
|
||||
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
|
||||
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
|
||||
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
|
||||
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
|
||||
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
|
||||
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
|
||||
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
|
||||
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
|
||||
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
|
||||
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
|
||||
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
|
||||
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|
||||
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
|
||||
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
|
||||
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
|
||||
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
|
||||
... 66 more
|
||||
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
|
||||
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:178)
|
||||
at org.h2.mvstore.FileStore.open(FileStore.java:128)
|
||||
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
|
||||
... 60 more
|
||||
|
||||
5
frontend/src/Components/Footer.html
Normal file
5
frontend/src/Components/Footer.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<footer class="flex-item6">
|
||||
<div class="text-center text-light p-2" style="font-size: 30px; font-weight: bold;">
|
||||
@2022 Copyright: BLSJY.com
|
||||
</div>
|
||||
</footer>
|
||||
@@ -1,10 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className="flex-item6">
|
||||
<div className="text-center text-light p-2" style={{fontSize: "30px", fontWeight: "bold"}}>@2022 Copyright: BLSJY.com</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
export default Footer;
|
||||
24
frontend/src/Components/Navbar.html
Normal file
24
frontend/src/Components/Navbar.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<nav class="navbar navbar-expand-lg navbar-light">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/movie/{customerId}(customerId=${customerId})}">
|
||||
Main Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/genre/{customerId}(customerId=${customerId})}">
|
||||
Search Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/library/{customerId}(customerId=${customerId})}">
|
||||
Library Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/customer}">
|
||||
Registration Page
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -1,28 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
function Navbar({ customerId }) {
|
||||
return (
|
||||
<nav class="navbar navbar-expand-lg navbar-light">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/movie/${customerId}`}>Main Page</Link></a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/genre/${customerId}`}>Search Page</Link></a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/library/${customerId}`}>Library Page</Link></a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to="/customer">Registration Page</Link></a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
export default Navbar;
|
||||
13
frontend/src/Templates/Error.html
Normal file
13
frontend/src/Templates/Error.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div><span th:text="${error}"></span></div>
|
||||
<a href="/">Return to registration</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
85
frontend/src/Templates/Filmpage.html
Normal file
85
frontend/src/Templates/Filmpage.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex; background-image: url('background.png');">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
|
||||
<main style="display: flex; flex: 1; gap: 100px;">
|
||||
<div class="flex-container" style="display: inline-flex; flex: 1; flex-wrap: wrap; gap: 40px;">
|
||||
<div class="flex-item1 align-self-center" style="flex: 1;">
|
||||
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" width="400px" height="600px"/>
|
||||
</div>
|
||||
<div class="flex-container align-self-center" style="flex: 3;">
|
||||
<div class="flex-item1 text-light" style="font-size: 50px;"><a th:text="${movie.title}"></a></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Average score: <span th:text="${movie.score}"></span></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Length: <span th:text="${movie.length}"></span></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Genre: <span th:text="${movie.genreName}"></span></div>
|
||||
<button class="primary" onclick="handleModalOpen()">Edit Movie</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<div id="modal" class="modal" th:classappend="${showModal} ? 'show' : ''">
|
||||
<div class="modal-content">
|
||||
<span class="close" onclick="handleModalClose()">×</span>
|
||||
<h2>Edit Movie</h2>
|
||||
<div class="form-group">
|
||||
<label>Title:</label>
|
||||
<input type="text" class="form-control" name="title" th:value="${modalData.title}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Score:</label>
|
||||
<input type="text" class="form-control" name="score" th:value="${modalData.score}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Length:</label>
|
||||
<input type="text" class="form-control" name="length" th:value="${modalData.length}"/>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" onclick="handleModalClose()">Close</button>
|
||||
<button class="btn btn-primary" onclick="handleModalSubmit()">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
|
||||
function handleModalOpen() {
|
||||
var modal = document.getElementById("modal");
|
||||
modal.classList.add("show");
|
||||
}
|
||||
|
||||
function handleModalClose() {
|
||||
var modal = document.getElementById("modal");
|
||||
modal.classList.remove("show");
|
||||
|
||||
titleInput.value = "";
|
||||
scoreInput.value = "";
|
||||
lengthInput.value = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleModalSubmit() {
|
||||
var titleInput = document.getElementsByName("title")[0];
|
||||
var scoreInput = document.getElementsByName("score")[0];
|
||||
var lengthInput = document.getElementsByName("length")[0];
|
||||
|
||||
var modalData = {
|
||||
title: titleInput.value,
|
||||
score: scoreInput.value,
|
||||
length: lengthInput.value
|
||||
};
|
||||
|
||||
const movieId = "${param.movieId}";
|
||||
modal.classList.remove("show");
|
||||
window.location.href = `/movies/movie/update/${movieId}?title=${modalData["title"]}&length=${modalData["length"]}&score=${modalData["score"]}`
|
||||
}
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
36
frontend/src/Templates/Librarypage.html
Normal file
36
frontend/src/Templates/Librarypage.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
|
||||
|
||||
<div class="flex-container min-vh-100" style="display: flex; margin-left: 20px; margin-top: 50px">
|
||||
|
||||
<th:block th:if="${movies.size() > 0}">
|
||||
<div style="flex-direction: row; display: flex; flex-wrap: wrap; gap: 30px">
|
||||
<th:block th:each="movie : ${movies}">
|
||||
<div>
|
||||
<h3 th:text="${movie.title}"></h3>
|
||||
<form th:action="@{/movies/{customerId}/delete/{movieId}(customerId=${customerId}, movieId=${movie.id})}" method="post">
|
||||
<button type="submit">Remove</button>
|
||||
</form>
|
||||
</div>
|
||||
</th:block>
|
||||
</div>
|
||||
</th:block>
|
||||
<h1 th:unless="${movies.size() > 0}" style="color: white">No movies available</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
32
frontend/src/Templates/Login.html
Normal file
32
frontend/src/Templates/Login.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex; ">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex; align-items: center; justify-content: center; gap: 20px;">
|
||||
<h1 for="userSelect" style="color: white;">Select User:</h1>
|
||||
<select id="userSelect" onchange="handleUserChange(event)" style="width: 100px;">
|
||||
<option th:each="customer : ${customers}" th:value="${customer.id}" th:text="${customer.username}"></option>
|
||||
</select>
|
||||
<button style="margin-top: 50px;" onclick="handleLogin()">Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
|
||||
function handleUserChange(event) {
|
||||
var selectedUserId = event.target.value;
|
||||
}
|
||||
|
||||
function handleLogin() {
|
||||
var selectedUserId = document.getElementById("userSelect").value;
|
||||
document.cookie = "userID=" + selectedUserId;
|
||||
window.location.href = "/genre/fill";
|
||||
}
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
38
frontend/src/Templates/Mainpage.html
Normal file
38
frontend/src/Templates/Mainpage.html
Normal file
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
|
||||
|
||||
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px;">
|
||||
<div th:if="${movies.length > 0}" style="flex-direction: row; display: flex; flex-wrap: wrap; justify-content: space-between;">
|
||||
<div th:each="movie : ${movies}" style="margin-bottom: 20px;">
|
||||
<div>
|
||||
<h3><a th:href="@{/movies/movie/{movieId}, movieId=${movie.id}}"
|
||||
th:text="${movie.title}"></a></h3>
|
||||
<button type="button" th:attr="data-movie-id=${movie.id}" onclick="handleAcquireMovie(event)">Acquire</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:unless="${movies.length > 0}" style="color: white;">No movies available</h1>
|
||||
</div>
|
||||
|
||||
<div th:replace="fragments/footer :: footer"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script th:inline="javascript">
|
||||
|
||||
function handleAcquireMovie(movieId) {
|
||||
var movieId = event.target.getAttribute("data-movie-id");
|
||||
var customerID = /*[[${userId}]]*/ null;
|
||||
var url = "/movies/" + customerId + "/" + movieId;
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
37
frontend/src/Templates/Registration.html
Normal file
37
frontend/src/Templates/Registration.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex;">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
|
||||
<main style="display: flex; flex: 1;">
|
||||
<aside class="flex-item2" style="flex: 2;"></aside>
|
||||
<div class="flex-item3 align-self-center" style="flex: 3;"><img src="cover.png" alt="cover" width="100%" height="600px"/></div>
|
||||
<section class="flex-container align-self-center" style="height: 660px; flex: 4; background-color: #ffd79d; flex-direction: column; display: flex;">
|
||||
<form action="#" th:action="@{/customer}" method="post">
|
||||
<section class="flex-itemR1" style="color: #320D3E; font-size: 50px; font-weight: bold; padding-left: 30px; padding-top: 10px;">SIGN UP</section>
|
||||
<section class="flex-itemR2" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
|
||||
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">USERNAME</label>
|
||||
</section>
|
||||
<section class="flex-itemR3" style="display: flex; width: 320px; padding-left: 30px;">
|
||||
<input class="form-control" id="inputUsername" type="string" name="fullName" placeholder="Enter username" th:value="${inputUsername}"/>
|
||||
</section>
|
||||
<section class="flex-itemR6" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
|
||||
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">PASSWORD</label>
|
||||
</section>
|
||||
<section class="flex-itemR7" style="display: flex; width: 320px; padding-left: 30px;">
|
||||
<input class="form-control" id="inputPassword" type="password" name="password" placeholder="Enter password" th:value="${inputPassword}"/>
|
||||
</section>
|
||||
<button class="btn btn-primary" type="submit" id="register" style="font-size: 20px; margin-left: 30px; margin-top: 15px; width: 150px; background-color: #320D3E; color: white; font-weight: bold;">Register</button>
|
||||
<a href="/login">Sign in</a>
|
||||
</form>
|
||||
</section>
|
||||
<aside class="flex-item5" style="flex: 2;"></aside>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
70
frontend/src/Templates/Searchpage.html
Normal file
70
frontend/src/Templates/Searchpage.html
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex;">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex; flex: 1; align-items: center; justify-content: flex-start; margin-top: 20px">
|
||||
<div>
|
||||
<select id="genre-select">
|
||||
<option value="all">All Genres</option>
|
||||
<option th:each="genre : ${genres}" th:value="${genre.name}" th:text="${genre.name}"></option>
|
||||
</select>
|
||||
<button type="button" onclick="handleSearch()">Search</button>
|
||||
</div>
|
||||
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px">
|
||||
<div style="flex-direction: row; display: flex; flex-wrap: wrap; gap: 30px">
|
||||
<div th:if="${movies.length > 0}" th:each="movie : ${movies}" style="margin-bottom: 20px;">
|
||||
<div>
|
||||
<h3><a th:href="@{/movies/movie/{movieId}, movieId=${movie.id}}"
|
||||
th:text="${movie.title}"></a></h3>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:if="${movies.length == 0}" style="color: white">No movies found</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
function handleSearch() {
|
||||
const genreSelect = document.getElementById("genre-select");
|
||||
const selectedGenre = genreSelect.value;
|
||||
|
||||
fetch(`/movies/${selectedGenre}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Update the movies array in the Thymeleaf model
|
||||
const moviesContainer = document.querySelector(".flex-container.min-vh-100 > div:last-child");
|
||||
moviesContainer.innerHTML = ""; // Clear previous movie elements
|
||||
|
||||
if (data.length > 0) {
|
||||
data.forEach(movie => {
|
||||
const movieElement = document.createElement("div");
|
||||
movieElement.innerHTML = `
|
||||
<div>
|
||||
<h3><a th:href="@{/movies/movie/{movieId}, movieId=${movie.id}}"
|
||||
th:text="${movie.title}"></a></h3>
|
||||
</div>
|
||||
`;
|
||||
moviesContainer.appendChild(movieElement);
|
||||
});
|
||||
} else {
|
||||
const noMoviesElement = document.createElement("h1");
|
||||
noMoviesElement.style.color = "white";
|
||||
noMoviesElement.textContent = "No movies found";
|
||||
moviesContainer.appendChild(noMoviesElement);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error fetching movies:", error);
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
43
frontend/src/Templates/Template.html
Normal file
43
frontend/src/Templates/Template.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
|
||||
<div style="background-image: url(background.png);">
|
||||
<nav class="navbar navbar-expand-lg navbar-light">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/movies" th:classappend="${#strings.equals(activeLink, '/movies')} ? 'active' : ''">
|
||||
Main Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/genre" th:classappend="${#strings.equals(activeLink, '/genre')} ? 'active' : ''">
|
||||
Search Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/customer/movies/{customerId}(customerId=${param.customerId})}">
|
||||
Library Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/" th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">
|
||||
Registration Page
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div layout:fragment="content">
|
||||
|
||||
</div>
|
||||
<footer class="flex-item6">
|
||||
<div class="text-center text-light p-2" style="font-size: 30px; font-weight: bold;">
|
||||
@2022 Copyright: BLSJY.com
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<th:block layout:fragment="scripts">
|
||||
</th:block>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 176 KiB |
@@ -1,50 +0,0 @@
|
||||
package ru.ulstu.is.sbapp.Customer.Controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
|
||||
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/customer")
|
||||
public class CustomerController {
|
||||
private final CustomerService customerService;
|
||||
|
||||
public CustomerController(CustomerService customerService)
|
||||
{
|
||||
this.customerService = customerService;
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public CustomerDTO getCustomer(@PathVariable Long id) {
|
||||
return new CustomerDTO(customerService.findCustomer(id));
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public List<CustomerDTO> getCustomers() {
|
||||
return customerService.findAllCustomers().stream().map(CustomerDTO::new).toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public CustomerDTO createCustomer(@RequestParam("fullName") String fullName, @RequestParam("password") String password ) {
|
||||
return new CustomerDTO(customerService.addCustomer(fullName,password));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public CustomerDTO updateCustomer(@PathVariable Long id, @RequestParam("fullName") String fullName) {
|
||||
return new CustomerDTO(customerService.updateCustomer(id,fullName));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public CustomerDTO deleteCustomer(@PathVariable Long id) {
|
||||
return new CustomerDTO(customerService.deleteCustomer(id));
|
||||
}
|
||||
|
||||
@GetMapping("/movies/{customerId}")
|
||||
public List<MovieDTO> getCustomerMovies(@PathVariable("customerId") Long customerId) {
|
||||
return customerService.findCustomerMovies(customerId).stream()
|
||||
.map(MovieDTO::new)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package ru.ulstu.is.sbapp.Customer.Controller;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.Customer;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
|
||||
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -9,14 +11,17 @@ public class CustomerDTO {
|
||||
private final long id;
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final CustomerRole role;
|
||||
private final List<MovieDTO> movies;
|
||||
public CustomerDTO(Customer customer) {
|
||||
this.id = customer.getId();
|
||||
this.username = customer.getUsername();
|
||||
this.password = customer.getPassword();
|
||||
this.role = customer.getRole();
|
||||
this.movies = customer.getMovies().stream().map(MovieDTO::new).toList();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getID() {
|
||||
return id;
|
||||
}
|
||||
@@ -29,6 +34,10 @@ public class CustomerDTO {
|
||||
return password;
|
||||
}
|
||||
|
||||
public CustomerRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public List<MovieDTO> getMovies() {
|
||||
return movies;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package ru.ulstu.is.sbapp.Customer.Controller;
|
||||
|
||||
import ru.ulstu.is.sbapp.Customer.Model.Customer;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
public class CustomerSignupDTO {
|
||||
|
||||
@NotBlank(message = "Username can't be null or empty")
|
||||
@Size(min = 3, max = 64)
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "Password can't be empty")
|
||||
@Size(min = 6, max = 64)
|
||||
private String password;
|
||||
private CustomerRole role;
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
public CustomerRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(CustomerRole role) {
|
||||
this.role = role;
|
||||
}
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package ru.ulstu.is.sbapp.Customer.MVC;
|
||||
|
||||
import org.aspectj.lang.annotation.RequiredTypes;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Customer.Controller.CustomerDTO;
|
||||
import ru.ulstu.is.sbapp.Customer.Controller.CustomerSignupDTO;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.Customer;
|
||||
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
|
||||
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
|
||||
import ru.ulstu.is.sbapp.Utilities.CookiesManagement;
|
||||
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/customer")
|
||||
public class CustomerMVC {
|
||||
private final CustomerService customerService;
|
||||
private final CookiesManagement cookiesManagement;
|
||||
|
||||
public CustomerMVC(CustomerService customerService)
|
||||
{
|
||||
this.customerService = customerService;
|
||||
this.cookiesManagement = new CookiesManagement();
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String showSignupForm(Model model) {
|
||||
model.addAttribute("customerDTO", new CustomerSignupDTO());
|
||||
return "Registration";
|
||||
}
|
||||
|
||||
@GetMapping("/find/{username}")
|
||||
public Long findCustomer(@PathVariable String username) {
|
||||
return customerService.findByLogin(username).getId();
|
||||
}
|
||||
|
||||
|
||||
@PostMapping
|
||||
public String createCustomer(@ModelAttribute("customerDTO") @Valid CustomerSignupDTO customerSignupDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "Registration";
|
||||
}
|
||||
try {
|
||||
final Customer customer = customerService.createCustomer(
|
||||
customerSignupDTO.getUsername(), customerSignupDTO.getPassword(),customerSignupDTO.getRole());
|
||||
return "redirect:/Login?created=" + customer.getUsername();
|
||||
} catch (ValidationException e) {
|
||||
model.addAttribute("errors", e.getMessage());
|
||||
return "Registration";
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public String updateCustomer(@PathVariable Long id, @RequestParam("fullName") String fullName) {
|
||||
return "redirect:/customer/" + new CustomerDTO(customerService.updateCustomer(id,fullName)).getID();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public String deleteCustomer(@PathVariable Long id) {
|
||||
customerService.deleteCustomer(id);
|
||||
return "redirect:/customer";
|
||||
}
|
||||
|
||||
@GetMapping("/movies")
|
||||
public String getCustomerMovies(Model model) {
|
||||
|
||||
String username = null;
|
||||
|
||||
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
|
||||
if (principal instanceof UserDetails) {
|
||||
username = ((UserDetails)principal). getUsername();
|
||||
} else {
|
||||
username = principal. toString();
|
||||
}
|
||||
|
||||
|
||||
model.addAttribute("movies", customerService.findCustomerMovies(customerService.findByLogin(username).getId()).stream()
|
||||
.map(MovieDTO::new)
|
||||
.toList());
|
||||
model.addAttribute("customerId",customerService.findByLogin(username).getId());
|
||||
return "Librarypage";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
@Entity
|
||||
public class Customer
|
||||
@@ -15,12 +16,16 @@ public class Customer
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
@Column
|
||||
@Column(nullable = false, unique = true, length = 64)
|
||||
@NotBlank(message = "Username can't be null or empty")
|
||||
@Size(min = 3, max = 64)
|
||||
private String username;
|
||||
@Column
|
||||
@Column(nullable = false, length = 64)
|
||||
@NotBlank(message = "Password can't be empty")
|
||||
@Size(min = 6, max = 64)
|
||||
private String password;
|
||||
|
||||
private CustomerRole role;
|
||||
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
private List<Movie> movies;
|
||||
|
||||
@@ -29,14 +34,15 @@ public class Customer
|
||||
{
|
||||
|
||||
}
|
||||
public Customer(String username,String password)
|
||||
public Customer(String username,String password,CustomerRole role)
|
||||
{
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
||||
this.role = role;
|
||||
this.movies = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
@@ -48,6 +54,10 @@ public class Customer
|
||||
return username;
|
||||
}
|
||||
|
||||
public CustomerRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setUsername(String username)
|
||||
{
|
||||
this.username = username;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.ulstu.is.sbapp.Customer.Model;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
public enum CustomerRole implements GrantedAuthority {
|
||||
ADMIN,
|
||||
USER;
|
||||
|
||||
private static final String PREFIX = "ROLE_";
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return PREFIX + this.name();
|
||||
}
|
||||
|
||||
public static final class AsString {
|
||||
public static final String ADMIN = PREFIX + "ADMIN";
|
||||
public static final String USER = PREFIX + "USER";
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.Customer;
|
||||
|
||||
public interface CustomerRepository extends JpaRepository<Customer, Long> {
|
||||
Customer findOneByUsernameIgnoreCase(String login);
|
||||
}
|
||||
|
||||
@@ -1,53 +1,67 @@
|
||||
package ru.ulstu.is.sbapp.Customer.Service;
|
||||
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.Customer;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
|
||||
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
|
||||
import ru.ulstu.is.sbapp.Movie.Model.Movie;
|
||||
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
|
||||
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class CustomerService
|
||||
public class CustomerService implements UserDetailsService
|
||||
{
|
||||
private final CustomerRepository customerRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public CustomerService(CustomerRepository customerRepository, ValidatorUtil validatorUtil) {
|
||||
public CustomerService(CustomerRepository customerRepository, ValidatorUtil validatorUtil, PasswordEncoder passwordEncoder) {
|
||||
this.customerRepository = customerRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Customer addCustomer(String fullName,String password)
|
||||
{
|
||||
if(!StringUtils.hasText(fullName))
|
||||
{
|
||||
throw new IllegalArgumentException("Customer's name or surname is missing");
|
||||
}
|
||||
public Customer findByLogin(String login) {
|
||||
return customerRepository.findOneByUsernameIgnoreCase(login);
|
||||
}
|
||||
|
||||
if(!StringUtils.hasText(password))
|
||||
{
|
||||
throw new IllegalArgumentException("Customer's name or surname is missing");
|
||||
public Customer createCustomer(String login, String password, CustomerRole role){
|
||||
if (findByLogin(login) != null) {
|
||||
throw new ValidationException(String.format("Customer '%s' already exists", login));
|
||||
}
|
||||
|
||||
final Customer customer = new Customer(fullName,password);
|
||||
final Customer customer = new Customer(login,passwordEncoder.encode(password), role);
|
||||
validatorUtil.validate(customer);
|
||||
return customerRepository.save(customer);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
final Customer customerEntity = findByLogin(username);
|
||||
if (customerEntity == null) {
|
||||
throw new UsernameNotFoundException(username);
|
||||
}
|
||||
return new org.springframework.security.core.userdetails.User(
|
||||
customerEntity.getUsername(), customerEntity.getPassword(), Collections.singleton(customerEntity.getRole()));
|
||||
}
|
||||
|
||||
/*@Transactional(readOnly = true)
|
||||
public Customer findCustomer(Long id)
|
||||
{
|
||||
final Optional<Customer> student = customerRepository.findById(id);
|
||||
return student.orElseThrow(() -> new CustomerNotFoundException(id));
|
||||
}
|
||||
}*/
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Customer> findAllCustomers()
|
||||
|
||||
@@ -2,13 +2,16 @@ package ru.ulstu.is.sbapp.Genre.Controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/genre")
|
||||
public class GenreContoller {
|
||||
@RequestMapping(WebConfiguration.REST_API + "/genre")
|
||||
@ControllerAdvice(annotations = RestController.class)
|
||||
public class GenreController {
|
||||
private final GenreService genreService;
|
||||
|
||||
public GenreContoller(GenreService genreService) {
|
||||
public GenreController(GenreService genreService) {
|
||||
this.genreService = genreService;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.ulstu.is.sbapp.Genre.Controller;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ru.ulstu.is.sbapp.Genre.Model.Genre;
|
||||
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
|
||||
|
||||
@@ -16,6 +17,8 @@ public class GenreDTO {
|
||||
this.name = genre.getName();
|
||||
this.movies = genre.getMovies().stream().map(MovieDTO::new).toList();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
51
src/main/java/ru/ulstu/is/sbapp/Genre/MVC/GenreMVC.java
Normal file
51
src/main/java/ru/ulstu/is/sbapp/Genre/MVC/GenreMVC.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package ru.ulstu.is.sbapp.Genre.MVC;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Genre.Controller.GenreDTO;
|
||||
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
|
||||
import java.util.List;
|
||||
@Controller
|
||||
@RequestMapping("/genre")
|
||||
public class GenreMVC {
|
||||
private final GenreService genreService;
|
||||
|
||||
public GenreMVC(GenreService genreService) {
|
||||
this.genreService = genreService;
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public String getGenre(@PathVariable Long id, Model model) {
|
||||
model.addAttribute("genre",new GenreDTO(genreService.findGenre(id)));
|
||||
return "genre-details";
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getGenres(Model model) {
|
||||
model.addAttribute("genres",genreService.findAllGenres().stream()
|
||||
.map(GenreDTO::new)
|
||||
.toList());
|
||||
return "Searchpage";
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public String createGenre(@RequestParam("name") String name) {
|
||||
|
||||
return "redirect:/genre/" + new GenreDTO(genreService.addGenre(name)).getID();
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public String updateGenre(@PathVariable Long id,
|
||||
@RequestParam("name") String name) {
|
||||
return "redirect:/genre/" + new GenreDTO(genreService.updateGenre(id,name)).getID();
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public String deleteGenre(@PathVariable Long id) {
|
||||
|
||||
genreService.deleteGenre(id);
|
||||
return "redirect:/genre";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,12 @@ package ru.ulstu.is.sbapp.Movie.Controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/movie")
|
||||
@RequestMapping(WebConfiguration.REST_API + "/movie")
|
||||
@ControllerAdvice(annotations = RestController.class)
|
||||
public class MovieController {
|
||||
private final MovieService movieService;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.ulstu.is.sbapp.Movie.Controller;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ru.ulstu.is.sbapp.Genre.Model.Genre;
|
||||
import ru.ulstu.is.sbapp.Movie.Model.Movie;
|
||||
|
||||
@@ -20,6 +21,7 @@ public class MovieDTO {
|
||||
this.score = movie.getScore();
|
||||
this.genreName = movie.getGenre().getName();
|
||||
}
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
144
src/main/java/ru/ulstu/is/sbapp/Movie/MVC/MovieMVC.java
Normal file
144
src/main/java/ru/ulstu/is/sbapp/Movie/MVC/MovieMVC.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package ru.ulstu.is.sbapp.Movie.MVC;
|
||||
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
|
||||
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
|
||||
import ru.ulstu.is.sbapp.Genre.Controller.GenreDTO;
|
||||
import ru.ulstu.is.sbapp.Genre.Model.Genre;
|
||||
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
|
||||
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
|
||||
import ru.ulstu.is.sbapp.Movie.Model.Movie;
|
||||
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
|
||||
import ru.ulstu.is.sbapp.Utilities.CookiesManagement;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Objects;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/movies")
|
||||
public class MovieMVC {
|
||||
private final MovieService movieService;
|
||||
private final GenreService genreService;
|
||||
private final CustomerService customerService;
|
||||
private final CookiesManagement cookiesManagement;
|
||||
public MovieMVC(MovieService movieService, GenreService genreService,CustomerService customerService)
|
||||
{
|
||||
this.movieService = movieService;
|
||||
this.genreService = genreService;
|
||||
this.customerService = customerService;
|
||||
this.cookiesManagement = new CookiesManagement();
|
||||
}
|
||||
|
||||
@GetMapping("/movie/{id}")
|
||||
public String getMovie(@PathVariable Long id, Model model) {
|
||||
model.addAttribute("movie", new MovieDTO(movieService.findMovie(id)));
|
||||
return "Filmpage";
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getMovies(Model model) {
|
||||
|
||||
genreService.fillRepo();
|
||||
movieService.fillRepo();
|
||||
String username = null;
|
||||
|
||||
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
|
||||
if (principal instanceof UserDetails) {
|
||||
username = ((UserDetails)principal). getUsername();
|
||||
} else {
|
||||
username = principal. toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
model.addAttribute("movies", movieService.findAllMovies().stream()
|
||||
.map(MovieDTO::new)
|
||||
.toList());
|
||||
model.addAttribute("userId", customerService.findByLogin(username).getId());
|
||||
return "Mainpage";
|
||||
}
|
||||
|
||||
@GetMapping("/{genre}")
|
||||
public String getSpecificMovies(@PathVariable("genre") String genre, Model model) {
|
||||
if(!Objects.equals(genre, "null") && !Objects.equals(genre,"all"))
|
||||
{
|
||||
model.addAttribute("movies", movieService.findAllSpecificMovies(genre).stream()
|
||||
.map(MovieDTO::new)
|
||||
.toList());
|
||||
}
|
||||
else
|
||||
{
|
||||
model.addAttribute("movies", movieService.findAllMovies().stream()
|
||||
.map(MovieDTO::new)
|
||||
.toList());
|
||||
}
|
||||
model.addAttribute("genres",genreService.findAllGenres().stream().map(GenreDTO::new).toList());
|
||||
return "Searchpage";
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
public String createMovie(@RequestParam("title") String title,
|
||||
@RequestParam("length") int length,
|
||||
@RequestParam("score") double score,
|
||||
@RequestParam("genre") Long genreId) {
|
||||
|
||||
return "redirect:/movie" + new MovieDTO(movieService.addMovie(title, length, score, genreId)).getID();
|
||||
}
|
||||
|
||||
@PostMapping("/movie/update/{id}")
|
||||
public String updateMovie(@PathVariable("id") Long id,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("length") int length,
|
||||
@RequestParam("score") double score) {
|
||||
movieService.updateMovie(id, title, length, score);
|
||||
return "redirect:/movies/movie/" + id;
|
||||
}
|
||||
|
||||
@PostMapping("/movie/delete/{id}")
|
||||
@Secured({CustomerRole.AsString.ADMIN})
|
||||
public String deleteMovie(@PathVariable("id") Long id) {
|
||||
movieService.deleteMovie(id);
|
||||
return "redirect:/movies";
|
||||
}
|
||||
|
||||
@PostMapping("/customer/{id}")
|
||||
public String assignMovie(@PathVariable("id") Long id) {
|
||||
|
||||
String username = null;
|
||||
|
||||
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
|
||||
if (principal instanceof UserDetails) {
|
||||
username = ((UserDetails)principal). getUsername();
|
||||
} else {
|
||||
username = principal. toString();
|
||||
}
|
||||
|
||||
|
||||
movieService.assignMovie(customerService.findByLogin(username).getId(), id);
|
||||
return "redirect:/movies";
|
||||
}
|
||||
|
||||
@PostMapping("/customer/delete/{id}")
|
||||
public String deleteMovieCustomer(@PathVariable("id") Long id) {
|
||||
|
||||
String username = null;
|
||||
|
||||
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
|
||||
if (principal instanceof UserDetails) {
|
||||
username = ((UserDetails)principal). getUsername();
|
||||
} else {
|
||||
username = principal. toString();
|
||||
}
|
||||
|
||||
movieService.deleteMovieCustomer(id, customerService.findByLogin(username).getId());
|
||||
return "redirect:/customer/movies";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -162,12 +162,15 @@ public class MovieService
|
||||
|
||||
specificMovie.getGenre().getMovies().remove(specificMovie);
|
||||
|
||||
movieRepository.delete(specificMovie);
|
||||
final List<Customer> customers = customerRepository.findAll();
|
||||
|
||||
customers.forEach(customer -> {
|
||||
customer.getMovies().remove(specificMovie);
|
||||
});
|
||||
|
||||
movieRepository.delete(specificMovie);
|
||||
|
||||
return specificMovie;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package ru.ulstu.is.sbapp;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class PasswordEncoderConfiguration {
|
||||
@Bean
|
||||
public PasswordEncoder createPasswordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
53
src/main/java/ru/ulstu/is/sbapp/SecurityConfiguration.java
Normal file
53
src/main/java/ru/ulstu/is/sbapp/SecurityConfiguration.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package ru.ulstu.is.sbapp;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
private static final String LOGIN_URL = "/Login";
|
||||
private static final String SIGNUP_URL = "/customer";
|
||||
private final CustomerService customerService;
|
||||
|
||||
public SecurityConfiguration(CustomerService customerService) {
|
||||
this.customerService = customerService;
|
||||
}
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.headers().frameOptions().sameOrigin().and()
|
||||
.cors().and()
|
||||
.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers(SIGNUP_URL).permitAll()
|
||||
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage(LOGIN_URL).permitAll()
|
||||
.and()
|
||||
.logout().permitAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(customerService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) {
|
||||
web.ignoring()
|
||||
.antMatchers("/css/**")
|
||||
.antMatchers("/js/**")
|
||||
.antMatchers("/templates/**")
|
||||
.antMatchers("/webjars/**");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.ulstu.is.sbapp.Utilities;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class CookiesManagement {
|
||||
|
||||
public String GetUserID(HttpServletRequest request)
|
||||
{
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if ("userID".equals(cookie.getName())) {
|
||||
return cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,7 @@ public class ValidationException extends RuntimeException {
|
||||
public ValidationException(Set<String> errors) {
|
||||
super(String.join("\n", errors));
|
||||
}
|
||||
public <T> ValidationException(String error) {
|
||||
super(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,17 @@ package ru.ulstu.is.sbapp;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
public static final String REST_API = "/api";
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
WebMvcConfigurer.super.addViewControllers(registry);
|
||||
registry.addViewController("Login");
|
||||
}
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedMethods("*");
|
||||
|
||||
13
src/main/resources/templates/Error.html
Normal file
13
src/main/resources/templates/Error.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div><span th:text="${error}"></span></div>
|
||||
<a href="/">Return to registration</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
81
src/main/resources/templates/Filmpage.html
Normal file
81
src/main/resources/templates/Filmpage.html
Normal file
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex;">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
|
||||
<main style="display: flex; flex: 1; gap: 100px;">
|
||||
<div class="flex-container" style="display: inline-flex; flex: 1; flex-wrap: wrap; gap: 40px;">
|
||||
<div class="flex-item1 align-self-center" style="flex: 1;">
|
||||
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" width="400px" height="600px"/>
|
||||
</div>
|
||||
<div id="movieCard" th:attr="data-movie-id=${movie.getID()}"class="flex-container align-self-center" style="flex: 3;">
|
||||
<div class="flex-item1 text-light" style="font-size: 50px;"><a th:text="${movie.title}"></a></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Average score: <span th:text="${movie.score}"></span></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Length: <span th:text="${movie.length}"></span></div>
|
||||
<div class="flex-item3 text-light" style="font-size: 35px;">Genre: <span th:text="${movie.genreName}"></span></div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modal">Edit Movie</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<div id="modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close" onclick="handleModalClose()">×</span>
|
||||
<h2>Edit Movie</h2>
|
||||
<div class="form-group">
|
||||
<label>Title:</label>
|
||||
<input type="text" class="form-control" name="title" th:value="${movie.title}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Score:</label>
|
||||
<input type="text" class="form-control" name="score" th:value="${movie.score}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Length:</label>
|
||||
<input type="text" class="form-control" name="length" th:value="${movie.length}"/>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" onclick="handleModalClose()">Close</button>
|
||||
<button class="btn btn-primary" onclick="handleModalSubmit()">Save Changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
function handleModalClose()
|
||||
{
|
||||
const modalElement = document.getElementById('modal');
|
||||
console.log("html modals sucks");
|
||||
// Use Bootstrap's Modal API to close the modal
|
||||
const modal = new bootstrap.Modal(modalElement);
|
||||
modal.hide();
|
||||
}
|
||||
function handleModalSubmit() {
|
||||
var titleInput = document.getElementsByName("title")[0];
|
||||
var scoreInput = document.getElementsByName("score")[0];
|
||||
var lengthInput = document.getElementsByName("length")[0];
|
||||
|
||||
var modalData = {
|
||||
title: titleInput.value,
|
||||
score: scoreInput.value,
|
||||
length: lengthInput.value
|
||||
};
|
||||
|
||||
const movieId = document.getElementById('movieCard').getAttribute('data-movie-id');
|
||||
console.log(movieId);
|
||||
fetch(`/movies/movie/update/${movieId}?title=${modalData["title"]}&length=${modalData["length"]}&score=${modalData["score"]}`,{
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
window.location.href = "/movies";
|
||||
location.reload();
|
||||
}
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
37
src/main/resources/templates/Librarypage.html
Normal file
37
src/main/resources/templates/Librarypage.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
|
||||
|
||||
<div class="flex-container min-vh-100" style="display: flex; margin-left: 20px; margin-top: 50px">
|
||||
|
||||
<th:block th:if="${not #lists.isEmpty(movies)}">
|
||||
<div style="flex-direction: row; display: flex; flex-wrap: wrap; gap: 30px">
|
||||
<th:block th:each="movie : ${movies}">
|
||||
<div className="flex-containerB" style="flex-direction: column; display: flex; width: 250px; height: 350px; gap:40px; align-items:center; color:aliceblue">
|
||||
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
|
||||
<h3 th:text="${movie.title}"></h3>
|
||||
<form th:action="@{/movies/customer/delete/{movieId}(movieId=${movie.getID()})}" method="post">
|
||||
<button type="submit">Remove</button>
|
||||
</form>
|
||||
</div>
|
||||
</th:block>
|
||||
</div>
|
||||
</th:block>
|
||||
<h1 th:unless="${not #lists.isEmpty(movies)}" style="color: white">No movies available</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
41
src/main/resources/templates/Login.html
Normal file
41
src/main/resources/templates/Login.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
|
||||
User isn't found or password isn't correct
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
|
||||
Successful logout
|
||||
</div>
|
||||
<div th:if="${param.created}" class="alert alert-success margin-bottom">
|
||||
User '<span th:text="${param.created}"></span>' was successfully created
|
||||
</div>
|
||||
<div class="flex-container" style="flex-direction: column; display: flex; ">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex; align-items: center; justify-content: center; gap: 20px;">
|
||||
<form th:action="@{/Login}" method="post" class="container-padding">
|
||||
<div class="mb-3">
|
||||
<input type="text" name="username" id="username" class="form-control"
|
||||
placeholder="Login" required="true" autofocus="true"/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Password" required="true"/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success button-fixed" >Login</button>
|
||||
<a class="btn btn-primary button-fixed" href="/customer">Registration</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
52
src/main/resources/templates/Mainpage.html
Normal file
52
src/main/resources/templates/Mainpage.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
|
||||
|
||||
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px;">
|
||||
|
||||
<div th:if="${not #lists.isEmpty(movies)}" style="flex-direction: row; display: flex; flex-wrap: wrap; justify-content: space-between;">
|
||||
<div th:each="movie : ${movies}" style="margin-bottom: 20px;">
|
||||
<div className="flex-containerB" style="flex-direction: column; display: flex; width: 250px; height: 350px; gap:40px; align-items:center;">
|
||||
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
|
||||
<h3><a th:href="@{/movies/movie/{movieId}(movieId=${movie.getID()})}"
|
||||
th:text="${movie.title}" style="text-decoration: none; color: white;"></a></h3>
|
||||
<button type="btn btn-primary" th:attr="data-movie-id=${movie.getID()}" onclick="handleAcquireMovie(event)">Acquire</button>
|
||||
<button type="btn btn-primary" th:attr="data-movie-id=${movie.getID()}" onclick="handleDeleteMovie(event)">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:unless="${not #lists.isEmpty(movies)}" style="color: white;">No movies available</h1>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script th:inline="javascript">
|
||||
|
||||
function handleAcquireMovie(movieId) {
|
||||
var movieId = event.target.getAttribute("data-movie-id");
|
||||
var url = "/movies/customer/" + movieId;
|
||||
fetch(url,{
|
||||
method: "POST",
|
||||
}) ;
|
||||
}
|
||||
|
||||
function handleDeleteMovie(movieId){
|
||||
var movieId = event.target.getAttribute("data-movie-id");
|
||||
var url = "/movies/movie/delete/" + movieId;
|
||||
fetch(url,{
|
||||
method: "POST",
|
||||
}) ;
|
||||
window.location.href = "/movies"
|
||||
location.reload();
|
||||
}
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
44
src/main/resources/templates/Registration.html
Normal file
44
src/main/resources/templates/Registration.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
||||
<div class="flex-container" style="flex-direction: column; display: flex;">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
|
||||
<main style="display: flex; flex: 1;">
|
||||
<aside class="flex-item2" style="flex: 2;"></aside>
|
||||
<div class="flex-item3 align-self-center" style="flex: 3;"><img src="https://i.pinimg.com/736x/57/ee/6a/57ee6a23a455b12eff3aa13d63f104cd.jpg" alt="cover" width="100%" height="600px"/></div>
|
||||
<section class="flex-container align-self-center" style="height: 660px; flex: 4; background-color: #ffd79d; flex-direction: column; display: flex;">
|
||||
<form action="#" th:action="@{/customer}" th:object="${customerDTO}" method="post">
|
||||
<section class="flex-itemR1" style="color: #320D3E; font-size: 50px; font-weight: bold; padding-left: 30px; padding-top: 10px;">SIGN UP</section>
|
||||
<section class="flex-itemR2" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
|
||||
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">USERNAME</label>
|
||||
</section>
|
||||
<section class="flex-itemR3" style="display: flex; width: 320px; padding-left: 30px;">
|
||||
<input class="form-control" id="inputUsername" type="string" name="username" placeholder="Enter username" th:field="${customerDTO.username}" required="true" autofocus="true" maxlength="64"/>
|
||||
</section>
|
||||
<section class="flex-itemR6" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
|
||||
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">PASSWORD</label>
|
||||
</section>
|
||||
<section class="flex-itemR7" style="display: flex; width: 320px; padding-left: 30px;">
|
||||
<input class="form-control" id="inputPassword" type="password" name="password" placeholder="Enter password" th:field="${customerDTO.password}" required="true" minlength="6" maxlength="64"/>
|
||||
</section>
|
||||
<section class="flex-itemR8" style="display: flex; width: 320px; padding-left: 30px;">
|
||||
<select id="genre-select" th:field="${customerDTO.role}" required="true">
|
||||
<option value="USER">USER</option>
|
||||
<option value="ADMIN">ADMIN</option>
|
||||
</select>
|
||||
</section>
|
||||
<button class="btn btn-primary" type="submit" id="register" style="font-size: 20px; margin-left: 30px; margin-top: 15px; width: 150px; background-color: #320D3E; color: white; font-weight: bold;">Register</button>
|
||||
<a href="/Login">Sign in</a>
|
||||
</form>
|
||||
</section>
|
||||
<aside class="flex-item5" style="flex: 2;"></aside>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</html>
|
||||
56
src/main/resources/templates/Searchpage.html
Normal file
56
src/main/resources/templates/Searchpage.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
<div class="flex-container" style="flex-direction: column; display: flex;">
|
||||
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex; flex: 1; align-items: center; justify-content: flex-start; margin-top: 20px">
|
||||
<div>
|
||||
<select id="genre-select">
|
||||
<option value="all">All Genres</option>
|
||||
<option th:each="genre : ${genres}" th:value="${genre.name}" th:text="${genre.name}"></option>
|
||||
</select>
|
||||
<button type="button" onclick="handleSearch()">Search</button>
|
||||
</div>
|
||||
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px">
|
||||
<div style="flex-direction: row; display: flex; flex-wrap: wrap; gap: 30px">
|
||||
<div th:if="${not #lists.isEmpty(movies)}" th:each="movie : ${movies}" style="margin-bottom: 20px;">
|
||||
<div className="flex-containerB" style="flex-direction: column; display: flex; width: 250px; height: 350px; gap:40px; align-items:center; color:aliceblue">
|
||||
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
|
||||
<h3><a th:href="@{/movies/movie/{movieId}(movieId=${movie.getID()})}"
|
||||
th:text="${movie.title}" style="text-decoration: none; color: white;"></a></h3>
|
||||
</div>
|
||||
</div>
|
||||
<h1 th:if="${#lists.isEmpty(movies)}" style="color: white">No movies found</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script>
|
||||
window.onload = function()
|
||||
{
|
||||
var storedOptionValue = localStorage.getItem('genre');
|
||||
if(storedOptionValue !== null)
|
||||
{
|
||||
var selectElement = document.getElementById('genre-select');
|
||||
selectElement.value = storedOptionValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
const genreSelect = document.getElementById("genre-select");
|
||||
const selectedGenre = genreSelect.value;
|
||||
localStorage.setItem('genre',selectedGenre);
|
||||
window.location.href = `/movies/${selectedGenre}`;
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
51
src/main/resources/templates/Template.html
Normal file
51
src/main/resources/templates/Template.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>I'M TIRED OF IP</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<div style="background-image: url('https://img.freepik.com/premium-vector/grainy-gradient-background-using-different-colors_606954-9.jpg');">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark">
|
||||
<ul class="navbar-nav mr-auto" sec:authorize="isAuthenticated()">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/movies" th:classappend="${#strings.equals(activeLink, '/movies')} ? 'active' : ''">
|
||||
Main Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/movies/null" th:classappend="${#strings.equals(activeLink, '/genre')} ? 'active' : ''">
|
||||
Search Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" th:href="@{/customer/movies}">
|
||||
Library Page
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/customer" th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">
|
||||
Registration Page
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div layout:fragment="content">
|
||||
|
||||
</div>
|
||||
<footer class="flex-item6">
|
||||
<div class="text-center text-light p-2" style="font-size: 30px; font-weight: bold;">
|
||||
@2022 Copyright: BLSJY.com
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<th:block layout:fragment="scripts">
|
||||
</th:block>
|
||||
</html>
|
||||
19
src/main/resources/templates/index.html
Normal file
19
src/main/resources/templates/index.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<div layout:fragment="content">
|
||||
|
||||
|
||||
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px;">
|
||||
|
||||
|
||||
<h1 style="color: white;">THE BEST ONLINE-CINEMA</h1>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user