├── Chapter01 ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── com │ │ │ └── packt │ │ │ └── cardatabase │ │ │ └── CardatabaseApplication.java │ └── test │ │ └── java │ │ └── com │ │ └── packt │ │ └── cardatabase │ │ └── CardatabaseApplicationTests.java ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.properties │ │ └── maven-wrapper.jar ├── .gitignore ├── pom.xml └── mvnw.cmd ├── Chapter11 ├── src │ ├── constants.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── App.css │ ├── App.js │ ├── components │ │ ├── AddCar.js │ │ ├── EditCar.js │ │ └── Carlist.js │ ├── logo.svg │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── Chapter12 ├── src │ ├── constants.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── App.css │ ├── App.js │ ├── components │ │ ├── AddCar.js │ │ ├── EditCar.js │ │ └── Carlist.js │ ├── logo.svg │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── Chapter13 ├── src │ ├── constants.js │ ├── index.css │ ├── AddCar.test.js │ ├── index.js │ ├── App.test.js │ ├── App.css │ ├── App.js │ ├── __snapshots__ │ │ └── App.test.js.snap │ ├── components │ │ ├── AddCar.js │ │ ├── EditCar.js │ │ └── Carlist.js │ ├── logo.svg │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── Chapter14 ├── src │ ├── constants.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── App.css │ ├── App.js │ ├── components │ │ ├── Login.js │ │ ├── AddCar.js │ │ ├── EditCar.js │ │ └── Carlist.js │ ├── logo.svg │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── Chapter03 ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.properties │ │ └── maven-wrapper.jar ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── packt │ │ │ │ └── cardatabase │ │ │ │ ├── domain │ │ │ │ ├── OwnerRepository.java │ │ │ │ ├── CarRepository.java │ │ │ │ ├── Owner.java │ │ │ │ └── Car.java │ │ │ │ └── CardatabaseApplication.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── packt │ │ └── cardatabase │ │ └── CardatabaseApplicationTests.java ├── pom.xml └── mvnw.cmd ├── Chapter04 ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.properties │ │ └── maven-wrapper.jar ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── packt │ │ │ │ └── cardatabase │ │ │ │ ├── domain │ │ │ │ ├── OwnerRepository.java │ │ │ │ ├── CarRepository.java │ │ │ │ ├── Owner.java │ │ │ │ └── Car.java │ │ │ │ ├── web │ │ │ │ └── CarController.java │ │ │ │ └── CardatabaseApplication.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── packt │ │ └── cardatabase │ │ └── CardatabaseApplicationTests.java ├── .gitignore ├── pom.xml └── mvnw.cmd ├── Chapter05 ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.properties │ │ └── maven-wrapper.jar ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── packt │ │ │ │ └── cardatabase │ │ │ │ ├── domain │ │ │ │ ├── OwnerRepository.java │ │ │ │ ├── UserRepository.java │ │ │ │ ├── AccountCredentials.java │ │ │ │ ├── CarRepository.java │ │ │ │ ├── User.java │ │ │ │ ├── Owner.java │ │ │ │ └── Car.java │ │ │ │ ├── web │ │ │ │ └── CarController.java │ │ │ │ ├── AuthenticationFilter.java │ │ │ │ ├── service │ │ │ │ ├── UserDetailServiceImpl.java │ │ │ │ └── AuthenticationService.java │ │ │ │ ├── CardatabaseApplication.java │ │ │ │ ├── LoginFilter.java │ │ │ │ └── SecurityConfig.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── packt │ │ └── cardatabase │ │ ├── CardatabaseApplicationTests.java │ │ ├── CarRepositoryTest.java │ │ └── CarRestTest.java ├── .gitignore ├── pom.xml └── mvnw.cmd ├── Chapter08 ├── Readme.md ├── weatherapp │ ├── App.js │ └── WeatherApp.js └── restgithub │ └── App.js ├── Chapter10 ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── src │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── App.js │ ├── App.css │ ├── logo.svg │ └── serviceWorker.js ├── .gitignore ├── package.json └── README.md ├── Chapter09 ├── ReactRouter │ ├── Home.js │ ├── Contact.js │ └── App.js ├── ShoppingList │ ├── App.js │ └── AddItem.js └── ReactTable │ └── App.js ├── Chapter15 └── Dockerfile ├── Chapter06 └── README.md ├── Chapter07 ├── MyList.js └── MyForm.js ├── LICENSE └── Chapter02 └── Readme.md /Chapter01/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter11/src/constants.js: -------------------------------------------------------------------------------- 1 | export const SERVER_URL = 'http://localhost:8080/' -------------------------------------------------------------------------------- /Chapter12/src/constants.js: -------------------------------------------------------------------------------- 1 | export const SERVER_URL = 'http://localhost:8080/' -------------------------------------------------------------------------------- /Chapter13/src/constants.js: -------------------------------------------------------------------------------- 1 | export const SERVER_URL = 'http://localhost:8080/' -------------------------------------------------------------------------------- /Chapter14/src/constants.js: -------------------------------------------------------------------------------- 1 | export const SERVER_URL = 'http://localhost:8080/' -------------------------------------------------------------------------------- /Chapter01/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter03/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter04/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter05/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip 2 | -------------------------------------------------------------------------------- /Chapter08/Readme.md: -------------------------------------------------------------------------------- 1 | Create React app: 2 | create-react-app weatherApp 3 | 4 | Replace App.js file with the file from Github 5 | 6 | Start your app: 7 | npm start -------------------------------------------------------------------------------- /Chapter10/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter10/public/favicon.ico -------------------------------------------------------------------------------- /Chapter11/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter11/public/favicon.ico -------------------------------------------------------------------------------- /Chapter12/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter12/public/favicon.ico -------------------------------------------------------------------------------- /Chapter13/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter13/public/favicon.ico -------------------------------------------------------------------------------- /Chapter14/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter14/public/favicon.ico -------------------------------------------------------------------------------- /Chapter01/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter01/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter03/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter03/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter04/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter04/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter05/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Full-Stack-Development-with-Spring-Boot-2-and-React-Second-Edition/HEAD/Chapter05/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /Chapter09/ReactRouter/Home.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Home = () => { 4 | return ( 5 |
6 |

Home.js

7 |
8 | ); 9 | } 10 | 11 | export default Home; -------------------------------------------------------------------------------- /Chapter09/ReactRouter/Contact.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Contact = () => { 4 | return ( 5 |
6 |

Contact.js

7 |
8 | ); 9 | } 10 | 11 | export default Contact; -------------------------------------------------------------------------------- /Chapter15/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | VOLUME /tmp 3 | EXPOSE 8080 4 | ARG JAR_FILE 5 | COPY target/cardatabase-0.0.1-SNAPSHOT.jar app.jar 6 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] -------------------------------------------------------------------------------- /Chapter03/src/main/java/com/packt/cardatabase/domain/OwnerRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface OwnerRepository extends CrudRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/domain/OwnerRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface OwnerRepository extends CrudRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/OwnerRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface OwnerRepository extends CrudRepository { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /Chapter08/weatherapp/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import WeatherApp from './WeatherApp'; 4 | 5 | function App() { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /Chapter10/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /Chapter11/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /Chapter12/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /Chapter14/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface UserRepository extends CrudRepository { 8 | User findByUsername(String username); 9 | } -------------------------------------------------------------------------------- /Chapter03/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mariadb://localhost:3306/cardb 2 | spring.datasource.username=YOUR_DB_USERNAME 3 | spring.datasource.password=YOUR_DB_PASSWORD 4 | spring.datasource.driver-class-name=org.mariadb.jdbc.Driver 5 | 6 | spring.jpa.generate-ddl=true 7 | spring.jpa.hibernate.ddl-auto=create-drop 8 | 9 | spring.jpa.show-sql=true 10 | -------------------------------------------------------------------------------- /Chapter03/src/main/java/com/packt/cardatabase/domain/CarRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | public interface CarRepository extends CrudRepository { 8 | // Fetch cars by brand and sort by year 9 | List findByBrandOrderByYearAsc(String brand); 10 | } 11 | -------------------------------------------------------------------------------- /Chapter01/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /Chapter04/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /Chapter05/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /Chapter10/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter11/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter12/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter13/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter14/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /Chapter05/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mariadb://localhost:3306/cardb 2 | spring.datasource.username=root 3 | spring.datasource.password=YOUR_DB_PASSWORD 4 | spring.datasource.driver-class-name=org.mariadb.jdbc.Driver 5 | 6 | spring.jpa.generate-ddl=true 7 | spring.jpa.hibernate.ddl-auto=create-drop 8 | 9 | spring.jpa.show-sql=true 10 | 11 | spring.data.rest.basePath=/api 12 | -------------------------------------------------------------------------------- /Chapter04/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mariadb://localhost:3306/cardb 2 | spring.datasource.username=root 3 | spring.datasource.password=YOUR_MARIADB_ROOT_PASSWORD 4 | spring.datasource.driver-class-name=org.mariadb.jdbc.Driver 5 | 6 | spring.jpa.generate-ddl=true 7 | spring.jpa.hibernate.ddl-auto=create-drop 8 | 9 | spring.jpa.show-sql=true 10 | 11 | spring.data.rest.basePath=/api 12 | -------------------------------------------------------------------------------- /Chapter10/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter11/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter12/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter13/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter14/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Chapter01/src/main/java/com/packt/cardatabase/CardatabaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CardatabaseApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CardatabaseApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chapter10/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter12/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter13/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter14/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /Chapter06/README.md: -------------------------------------------------------------------------------- 1 | ## Commands used in chapter 6 2 | 3 | These commands prints out the version of npm and node 4 | 5 | ``` 6 | npm -v 7 | node -v 8 | ``` 9 | 10 | This command creates React app named myapp: 11 | 12 | ``` 13 | npx create-react-app myapp 14 | ``` 15 | 16 | This command starts React app (execute in the project root folder) 17 | 18 | ``` 19 | npm start 20 | ``` 21 | 22 | OR if you are using yarn 23 | 24 | ``` 25 | yarn star 26 | ``` 27 | -------------------------------------------------------------------------------- /Chapter13/src/AddCar.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AddCar from './components/AddCar'; 3 | import Enzyme, { shallow } from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | 6 | Enzyme.configure({ adapter: new Adapter() }); 7 | 8 | describe('', () => { 9 | it('renders five components', () => { 10 | const wrapper = shallow(); 11 | expect(wrapper.find('TextField')).toHaveLength(5); 12 | }); 13 | }); -------------------------------------------------------------------------------- /Chapter01/src/test/java/com/packt/cardatabase/CardatabaseApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class CardatabaseApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter03/src/test/java/com/packt/cardatabase/CardatabaseApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class CardatabaseApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter04/src/test/java/com/packt/cardatabase/CardatabaseApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class CardatabaseApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Chapter07/MyList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const MyList = () => { 4 | const data = [{brand: 'Ford', model: 'Mustang'}, 5 | {brand:'VW', model: 'Beetle'}, {brand: 'Tesla', model: 'Model S'}]; 6 | 7 | const tableRows = data.map((item, index) => 8 | {item.brand}{item.model} 9 | ); 10 | 11 | return ( 12 |
13 | {tableRows}
14 |
15 | ); 16 | }; 17 | 18 | export default MyList; -------------------------------------------------------------------------------- /Chapter10/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Chapter11/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Chapter12/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Chapter13/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Chapter14/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /Chapter13/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import AddCar from './components/AddCar'; 5 | import renderer from 'react-test-renderer' 6 | 7 | it('renders without crashing', () => { 8 | const div = document.createElement('div'); 9 | ReactDOM.render(, div); 10 | ReactDOM.unmountComponentAtNode(div); 11 | }); 12 | 13 | it('renders a snapshot', () => { 14 | const tree = renderer.create().toJSON(); 15 | expect(tree).toMatchSnapshot(); 16 | }); -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/AccountCredentials.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | public class AccountCredentials { 4 | private String username; 5 | private String password; 6 | 7 | public String getUsername() { 8 | return username; 9 | } 10 | public void setUsername(String username) { 11 | this.username = username; 12 | } 13 | public String getPassword() { 14 | return password; 15 | } 16 | public void setPassword(String password) { 17 | this.password = password; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | 7 | function App() { 8 | return ( 9 |
10 | 11 | 12 | 13 | CarList 14 | 15 | 16 | 17 |
18 | ); 19 | } 20 | 21 | export default App; -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/domain/CarRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.data.repository.query.Param; 7 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 8 | 9 | @RepositoryRestResource 10 | public interface CarRepository extends CrudRepository { 11 | // Fetch cars by brand 12 | List findByBrand(@Param("brand") String brand); 13 | 14 | // Fetch cars by color 15 | List findByColor(@Param("color") String color); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/CarRepository.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.data.repository.query.Param; 7 | import org.springframework.data.rest.core.annotation.RepositoryRestResource; 8 | 9 | @RepositoryRestResource 10 | public interface CarRepository extends CrudRepository { 11 | // Fetch cars by brand 12 | List findByBrand(@Param("brand") String brand); 13 | 14 | // Fetch cars by color 15 | List findByColor(@Param("color") String color); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/web/CarController.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import com.packt.cardatabase.domain.Car; 8 | import com.packt.cardatabase.domain.CarRepository; 9 | 10 | @RestController 11 | public class CarController { 12 | @Autowired 13 | private CarRepository repository; 14 | 15 | @RequestMapping("/cars") 16 | public Iterable getCars() { 17 | return repository.findAll(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/web/CarController.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.web; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import com.packt.cardatabase.domain.Car; 8 | import com.packt.cardatabase.domain.CarRepository; 9 | 10 | @RestController 11 | public class CarController { 12 | @Autowired 13 | private CarRepository repository; 14 | 15 | @RequestMapping("/cars") 16 | public Iterable getCars() { 17 | return repository.findAll(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter11/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter12/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter13/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter14/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .App-header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .App-link { 23 | color: #61dafb; 24 | } 25 | 26 | @keyframes App-logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chapter14/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import Login from './components/Login'; 7 | 8 | function App() { 9 | return ( 10 |
11 | 12 | 13 | 14 | CarList 15 | 16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /Chapter11/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import Carlist from './components/Carlist'; 7 | 8 | function App() { 9 | return ( 10 |
11 | 12 | 13 | 14 | CarList 15 | 16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /Chapter12/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import Carlist from './components/Carlist'; 7 | 8 | function App() { 9 | return ( 10 |
11 | 12 | 13 | 14 | CarList 15 | 16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /Chapter13/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import Carlist from './components/Carlist'; 7 | 8 | function App() { 9 | return ( 10 |
11 | 12 | 13 | 14 | CarList 15 | 16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /Chapter05/src/test/java/com/packt/cardatabase/CardatabaseApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import com.packt.cardatabase.web.CarController; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class CardatabaseApplicationTests { 16 | @Autowired 17 | private CarController controller; 18 | 19 | @Test 20 | public void contextLoads() { 21 | assertThat(controller).isNotNull(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Chapter10/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carfront", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.3", 7 | "react": "^16.8.6", 8 | "react-dom": "^16.8.6", 9 | "react-scripts": "3.0.1" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test", 15 | "eject": "react-scripts eject" 16 | }, 17 | "eslintConfig": { 18 | "extends": "react-app" 19 | }, 20 | "browserslist": { 21 | "production": [ 22 | ">0.2%", 23 | "not dead", 24 | "not op_mini all" 25 | ], 26 | "development": [ 27 | "last 1 chrome version", 28 | "last 1 firefox version", 29 | "last 1 safari version" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter09/ReactRouter/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import { BrowserRouter, Switch, Route, Link } from 'react-router-dom' 4 | import Contact from './Contact'; 5 | import Home from './Home'; 6 | 7 | function App() { 8 | return ( 9 |
10 | 11 |
12 | Home{' '} 13 | Contact{' '} 14 | Links{' '} 15 | 16 | 17 | 18 |

Links

} /> 19 |

Page not found

} /> 20 |
21 |
22 |
23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /Chapter11/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carfront", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.3", 7 | "react": "^16.8.6", 8 | "react-csv": "^1.1.1", 9 | "react-dom": "^16.8.6", 10 | "react-scripts": "3.0.1", 11 | "react-table": "^6.10.0", 12 | "react-toastify": "^5.1.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter12/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carfront", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.3", 7 | "react": "^16.8.6", 8 | "react-csv": "^1.1.1", 9 | "react-dom": "^16.8.6", 10 | "react-scripts": "3.0.1", 11 | "react-table": "^6.10.0", 12 | "react-toastify": "^5.1.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter14/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carfront", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.3", 7 | "react": "^16.8.6", 8 | "react-csv": "^1.1.1", 9 | "react-dom": "^16.8.6", 10 | "react-scripts": "3.0.1", 11 | "react-table": "^6.10.0", 12 | "react-toastify": "^5.1.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter13/src/__snapshots__/App.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renders a snapshot 1`] = ` 4 |
5 | 37 |
38 | `; 39 | -------------------------------------------------------------------------------- /Chapter08/restgithub/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import './App.css'; 3 | 4 | function App() { 5 | const [data, setData] = useState([]); 6 | const [keyword, setKeyword] = useState(''); 7 | 8 | const fetchData = () => { 9 | const url = `https://api.github.com/search/repositories?q=${keyword}`; 10 | fetch(url) 11 | .then(response => response.json()) 12 | .then(responseData => { 13 | setData(responseData.items); 14 | }); 15 | } 16 | 17 | const handleChange = (e) => { 18 | setKeyword(e.target.value); 19 | } 20 | 21 | const tableRows = data.map((item, index) => 22 | {item.full_name} 23 | {item.html_url}); 24 | 25 | return ( 26 |
27 | 28 | 29 | {tableRows}
30 |
31 | ); 32 | } 33 | 34 | export default App; 35 | -------------------------------------------------------------------------------- /Chapter13/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carfront", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.3", 7 | "react": "^16.8.6", 8 | "react-csv": "^1.1.1", 9 | "react-dom": "^16.8.6", 10 | "react-scripts": "3.0.1", 11 | "react-table": "^6.10.0", 12 | "react-toastify": "^5.1.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": "react-app" 22 | }, 23 | "browserslist": { 24 | "production": [ 25 | ">0.2%", 26 | "not dead", 27 | "not op_mini all" 28 | ], 29 | "development": [ 30 | "last 1 chrome version", 31 | "last 1 firefox version", 32 | "last 1 safari version" 33 | ] 34 | }, 35 | "devDependencies": { 36 | "enzyme": "^3.9.0", 37 | "enzyme-adapter-react-16": "^1.13.0", 38 | "react-test-renderer": "^16.8.6" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Chapter07/MyForm.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | const MyForm = () => { 4 | const [user, setUser] = useState({firstName: '', lastName: '', email: ''}); 5 | 6 | // Save input box value to state when it has been changed 7 | const inputChanged = (event) => { 8 | setUser({...user, [event.target.name]: event.target.value}); 9 | } 10 | 11 | const handleSubmit = (event) => { 12 | alert(`Hello ${user.firstName} ${user.lastName}`); 13 | event.preventDefault(); 14 | } 15 | 16 | return ( 17 |
18 | 19 |
21 | 22 |
24 | 25 |
27 | 28 |
29 | ); 30 | }; 31 | 32 | export default MyForm; -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/AuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.ServletRequest; 8 | import javax.servlet.ServletResponse; 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | import org.springframework.security.core.Authentication; 12 | import org.springframework.security.core.context.SecurityContextHolder; 13 | import org.springframework.web.filter.GenericFilterBean; 14 | 15 | import com.packt.cardatabase.service.AuthenticationService; 16 | 17 | public class AuthenticationFilter extends GenericFilterBean { 18 | 19 | @Override 20 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 21 | throws IOException, ServletException { 22 | Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest)request); 23 | 24 | SecurityContextHolder.getContext().setAuthentication(authentication); 25 | filterChain.doFilter(request, response); 26 | } 27 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter09/ShoppingList/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import AppBar from '@material-ui/core/AppBar'; 4 | import Toolbar from '@material-ui/core/Toolbar'; 5 | import Typography from '@material-ui/core/Typography'; 6 | import AddItem from './AddItem'; 7 | import List from '@material-ui/core/List'; 8 | import ListItem from '@material-ui/core/ListItem'; 9 | import ListItemText from '@material-ui/core/ListItemText'; 10 | 11 | function App() { 12 | const [items, setItems] = React.useState([]); 13 | 14 | const addItem = (item) => { 15 | setItems([item, ...items]); 16 | } 17 | 18 | const listItems = items.map((item, index) => 19 | 20 | 21 | ); 22 | 23 | return ( 24 |
25 | 26 | 27 | 28 | SHOPPINGLIST 29 | 30 | 31 | 32 | 33 | {listItems} 34 |
35 | ); 36 | } 37 | 38 | export default App; 39 | -------------------------------------------------------------------------------- /Chapter08/weatherapp/WeatherApp.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import './App.css'; 3 | 4 | class WeatherApp extends Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = {temp: 0, desc: '', icon: '', loading: true} 8 | } 9 | 10 | componentDidMount() { 11 | fetch('http://api.openweathermap.org/data/2.5/weather?q=London&units=Metric&APIkey=YOUR_API_KEY') 12 | .then(response => response.json()) 13 | .then(responseData => { 14 | this.setState({ 15 | temp: responseData.main.temp, 16 | desc: responseData.weather[0].description, 17 | icon: responseData.weather[0].icon, 18 | loading: false 19 | }); 20 | }); 21 | } 22 | 23 | render() { 24 | const imgSrc = 'http://openweathermap.org/img/w/' + 25 | this.state.icon + '.png'; 26 | 27 | if (this.state.loading) { 28 | return

Loading

; 29 | } 30 | else { 31 | return ( 32 |
33 |

Temperature: {this.state.temp} °C

34 |

Description: {this.state.desc}

35 | Weather icon 36 |
37 | ); 38 | } 39 | } 40 | } 41 | 42 | export default WeatherApp; -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/service/UserDetailServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.security.core.authority.AuthorityUtils; 5 | import org.springframework.security.core.userdetails.UserDetails; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.packt.cardatabase.domain.User; 11 | import com.packt.cardatabase.domain.UserRepository; 12 | 13 | @Service 14 | public class UserDetailServiceImpl implements UserDetailsService { 15 | @Autowired 16 | private UserRepository repository; 17 | 18 | 19 | @Override 20 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 21 | { 22 | User currentUser = repository.findByUsername(username); 23 | UserDetails user = new org.springframework.security.core.userdetails.User(username, currentUser.getPassword() 24 | , true, true, true, true, AuthorityUtils.createAuthorityList(currentUser.getRole())); 25 | return user; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /Chapter02/Readme.md: -------------------------------------------------------------------------------- 1 | # Code snippets 2 | 3 | ```java 4 | public class Car { 5 | private Owner owner; 6 | 7 | public Car() { 8 | owner = new Owner(); 9 | } 10 | } 11 | ``` 12 | 13 | ```java 14 | public class Car { 15 | private Owner owner; 16 | 17 | public Car(Owner owner) { 18 | this.owner = owner; 19 | } 20 | } 21 | ``` 22 | 23 | ```java 24 | public class Car { 25 | private Owner owner; 26 | 27 | public void setOwner(Owner owner) { 28 | this.owner = owner; 29 | } 30 | } 31 | ``` 32 | 33 | ```java 34 | public class Car { 35 | @Autowired 36 | private Owner owner; 37 | 38 | // continues 39 | } 40 | ``` 41 | 42 | ```java 43 | public class Car { 44 | @Autowired 45 | private CarRepository carRepository; 46 | 47 | // Fetch all cars from db 48 | carRepositoty.findAll(); 49 | //Continues 50 | } 51 | ``` 52 | 53 | ```java 54 | @Configuration 55 | public class ConfigFileResource { 56 | 57 | @Bean(name="configFile") 58 | public File configFile() { 59 | File configFile = new File("configFile.xml"); 60 | return configFile; 61 | } 62 | } 63 | ``` 64 | 65 | ```java 66 | // By bean name 67 | @Resource(name="configFile") 68 | private ConfigFile cFile 69 | 70 | OR 71 | 72 | 73 | // Without name 74 | @Resource 75 | private ConfigFile cFile 76 | ``` 77 | -------------------------------------------------------------------------------- /Chapter05/src/test/java/com/packt/cardatabase/CarRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 9 | import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import com.packt.cardatabase.domain.Car; 13 | import com.packt.cardatabase.domain.CarRepository; 14 | 15 | @RunWith(SpringRunner.class) 16 | @DataJpaTest 17 | public class CarRepositoryTest { 18 | @Autowired 19 | private TestEntityManager entityManager; 20 | 21 | @Autowired 22 | private CarRepository repository; 23 | 24 | @Test 25 | public void saveCar() { 26 | Car car = new Car("Tesla", "Model X", "White", "ABC-1234", 2017, 86000); 27 | entityManager.persistAndFlush(car); 28 | 29 | assertThat(car.getId()).isNotNull(); 30 | } 31 | 32 | @Test 33 | public void deleteCars() { 34 | entityManager.persistAndFlush(new Car("Tesla", "Model X", "White", "ABC-1234", 2017, 86000)); 35 | entityManager.persistAndFlush(new Car("Mini", "Cooper", "Yellow", "BWS-3007", 2015, 24500)); 36 | 37 | repository.deleteAll(); 38 | assertThat(repository.findAll()).isEmpty(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Chapter03/src/main/java/com/packt/cardatabase/CardatabaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | import com.packt.cardatabase.domain.Car; 10 | import com.packt.cardatabase.domain.CarRepository; 11 | import com.packt.cardatabase.domain.Owner; 12 | import com.packt.cardatabase.domain.OwnerRepository; 13 | 14 | @SpringBootApplication 15 | public class CardatabaseApplication { 16 | @Autowired 17 | private CarRepository repository; 18 | 19 | @Autowired 20 | private OwnerRepository orepository; 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(CardatabaseApplication.class, args); 24 | } 25 | 26 | @Bean 27 | CommandLineRunner runner() { 28 | return args -> { 29 | Owner owner1 = new Owner("John" , "Johnson"); 30 | Owner owner2 = new Owner("Mary" , "Robinson"); 31 | orepository.save(owner1); 32 | orepository.save(owner2); 33 | 34 | repository.save(new Car("Ford", "Mustang", "Red", "ADF-1121", 2017, 59000, owner1)); 35 | repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2014, 29000, owner2)); 36 | repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2018, 39000, owner2)); 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/CardatabaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | import com.packt.cardatabase.domain.Car; 10 | import com.packt.cardatabase.domain.CarRepository; 11 | import com.packt.cardatabase.domain.Owner; 12 | import com.packt.cardatabase.domain.OwnerRepository; 13 | 14 | @SpringBootApplication 15 | public class CardatabaseApplication { 16 | @Autowired 17 | private CarRepository repository; 18 | 19 | @Autowired 20 | private OwnerRepository orepository; 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(CardatabaseApplication.class, args); 24 | } 25 | 26 | @Bean 27 | CommandLineRunner runner() { 28 | return args -> { 29 | Owner owner1 = new Owner("John" , "Johnson"); 30 | Owner owner2 = new Owner("Mary" , "Robinson"); 31 | orepository.save(owner1); 32 | orepository.save(owner2); 33 | 34 | repository.save(new Car("Ford", "Mustang", "Red", "ADF-1121", 2017, 59000, owner1)); 35 | repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2014, 29000, owner2)); 36 | repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2018, 39000, owner2)); 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chapter03/src/main/java/com/packt/cardatabase/domain/Owner.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.OneToMany; 11 | 12 | @Entity 13 | public class Owner { 14 | @Id 15 | @GeneratedValue(strategy=GenerationType.AUTO) 16 | private long ownerid; 17 | private String firstname, lastname; 18 | 19 | @OneToMany(cascade = CascadeType.ALL, mappedBy="owner") 20 | private List cars; 21 | 22 | public Owner() {} 23 | 24 | public Owner(String firstname, String lastname) { 25 | super(); 26 | this.firstname = firstname; 27 | this.lastname = lastname; 28 | } 29 | 30 | public List getCars() { 31 | return cars; 32 | } 33 | 34 | public void setCars(List cars) { 35 | this.cars = cars; 36 | } 37 | 38 | public long getOwnerid() { 39 | return ownerid; 40 | } 41 | 42 | public void setOwnerid(long ownerid) { 43 | this.ownerid = ownerid; 44 | } 45 | 46 | public String getFirstname() { 47 | return firstname; 48 | } 49 | 50 | public void setFirstname(String firstname) { 51 | this.firstname = firstname; 52 | } 53 | 54 | public String getLastname() { 55 | return lastname; 56 | } 57 | 58 | public void setLastname(String lastname) { 59 | this.lastname = lastname; 60 | } 61 | 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Chapter05/src/test/java/com/packt/cardatabase/CarRestTest.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 4 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 5 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | import org.springframework.test.web.servlet.MockMvc; 15 | 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | @AutoConfigureMockMvc 19 | public class CarRestTest { 20 | @Autowired 21 | private MockMvc mockMvc; 22 | 23 | @Test 24 | public void testAuthentication() throws Exception { 25 | // Testing authentication with correct credentials 26 | this.mockMvc.perform(post("/login").content("{\"username\":\"admin\", \"password\":\"admin\"}")). 27 | andDo(print()).andExpect(status().isOk()); 28 | 29 | // Testing authentication with wrong credentials 30 | this.mockMvc.perform(post("/login").content("{\"username\":\"admin\", \"password\":\"wrongpwd\"}")). 31 | andDo(print()).andExpect(status().is4xxClientError()); 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Chapter09/ReactTable/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import './App.css'; 3 | import ReactTable from "react-table"; 4 | import 'react-table/react-table.css'; 5 | 6 | function App() { 7 | const [data, setData] = useState([]); 8 | const [keyword, setKeyword] = useState(''); 9 | 10 | const fetchData = () => { 11 | const url = `https://api.github.com/search/repositories?q=${keyword}`; 12 | fetch(url) 13 | .then(response => response.json()) 14 | .then(responseData => { 15 | setData(responseData.items); 16 | }); 17 | } 18 | 19 | const handleChange = (e) => { 20 | setKeyword(e.target.value); 21 | } 22 | 23 | const btnClick = (value) => { 24 | alert(value); 25 | } 26 | 27 | const columns = [{ 28 | Header: 'Name', // Header of the column 29 | accessor: 'full_name' // Value accessor 30 | }, { 31 | Header: 'URL', 32 | accessor: 'html_url', 33 | }, { 34 | Header: 'Owner', 35 | accessor: 'owner.login', 36 | }, { 37 | id: 'button', 38 | sortable: false, 39 | filterable: false, 40 | width: 100, 41 | accessor: 'full_name', 42 | Cell: ({value}) => () 43 | }] 44 | 45 | return ( 46 |
47 | 48 | 49 | 50 |
51 | ); 52 | } 53 | 54 | export default App; 55 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | 9 | @Entity 10 | public class User { 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.IDENTITY) 13 | @Column(nullable = false, updatable = false) 14 | private Long id; 15 | 16 | @Column(nullable = false, unique = true) 17 | private String username; 18 | 19 | @Column(nullable = false) 20 | private String password; 21 | 22 | @Column(nullable = false) 23 | private String role; 24 | 25 | public User() { 26 | } 27 | 28 | public User(String username, String password, String role) { 29 | super(); 30 | this.username = username; 31 | this.password = password; 32 | this.role = role; 33 | } 34 | 35 | public Long getId() { 36 | return id; 37 | } 38 | 39 | public void setId(Long id) { 40 | this.id = id; 41 | } 42 | 43 | public String getUsername() { 44 | return username; 45 | } 46 | 47 | public void setUsername(String username) { 48 | this.username = username; 49 | } 50 | 51 | public String getPassword() { 52 | return password; 53 | } 54 | 55 | public void setPassword(String password) { 56 | this.password = password; 57 | } 58 | 59 | public String getRole() { 60 | return role; 61 | } 62 | 63 | public void setRole(String role) { 64 | this.role = role; 65 | } 66 | } -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/domain/Owner.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.OneToMany; 11 | 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 14 | 15 | @Entity 16 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 17 | public class Owner { 18 | @Id 19 | @GeneratedValue(strategy=GenerationType.AUTO) 20 | private long ownerid; 21 | private String firstname, lastname; 22 | 23 | @OneToMany(cascade = CascadeType.ALL, mappedBy="owner") 24 | @JsonIgnore 25 | private List cars; 26 | 27 | public Owner() {} 28 | 29 | public Owner(String firstname, String lastname) { 30 | super(); 31 | this.firstname = firstname; 32 | this.lastname = lastname; 33 | } 34 | 35 | public List getCars() { 36 | return cars; 37 | } 38 | 39 | public void setCars(List cars) { 40 | this.cars = cars; 41 | } 42 | 43 | public long getOwnerid() { 44 | return ownerid; 45 | } 46 | 47 | public void setOwnerid(long ownerid) { 48 | this.ownerid = ownerid; 49 | } 50 | 51 | public String getFirstname() { 52 | return firstname; 53 | } 54 | 55 | public void setFirstname(String firstname) { 56 | this.firstname = firstname; 57 | } 58 | 59 | public String getLastname() { 60 | return lastname; 61 | } 62 | 63 | public void setLastname(String lastname) { 64 | this.lastname = lastname; 65 | } 66 | 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/Owner.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import java.util.List; 4 | 5 | import javax.persistence.CascadeType; 6 | import javax.persistence.Entity; 7 | import javax.persistence.GeneratedValue; 8 | import javax.persistence.GenerationType; 9 | import javax.persistence.Id; 10 | import javax.persistence.OneToMany; 11 | 12 | import com.fasterxml.jackson.annotation.JsonIgnore; 13 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 14 | 15 | @Entity 16 | @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) 17 | public class Owner { 18 | @Id 19 | @GeneratedValue(strategy=GenerationType.AUTO) 20 | private long ownerid; 21 | private String firstname, lastname; 22 | 23 | @OneToMany(cascade = CascadeType.ALL, mappedBy="owner") 24 | @JsonIgnore 25 | private List cars; 26 | 27 | public Owner() {} 28 | 29 | public Owner(String firstname, String lastname) { 30 | super(); 31 | this.firstname = firstname; 32 | this.lastname = lastname; 33 | } 34 | 35 | public List getCars() { 36 | return cars; 37 | } 38 | 39 | public void setCars(List cars) { 40 | this.cars = cars; 41 | } 42 | 43 | public long getOwnerid() { 44 | return ownerid; 45 | } 46 | 47 | public void setOwnerid(long ownerid) { 48 | this.ownerid = ownerid; 49 | } 50 | 51 | public String getFirstname() { 52 | return firstname; 53 | } 54 | 55 | public void setFirstname(String firstname) { 56 | this.firstname = firstname; 57 | } 58 | 59 | public String getLastname() { 60 | return lastname; 61 | } 62 | 63 | public void setLastname(String lastname) { 64 | this.lastname = lastname; 65 | } 66 | 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /Chapter10/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter11/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter12/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter13/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter14/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 |
27 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/service/AuthenticationService.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.service; 2 | 3 | import io.jsonwebtoken.Jwts; 4 | import io.jsonwebtoken.SignatureAlgorithm; 5 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 6 | import org.springframework.security.core.Authentication; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.util.Date; 11 | 12 | import static java.util.Collections.emptyList; 13 | 14 | public class AuthenticationService { 15 | static final long EXPIRATIONTIME = 864_000_00; // 1 day in milliseconds 16 | static final String SIGNINGKEY = "SecretKey"; 17 | static final String PREFIX = "Bearer"; 18 | 19 | static public void addToken(HttpServletResponse res, String username) { 20 | String JwtToken = Jwts.builder().setSubject(username) 21 | .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME)) 22 | .signWith(SignatureAlgorithm.HS512, SIGNINGKEY) 23 | .compact(); 24 | res.addHeader("Authorization", PREFIX + " " + JwtToken); 25 | res.addHeader("Access-Control-Expose-Headers", "Authorization"); 26 | } 27 | 28 | static public Authentication getAuthentication(HttpServletRequest request) { 29 | String token = request.getHeader("Authorization"); 30 | if (token != null) { 31 | String user = Jwts.parser() 32 | .setSigningKey(SIGNINGKEY) 33 | .parseClaimsJws(token.replace(PREFIX, "")) 34 | .getBody() 35 | .getSubject(); 36 | 37 | if (user != null) 38 | return new UsernamePasswordAuthenticationToken(user, null, emptyList()); 39 | } 40 | return null; 41 | } 42 | } -------------------------------------------------------------------------------- /Chapter01/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.packt 7 | cardatabase 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | cardatabase 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-devtools 36 | runtime 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-maven-plugin 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Chapter14/src/components/Login.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import {SERVER_URL} from '../constants.js'; 3 | import TextField from '@material-ui/core/TextField'; 4 | import Button from '@material-ui/core/Button'; 5 | import Carlist from './Carlist'; 6 | import { ToastContainer, toast } from 'react-toastify'; 7 | import 'react-toastify/dist/ReactToastify.css'; 8 | 9 | const Login = () => { 10 | const [user, setUser] = useState({username: '', password: ''}) 11 | const [isAuthenticated, setAuth] = useState(false); 12 | 13 | const handleChange = (event) => { 14 | setUser({...user, [event.target.name] : event.target.value}) 15 | } 16 | 17 | const login = () => { 18 | fetch(SERVER_URL + 'login', { 19 | method: 'POST', 20 | body: JSON.stringify(user) 21 | }) 22 | .then(res => { 23 | const jwtToken = res.headers.get('Authorization'); 24 | if (jwtToken !== null) { 25 | sessionStorage.setItem("jwt", jwtToken); 26 | setAuth(true); 27 | } 28 | else { 29 | toast.warn("Check your username and password", { 30 | position: toast.POSITION.BOTTOM_LEFT 31 | }) 32 | } 33 | }) 34 | .catch(err => console.error(err)) 35 | } 36 | 37 | if (isAuthenticated === true) { 38 | return () 39 | } 40 | else { 41 | return ( 42 |
43 |
45 |

47 | 51 | 52 |
53 | ); 54 | } 55 | } 56 | 57 | export default Login; -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/CardatabaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | import com.packt.cardatabase.domain.Car; 10 | import com.packt.cardatabase.domain.CarRepository; 11 | import com.packt.cardatabase.domain.Owner; 12 | import com.packt.cardatabase.domain.OwnerRepository; 13 | import com.packt.cardatabase.domain.User; 14 | import com.packt.cardatabase.domain.UserRepository; 15 | 16 | @SpringBootApplication 17 | public class CardatabaseApplication { 18 | @Autowired 19 | private CarRepository repository; 20 | 21 | @Autowired 22 | private OwnerRepository orepository; 23 | 24 | @Autowired 25 | private UserRepository urepository; 26 | 27 | public static void main(String[] args) { 28 | SpringApplication.run(CardatabaseApplication.class, args); 29 | } 30 | 31 | @Bean 32 | CommandLineRunner runner() { 33 | return args -> { 34 | Owner owner1 = new Owner("John" , "Johnson"); 35 | Owner owner2 = new Owner("Mary" , "Robinson"); 36 | orepository.save(owner1); 37 | orepository.save(owner2); 38 | 39 | repository.save(new Car("Ford", "Mustang", "Red", "ADF-1121", 2017, 59000, owner1)); 40 | repository.save(new Car("Nissan", "Leaf", "White", "SSJ-3002", 2014, 29000, owner2)); 41 | repository.save(new Car("Toyota", "Prius", "Silver", "KKO-0212", 2018, 39000, owner2)); 42 | 43 | urepository.save(new User("user", "$2a$04$1.YhMIgNX/8TkCKGFUONWO1waedKhQ5KrnB30fl0Q01QKqmzLf.Zi", "USER")); 44 | urepository.save(new User("admin", "$2a$04$KNLUwOWHVQZVpXyMBNc7JOzbLiBjb9Tk9bP7KNcPI12ICuvzXQQKG", "ADMIN")); 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Chapter09/ShoppingList/AddItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Button from '@material-ui/core/Button'; 3 | import TextField from '@material-ui/core/TextField'; 4 | import Dialog from '@material-ui/core/Dialog'; 5 | import DialogActions from '@material-ui/core/DialogActions'; 6 | import DialogContent from '@material-ui/core/DialogContent'; 7 | import DialogTitle from '@material-ui/core/DialogTitle'; 8 | 9 | const AddItem = (props) => { 10 | const [open, setOpen] = React.useState(false); 11 | const [item, setItem] = React.useState({product: '', amount: ''}); 12 | 13 | const handleOpen = () => { 14 | setOpen(true); 15 | } 16 | 17 | const handleClose = () => { 18 | setOpen(false); 19 | } 20 | 21 | // Handle the change of input field values 22 | const handleChange = (e) => { 23 | setItem({...item, [e.target.name]:e.target.value}) 24 | } 25 | 26 | // Calls addItem function (in props) and pass item state into it. 27 | const addItem = () => { 28 | props.addItem(item); 29 | handleClose(); 30 | } 31 | 32 | return ( 33 |
34 | 37 | 38 | New Item 39 | 40 | 42 | 44 | 45 | 46 | 49 | 52 | 53 | 54 |
55 | ); 56 | } 57 | 58 | export default AddItem; -------------------------------------------------------------------------------- /Chapter03/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.packt 7 | cardatabase 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | cardatabase 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.mariadb.jdbc 38 | mariadb-java-client 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-devtools 43 | runtime 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Chapter03/src/main/java/com/packt/cardatabase/domain/Car.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.JoinColumn; 8 | import javax.persistence.ManyToOne; 9 | import javax.persistence.FetchType; 10 | 11 | @Entity 12 | public class Car { 13 | @Id 14 | @GeneratedValue(strategy=GenerationType.AUTO) 15 | private long id; 16 | private String brand, model, color, registerNumber; 17 | private int year, price; 18 | 19 | @ManyToOne(fetch=FetchType.LAZY) 20 | @JoinColumn(name = "owner") 21 | private Owner owner; 22 | 23 | public Car() {} 24 | 25 | public Car(String brand, String model, String color, String registerNumber, int year, int price, Owner owner) { 26 | super(); 27 | this.brand = brand; 28 | this.model = model; 29 | this.color = color; 30 | this.registerNumber = registerNumber; 31 | this.year = year; 32 | this.price = price; 33 | this.owner = owner; 34 | } 35 | 36 | public Owner getOwner() { 37 | return owner; 38 | } 39 | 40 | public void setOwner(Owner owner) { 41 | this.owner = owner; 42 | } 43 | 44 | public String getBrand() { 45 | return brand; 46 | } 47 | public void setBrand(String brand) { 48 | this.brand = brand; 49 | } 50 | public String getModel() { 51 | return model; 52 | } 53 | public void setModel(String model) { 54 | this.model = model; 55 | } 56 | public String getColor() { 57 | return color; 58 | } 59 | public void setColor(String color) { 60 | this.color = color; 61 | } 62 | public String getRegisterNumber() { 63 | return registerNumber; 64 | } 65 | public void setRegisterNumber(String registerNumber) { 66 | this.registerNumber = registerNumber; 67 | } 68 | public int getYear() { 69 | return year; 70 | } 71 | public void setYear(int year) { 72 | this.year = year; 73 | } 74 | public int getPrice() { 75 | return price; 76 | } 77 | public void setPrice(int price) { 78 | this.price = price; 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Chapter04/src/main/java/com/packt/cardatabase/domain/Car.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | import javax.persistence.JoinColumn; 9 | import javax.persistence.ManyToOne; 10 | 11 | @Entity 12 | public class Car { 13 | @Id 14 | @GeneratedValue(strategy=GenerationType.AUTO) 15 | private long id; 16 | private String brand, model, color, registerNumber; 17 | private int year, price; 18 | 19 | @ManyToOne(fetch = FetchType.LAZY) 20 | @JoinColumn(name = "owner") 21 | private Owner owner; 22 | 23 | public Car() {} 24 | 25 | public Car(String brand, String model, String color, String registerNumber, int year, int price, Owner owner) { 26 | super(); 27 | this.brand = brand; 28 | this.model = model; 29 | this.color = color; 30 | this.registerNumber = registerNumber; 31 | this.year = year; 32 | this.price = price; 33 | this.owner = owner; 34 | } 35 | 36 | public Owner getOwner() { 37 | return owner; 38 | } 39 | 40 | public void setOwner(Owner owner) { 41 | this.owner = owner; 42 | } 43 | 44 | public String getBrand() { 45 | return brand; 46 | } 47 | public void setBrand(String brand) { 48 | this.brand = brand; 49 | } 50 | public String getModel() { 51 | return model; 52 | } 53 | public void setModel(String model) { 54 | this.model = model; 55 | } 56 | public String getColor() { 57 | return color; 58 | } 59 | public void setColor(String color) { 60 | this.color = color; 61 | } 62 | public String getRegisterNumber() { 63 | return registerNumber; 64 | } 65 | public void setRegisterNumber(String registerNumber) { 66 | this.registerNumber = registerNumber; 67 | } 68 | public int getYear() { 69 | return year; 70 | } 71 | public void setYear(int year) { 72 | this.year = year; 73 | } 74 | public int getPrice() { 75 | return price; 76 | } 77 | public void setPrice(int price) { 78 | this.price = price; 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Chapter11/src/components/AddCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | 7 | const AddCar = (props) => { 8 | const [open, setOpen] = useState(false); 9 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 10 | 11 | const handleClickOpen = () => { 12 | setOpen(true); 13 | }; 14 | 15 | const handleClose = () => { 16 | setOpen(false); 17 | }; 18 | 19 | const handleChange = (event) => { 20 | setCar({...car, [event.target.name]: event.target.value}); 21 | } 22 | 23 | // Save car and close modal form 24 | const handleSave = () => { 25 | props.addCar(car); 26 | handleClose(); 27 | } 28 | 29 | return ( 30 |
31 | 32 | 33 | New car 34 | 35 |
37 |
39 |
41 |
43 |
45 |
46 | 47 | 48 | 49 | 50 |
51 |
52 | ); 53 | }; 54 | 55 | export default AddCar; -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/LoginFilter.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import java.io.IOException; 4 | import java.util.Collections; 5 | 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.springframework.security.authentication.AuthenticationManager; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.Authentication; 14 | import org.springframework.security.core.AuthenticationException; 15 | import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; 16 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 17 | 18 | import com.fasterxml.jackson.databind.ObjectMapper; 19 | import com.packt.cardatabase.domain.AccountCredentials; 20 | import com.packt.cardatabase.service.AuthenticationService; 21 | 22 | public class LoginFilter extends AbstractAuthenticationProcessingFilter { 23 | 24 | public LoginFilter(String url, AuthenticationManager authManager) { 25 | super(new AntPathRequestMatcher(url)); 26 | setAuthenticationManager(authManager); 27 | } 28 | 29 | @Override 30 | public Authentication attemptAuthentication( 31 | HttpServletRequest req, HttpServletResponse res) 32 | throws AuthenticationException, IOException, ServletException { 33 | AccountCredentials creds = new ObjectMapper() 34 | .readValue(req.getInputStream(), AccountCredentials.class); 35 | return getAuthenticationManager().authenticate( 36 | new UsernamePasswordAuthenticationToken( 37 | creds.getUsername(), 38 | creds.getPassword(), 39 | Collections.emptyList() 40 | ) 41 | ); 42 | } 43 | 44 | @Override 45 | protected void successfulAuthentication( 46 | HttpServletRequest req, 47 | HttpServletResponse res, FilterChain chain, 48 | Authentication auth) throws IOException, ServletException { 49 | AuthenticationService.addToken(res, auth.getName()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Chapter04/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.packt 7 | cardatabase 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | cardatabase 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-data-rest 39 | 40 | 41 | org.mariadb.jdbc 42 | mariadb-java-client 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-devtools 47 | runtime 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-maven-plugin 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Chapter11/src/components/EditCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | 7 | const EditCar = (props) => { 8 | const [open, setOpen] = useState(false); 9 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 10 | 11 | const handleClickOpen = () => { 12 | setCar({brand: props.car.brand, model: props.car.model, color: props.car.color, 13 | year: props.car.year, fuel: props.car.fuel, price: props.car.price }) 14 | setOpen(true); 15 | } 16 | 17 | const handleClose = () => { 18 | setOpen(false); 19 | }; 20 | 21 | const handleChange = (event) => { 22 | setCar({...car, [event.target.name]: event.target.value}); 23 | } 24 | 25 | // Update car and close modal form 26 | const handleSave = () => { 27 | props.updateCar(car, props.link); 28 | handleClose(); 29 | } 30 | 31 | return ( 32 |
33 | 34 | 35 | Edit car 36 | 37 |
39 |
41 |
43 |
45 |
47 |
48 | 49 | 50 | 51 | 52 |
53 |
54 | ); 55 | }; 56 | 57 | export default EditCar; -------------------------------------------------------------------------------- /Chapter12/src/components/AddCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const AddCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setOpen(true); 15 | }; 16 | 17 | const handleClose = () => { 18 | setOpen(false); 19 | }; 20 | 21 | const handleChange = (event) => { 22 | setCar({...car, [event.target.name]: event.target.value}); 23 | } 24 | 25 | // Save car and close modal form 26 | const handleSave = () => { 27 | props.addCar(car); 28 | handleClose(); 29 | } 30 | 31 | return ( 32 |
33 | 36 | 37 | New car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default AddCar; -------------------------------------------------------------------------------- /Chapter13/src/components/AddCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const AddCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setOpen(true); 15 | }; 16 | 17 | const handleClose = () => { 18 | setOpen(false); 19 | }; 20 | 21 | const handleChange = (event) => { 22 | setCar({...car, [event.target.name]: event.target.value}); 23 | } 24 | 25 | // Save car and close modal form 26 | const handleSave = () => { 27 | props.addCar(car); 28 | handleClose(); 29 | } 30 | 31 | return ( 32 |
33 | 36 | 37 | New car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default AddCar; -------------------------------------------------------------------------------- /Chapter14/src/components/AddCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const AddCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setOpen(true); 15 | }; 16 | 17 | const handleClose = () => { 18 | setOpen(false); 19 | }; 20 | 21 | const handleChange = (event) => { 22 | setCar({...car, [event.target.name]: event.target.value}); 23 | } 24 | 25 | // Save car and close modal form 26 | const handleSave = () => { 27 | props.addCar(car); 28 | handleClose(); 29 | } 30 | 31 | return ( 32 |
33 | 36 | 37 | New car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default AddCar; -------------------------------------------------------------------------------- /Chapter12/src/components/EditCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const EditCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setCar({brand: props.car.brand, model: props.car.model, color: props.car.color, 15 | year: props.car.year, fuel: props.car.fuel, price: props.car.price }) 16 | setOpen(true); 17 | } 18 | 19 | const handleClose = () => { 20 | setOpen(false); 21 | }; 22 | 23 | const handleChange = (event) => { 24 | setCar({...car, [event.target.name]: event.target.value}); 25 | } 26 | 27 | // Update car and close modal form 28 | const handleSave = () => { 29 | props.updateCar(car, props.link); 30 | handleClose(); 31 | } 32 | 33 | return ( 34 |
35 | 36 | 37 | Edit car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default EditCar; -------------------------------------------------------------------------------- /Chapter13/src/components/EditCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const EditCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setCar({brand: props.car.brand, model: props.car.model, color: props.car.color, 15 | year: props.car.year, fuel: props.car.fuel, price: props.car.price }) 16 | setOpen(true); 17 | } 18 | 19 | const handleClose = () => { 20 | setOpen(false); 21 | }; 22 | 23 | const handleChange = (event) => { 24 | setCar({...car, [event.target.name]: event.target.value}); 25 | } 26 | 27 | // Update car and close modal form 28 | const handleSave = () => { 29 | props.updateCar(car, props.link); 30 | handleClose(); 31 | } 32 | 33 | return ( 34 |
35 | 36 | 37 | Edit car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default EditCar; -------------------------------------------------------------------------------- /Chapter14/src/components/EditCar.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog'; 3 | import DialogActions from '@material-ui/core/DialogActions'; 4 | import DialogContent from '@material-ui/core/DialogContent'; 5 | import DialogTitle from '@material-ui/core/DialogTitle'; 6 | import Button from '@material-ui/core/Button'; 7 | import TextField from '@material-ui/core/TextField'; 8 | 9 | const EditCar = (props) => { 10 | const [open, setOpen] = useState(false); 11 | const [car, setCar] = useState({brand: '', model: '', year: '', color: '', price: ''}); 12 | 13 | const handleClickOpen = () => { 14 | setCar({brand: props.car.brand, model: props.car.model, color: props.car.color, 15 | year: props.car.year, fuel: props.car.fuel, price: props.car.price }) 16 | setOpen(true); 17 | } 18 | 19 | const handleClose = () => { 20 | setOpen(false); 21 | }; 22 | 23 | const handleChange = (event) => { 24 | setCar({...car, [event.target.name]: event.target.value}); 25 | } 26 | 27 | // Update car and close modal form 28 | const handleSave = () => { 29 | props.updateCar(car, props.link); 30 | handleClose(); 31 | } 32 | 33 | return ( 34 |
35 | 36 | 37 | Edit car 38 | 39 | 41 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | ); 57 | }; 58 | 59 | export default EditCar; -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/domain/Car.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase.domain; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.FetchType; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | import javax.persistence.JoinColumn; 9 | import javax.persistence.ManyToOne; 10 | 11 | @Entity 12 | public class Car { 13 | @Id 14 | @GeneratedValue(strategy=GenerationType.AUTO) 15 | private long id; 16 | private String brand, model, color, registerNumber; 17 | private int year, price; 18 | 19 | @ManyToOne(fetch = FetchType.LAZY) 20 | @JoinColumn(name = "owner") 21 | private Owner owner; 22 | 23 | public Car() {} 24 | 25 | public Car(String brand, String model, String color, String registerNumber, int year, int price) { 26 | super(); 27 | this.brand = brand; 28 | this.model = model; 29 | this.color = color; 30 | this.registerNumber = registerNumber; 31 | this.year = year; 32 | this.price = price; 33 | } 34 | 35 | public Car(String brand, String model, String color, String registerNumber, int year, int price, Owner owner) { 36 | super(); 37 | this.brand = brand; 38 | this.model = model; 39 | this.color = color; 40 | this.registerNumber = registerNumber; 41 | this.year = year; 42 | this.price = price; 43 | this.owner = owner; 44 | } 45 | 46 | 47 | public long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(long id) { 52 | this.id = id; 53 | } 54 | 55 | public Owner getOwner() { 56 | return owner; 57 | } 58 | 59 | public void setOwner(Owner owner) { 60 | this.owner = owner; 61 | } 62 | 63 | public String getBrand() { 64 | return brand; 65 | } 66 | public void setBrand(String brand) { 67 | this.brand = brand; 68 | } 69 | public String getModel() { 70 | return model; 71 | } 72 | public void setModel(String model) { 73 | this.model = model; 74 | } 75 | public String getColor() { 76 | return color; 77 | } 78 | public void setColor(String color) { 79 | this.color = color; 80 | } 81 | public String getRegisterNumber() { 82 | return registerNumber; 83 | } 84 | public void setRegisterNumber(String registerNumber) { 85 | this.registerNumber = registerNumber; 86 | } 87 | public int getYear() { 88 | return year; 89 | } 90 | public void setYear(int year) { 91 | this.year = year; 92 | } 93 | public int getPrice() { 94 | return price; 95 | } 96 | public void setPrice(int price) { 97 | this.price = price; 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /Chapter10/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter11/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter12/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter13/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter14/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter05/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.packt 7 | cardatabase 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | cardatabase 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.3.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-data-jpa 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-security 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-data-rest 43 | 44 | 45 | org.mariadb.jdbc 46 | mariadb-java-client 47 | 48 | 49 | com.h2database 50 | h2 51 | test 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-devtools 56 | runtime 57 | 58 | 59 | io.jsonwebtoken 60 | jjwt 61 | 0.9.1 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-test 66 | test 67 | 68 | 69 | 70 | 71 | 72 | 73 | org.springframework.boot 74 | spring-boot-maven-plugin 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Chapter05/src/main/java/com/packt/cardatabase/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.packt.cardatabase; 2 | 3 | import java.util.Arrays; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.http.HttpMethod; 9 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 12 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 14 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 15 | import org.springframework.web.cors.CorsConfiguration; 16 | import org.springframework.web.cors.CorsConfigurationSource; 17 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 18 | 19 | import com.packt.cardatabase.service.UserDetailServiceImpl; 20 | 21 | @Configuration 22 | @EnableWebSecurity 23 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 24 | @Autowired 25 | private UserDetailServiceImpl userDetailsService; 26 | 27 | @Override 28 | protected void configure(HttpSecurity http) throws Exception { 29 | http.csrf().disable().cors().and().authorizeRequests() 30 | .antMatchers(HttpMethod.POST, "/login").permitAll() 31 | .anyRequest().authenticated() 32 | .and() 33 | // Filter for the api/login requests 34 | .addFilterBefore(new LoginFilter("/login", authenticationManager()), 35 | UsernamePasswordAuthenticationFilter.class) 36 | // Filter for other requests to check JWT in header 37 | .addFilterBefore(new AuthenticationFilter(), 38 | UsernamePasswordAuthenticationFilter.class); 39 | } 40 | 41 | @Bean 42 | CorsConfigurationSource corsConfigurationSource() { 43 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 44 | CorsConfiguration config = new CorsConfiguration(); 45 | config.setAllowedOrigins(Arrays.asList("*")); 46 | config.setAllowedMethods(Arrays.asList("*")); 47 | config.setAllowedHeaders(Arrays.asList("*")); 48 | config.setAllowCredentials(true); 49 | config.applyPermitDefaultValues(); 50 | 51 | source.registerCorsConfiguration("/**", config); 52 | return source; 53 | } 54 | 55 | @Autowired 56 | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 57 | auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder()); 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /Chapter10/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Chapter11/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Chapter12/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Chapter13/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Chapter14/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /Chapter11/src/components/Carlist.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import {SERVER_URL} from '../constants.js' 3 | import ReactTable from "react-table"; 4 | import 'react-table/react-table.css'; 5 | import { ToastContainer, toast } from 'react-toastify'; 6 | import 'react-toastify/dist/ReactToastify.css'; 7 | import AddCar from './AddCar'; 8 | import EditCar from './EditCar'; 9 | import { CSVLink } from 'react-csv'; 10 | 11 | class Carlist extends Component { 12 | constructor(props) { 13 | super(props); 14 | this.state = { cars: [] }; 15 | } 16 | 17 | componentDidMount() { 18 | this.fetchCars(); 19 | } 20 | 21 | fetchCars = () => { 22 | console.log("FETCH") 23 | fetch(SERVER_URL + 'api/cars') 24 | .then((response) => response.json()) 25 | .then((responseData) => { 26 | this.setState({ 27 | cars: responseData._embedded.cars, 28 | }); 29 | }) 30 | .catch(err => console.error(err)); 31 | } 32 | 33 | // Delete car 34 | onDelClick = (link) => { 35 | if (window.confirm('Are you sure to delete?')) { 36 | fetch(link, {method: 'DELETE'}) 37 | .then(res => { 38 | toast.success("Car deleted", { 39 | position: toast.POSITION.BOTTOM_LEFT 40 | }); 41 | this.fetchCars(); 42 | }) 43 | .catch(err => { 44 | toast.error("Error when deleting", { 45 | position: toast.POSITION.BOTTOM_LEFT 46 | }); 47 | console.error(err) 48 | }) 49 | } 50 | } 51 | 52 | // Add new car 53 | addCar(car) { 54 | fetch(SERVER_URL + 'api/cars', 55 | { method: 'POST', 56 | headers: { 57 | 'Content-Type': 'application/json', 58 | }, 59 | body: JSON.stringify(car) 60 | }) 61 | .then(res => this.fetchCars()) 62 | .catch(err => console.error(err)) 63 | } 64 | 65 | // Update car 66 | updateCar(car, link) { 67 | fetch(link, 68 | { method: 'PUT', 69 | headers: { 70 | 'Content-Type': 'application/json', 71 | }, 72 | body: JSON.stringify(car) 73 | }) 74 | .then(res => { 75 | toast.success("Changes saved", { 76 | position: toast.POSITION.BOTTOM_LEFT 77 | }); 78 | this.fetchCars(); 79 | }) 80 | .catch(err => 81 | toast.error("Error when saving", { 82 | position: toast.POSITION.BOTTOM_LEFT 83 | }) 84 | ) 85 | } 86 | 87 | render() { 88 | const columns = [{ 89 | Header: 'Brand', 90 | accessor: 'brand' 91 | }, { 92 | Header: 'Model', 93 | accessor: 'model', 94 | }, { 95 | Header: 'Color', 96 | accessor: 'color', 97 | }, { 98 | Header: 'Year', 99 | accessor: 'year', 100 | }, { 101 | Header: 'Price €', 102 | accessor: 'price', 103 | }, { 104 | sortable: false, 105 | filterable: false, 106 | width: 100, 107 | accessor: '_links.self.href', 108 | Cell: ({value, row}) => (), 109 | }, { 110 | sortable: false, 111 | filterable: false, 112 | width: 100, 113 | accessor: '_links.self.href', 114 | Cell: ({value}) => () 115 | }] 116 | 117 | return ( 118 |
119 | 120 | Export CSV 121 | 123 | 124 |
125 | ); 126 | } 127 | } 128 | 129 | export default Carlist; -------------------------------------------------------------------------------- /Chapter12/src/components/Carlist.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import {SERVER_URL} from '../constants.js' 3 | import ReactTable from "react-table"; 4 | import 'react-table/react-table.css'; 5 | import { ToastContainer, toast } from 'react-toastify'; 6 | import 'react-toastify/dist/ReactToastify.css'; 7 | import AddCar from './AddCar'; 8 | import EditCar from './EditCar'; 9 | import { CSVLink } from 'react-csv'; 10 | import Button from '@material-ui/core/Button'; 11 | import Grid from '@material-ui/core/Grid'; 12 | 13 | class Carlist extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { cars: [] }; 17 | } 18 | 19 | componentDidMount() { 20 | this.fetchCars(); 21 | } 22 | 23 | fetchCars = () => { 24 | console.log("FETCH") 25 | fetch(SERVER_URL + 'api/cars') 26 | .then((response) => response.json()) 27 | .then((responseData) => { 28 | this.setState({ 29 | cars: responseData._embedded.cars, 30 | }); 31 | }) 32 | .catch(err => console.error(err)); 33 | } 34 | 35 | // Delete car 36 | onDelClick = (link) => { 37 | if (window.confirm('Are you sure to delete?')) { 38 | fetch(link, {method: 'DELETE'}) 39 | .then(res => { 40 | toast.success("Car deleted", { 41 | position: toast.POSITION.BOTTOM_LEFT 42 | }); 43 | this.fetchCars(); 44 | }) 45 | .catch(err => { 46 | toast.error("Error when deleting", { 47 | position: toast.POSITION.BOTTOM_LEFT 48 | }); 49 | console.error(err) 50 | }) 51 | } 52 | } 53 | 54 | // Add new car 55 | addCar(car) { 56 | fetch(SERVER_URL + 'api/cars', 57 | { method: 'POST', 58 | headers: { 59 | 'Content-Type': 'application/json', 60 | }, 61 | body: JSON.stringify(car) 62 | }) 63 | .then(res => this.fetchCars()) 64 | .catch(err => console.error(err)) 65 | } 66 | 67 | // Update car 68 | updateCar(car, link) { 69 | fetch(link, 70 | { method: 'PUT', 71 | headers: { 72 | 'Content-Type': 'application/json', 73 | }, 74 | body: JSON.stringify(car) 75 | }) 76 | .then(res => { 77 | toast.success("Changes saved", { 78 | position: toast.POSITION.BOTTOM_LEFT 79 | }); 80 | this.fetchCars(); 81 | }) 82 | .catch(err => 83 | toast.error("Error when saving", { 84 | position: toast.POSITION.BOTTOM_LEFT 85 | }) 86 | ) 87 | } 88 | 89 | render() { 90 | const columns = [{ 91 | Header: 'Brand', 92 | accessor: 'brand' 93 | }, { 94 | Header: 'Model', 95 | accessor: 'model', 96 | }, { 97 | Header: 'Color', 98 | accessor: 'color', 99 | }, { 100 | Header: 'Year', 101 | accessor: 'year', 102 | }, { 103 | Header: 'Price €', 104 | accessor: 'price', 105 | }, { 106 | sortable: false, 107 | filterable: false, 108 | width: 100, 109 | accessor: '_links.self.href', 110 | Cell: ({value, row}) => (), 111 | }, { 112 | sortable: false, 113 | filterable: false, 114 | width: 100, 115 | accessor: '_links.self.href', 116 | Cell: ({value}) => () 118 | }] 119 | 120 | return ( 121 |
122 | 123 | 124 | 125 | 126 | 127 | Export CSV 128 | 129 | 130 | 132 | 133 |
134 | ); 135 | } 136 | } 137 | 138 | export default Carlist; 139 | -------------------------------------------------------------------------------- /Chapter13/src/components/Carlist.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import {SERVER_URL} from '../constants.js' 3 | import ReactTable from "react-table"; 4 | import 'react-table/react-table.css'; 5 | import { ToastContainer, toast } from 'react-toastify'; 6 | import 'react-toastify/dist/ReactToastify.css'; 7 | import AddCar from './AddCar'; 8 | import EditCar from './EditCar'; 9 | import { CSVLink } from 'react-csv'; 10 | import Button from '@material-ui/core/Button'; 11 | import Grid from '@material-ui/core/Grid'; 12 | 13 | class Carlist extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { cars: [] }; 17 | } 18 | 19 | componentDidMount() { 20 | this.fetchCars(); 21 | } 22 | 23 | fetchCars = () => { 24 | console.log("FETCH") 25 | fetch(SERVER_URL + 'api/cars') 26 | .then((response) => response.json()) 27 | .then((responseData) => { 28 | this.setState({ 29 | cars: responseData._embedded.cars, 30 | }); 31 | }) 32 | .catch(err => console.error(err)); 33 | } 34 | 35 | // Delete car 36 | onDelClick = (link) => { 37 | if (window.confirm('Are you sure to delete?')) { 38 | fetch(link, {method: 'DELETE'}) 39 | .then(res => { 40 | toast.success("Car deleted", { 41 | position: toast.POSITION.BOTTOM_LEFT 42 | }); 43 | this.fetchCars(); 44 | }) 45 | .catch(err => { 46 | toast.error("Error when deleting", { 47 | position: toast.POSITION.BOTTOM_LEFT 48 | }); 49 | console.error(err) 50 | }) 51 | } 52 | } 53 | 54 | // Add new car 55 | addCar(car) { 56 | fetch(SERVER_URL + 'api/cars', 57 | { method: 'POST', 58 | headers: { 59 | 'Content-Type': 'application/json', 60 | }, 61 | body: JSON.stringify(car) 62 | }) 63 | .then(res => this.fetchCars()) 64 | .catch(err => console.error(err)) 65 | } 66 | 67 | // Update car 68 | updateCar(car, link) { 69 | fetch(link, 70 | { method: 'PUT', 71 | headers: { 72 | 'Content-Type': 'application/json', 73 | }, 74 | body: JSON.stringify(car) 75 | }) 76 | .then(res => { 77 | toast.success("Changes saved", { 78 | position: toast.POSITION.BOTTOM_LEFT 79 | }); 80 | this.fetchCars(); 81 | }) 82 | .catch(err => 83 | toast.error("Error when saving", { 84 | position: toast.POSITION.BOTTOM_LEFT 85 | }) 86 | ) 87 | } 88 | 89 | render() { 90 | const columns = [{ 91 | Header: 'Brand', 92 | accessor: 'brand' 93 | }, { 94 | Header: 'Model', 95 | accessor: 'model', 96 | }, { 97 | Header: 'Color', 98 | accessor: 'color', 99 | }, { 100 | Header: 'Year', 101 | accessor: 'year', 102 | }, { 103 | Header: 'Price €', 104 | accessor: 'price', 105 | }, { 106 | sortable: false, 107 | filterable: false, 108 | width: 100, 109 | accessor: '_links.self.href', 110 | Cell: ({value, row}) => (), 111 | }, { 112 | sortable: false, 113 | filterable: false, 114 | width: 100, 115 | accessor: '_links.self.href', 116 | Cell: ({value}) => () 118 | }] 119 | 120 | return ( 121 |
122 | 123 | 124 | 125 | 126 | 127 | Export CSV 128 | 129 | 130 | 132 | 133 |
134 | ); 135 | } 136 | } 137 | 138 | export default Carlist; 139 | -------------------------------------------------------------------------------- /Chapter14/src/components/Carlist.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import {SERVER_URL} from '../constants.js' 3 | import ReactTable from "react-table"; 4 | import 'react-table/react-table.css'; 5 | import { ToastContainer, toast } from 'react-toastify'; 6 | import 'react-toastify/dist/ReactToastify.css'; 7 | import AddCar from './AddCar'; 8 | import EditCar from './EditCar'; 9 | import { CSVLink } from 'react-csv'; 10 | import Button from '@material-ui/core/Button'; 11 | import Grid from '@material-ui/core/Grid'; 12 | 13 | class Carlist extends Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { cars: [] }; 17 | } 18 | 19 | componentDidMount() { 20 | this.fetchCars(); 21 | } 22 | 23 | fetchCars = () => { 24 | // Read the token from the session storage 25 | // and include it to Authorization header 26 | const token = sessionStorage.getItem("jwt"); 27 | fetch(SERVER_URL + 'api/cars', 28 | { 29 | headers: {'Authorization': token} 30 | }) 31 | .then((response) => response.json()) 32 | .then((responseData) => { 33 | this.setState({ 34 | cars: responseData._embedded.cars, 35 | }); 36 | }) 37 | .catch(err => console.error(err)); 38 | } 39 | 40 | // Delete car 41 | onDelClick = (link) => { 42 | if (window.confirm('Are you sure to delete?')) { 43 | const token = sessionStorage.getItem("jwt"); 44 | fetch(link, 45 | { 46 | method: 'DELETE', 47 | headers: {'Authorization': token} 48 | }) 49 | .then(res => { 50 | toast.success("Car deleted", { 51 | position: toast.POSITION.BOTTOM_LEFT 52 | }); 53 | this.fetchCars(); 54 | }) 55 | .catch(err => { 56 | toast.error("Error when deleting", { 57 | position: toast.POSITION.BOTTOM_LEFT 58 | }); 59 | console.error(err) 60 | }) 61 | } 62 | } 63 | 64 | // Add new car 65 | addCar(car) { 66 | const token = sessionStorage.getItem("jwt"); 67 | fetch(SERVER_URL + 'api/cars', 68 | { method: 'POST', 69 | headers: { 70 | 'Content-Type': 'application/json', 71 | 'Authorization': token 72 | }, 73 | body: JSON.stringify(car) 74 | }) 75 | .then(res => this.fetchCars()) 76 | .catch(err => console.error(err)) 77 | } 78 | 79 | // Update car 80 | updateCar(car, link) { 81 | const token = sessionStorage.getItem("jwt"); 82 | fetch(link, 83 | { method: 'PUT', 84 | headers: { 85 | 'Content-Type': 'application/json', 86 | 'Authorization': token 87 | }, 88 | body: JSON.stringify(car) 89 | }) 90 | .then(res => { 91 | toast.success("Changes saved", { 92 | position: toast.POSITION.BOTTOM_LEFT 93 | }); 94 | this.fetchCars(); 95 | }) 96 | .catch(err => 97 | toast.error("Error when saving", { 98 | position: toast.POSITION.BOTTOM_LEFT 99 | }) 100 | ) 101 | } 102 | 103 | render() { 104 | const columns = [{ 105 | Header: 'Brand', 106 | accessor: 'brand' 107 | }, { 108 | Header: 'Model', 109 | accessor: 'model', 110 | }, { 111 | Header: 'Color', 112 | accessor: 'color', 113 | }, { 114 | Header: 'Year', 115 | accessor: 'year', 116 | }, { 117 | Header: 'Price €', 118 | accessor: 'price', 119 | }, { 120 | sortable: false, 121 | filterable: false, 122 | width: 100, 123 | accessor: '_links.self.href', 124 | Cell: ({value, row}) => (), 125 | }, { 126 | sortable: false, 127 | filterable: false, 128 | width: 100, 129 | accessor: '_links.self.href', 130 | Cell: ({value}) => () 132 | }] 133 | 134 | return ( 135 |
136 | 137 | 138 | 139 | 140 | 141 | Export CSV 142 | 143 | 144 | 146 | 147 |
148 | ); 149 | } 150 | } 151 | 152 | export default Carlist; -------------------------------------------------------------------------------- /Chapter10/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Chapter11/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Chapter12/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Chapter13/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Chapter14/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Chapter01/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /Chapter03/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /Chapter04/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /Chapter05/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | --------------------------------------------------------------------------------