├── .gradle ├── 6.1 │ ├── gc.properties │ ├── fileChanges │ │ └── last-build.bin │ ├── fileHashes │ │ └── fileHashes.lock │ └── executionHistory │ │ └── executionHistory.lock ├── vcs-1 │ └── gc.properties ├── buildOutputCleanup │ ├── cache.properties │ └── buildOutputCleanup.lock └── checksums │ └── checksums.lock ├── src ├── main │ ├── .DS_Store │ ├── resources │ │ ├── .DS_Store │ │ ├── other │ │ │ ├── database_mysql.sql │ │ │ ├── database_postgres.sql │ │ │ └── Orders.postman_collection.json │ │ └── application.yaml │ └── java │ │ └── it │ │ └── frankladder │ │ └── fakestore │ │ ├── .DS_Store │ │ ├── support │ │ ├── exceptions │ │ │ ├── UserNotFoundException.java │ │ │ ├── DateWrongRangeException.java │ │ │ ├── BarCodeAlreadyExistException.java │ │ │ ├── MailUserAlreadyExistsException.java │ │ │ └── QuantityProductUnavailableException.java │ │ ├── ResponseMessage.java │ │ └── authentication │ │ │ ├── Utils.java │ │ │ └── JwtAuthenticationConverter.java │ │ ├── repositories │ │ ├── ProductInPurchaseRepository.java │ │ ├── UserRepository.java │ │ ├── PurchaseRepository.java │ │ └── ProductRepository.java │ │ ├── FakeStoreApplication.java │ │ ├── controllers │ │ └── rest │ │ │ ├── HomeController.java │ │ │ ├── CheckController.java │ │ │ ├── AccountingController.java │ │ │ ├── ProductsController.java │ │ │ └── PurchasingController.java │ │ ├── configurations │ │ ├── EncodingConfiguration.java │ │ └── SecurityConfiguration.java │ │ ├── entities │ │ ├── ProductInPurchase.java │ │ ├── Purchase.java │ │ ├── User.java │ │ └── Product.java │ │ └── services │ │ ├── AccountingService.java │ │ ├── ProductService.java │ │ └── PurchasingService.java └── test │ └── java │ └── it │ └── frankladder │ └── fakestore │ └── FakeStoreApplicationTests.java ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── frontend ├── styles │ ├── shared-styles.css │ └── vaadin-text-field-styles.css └── src │ ├── products-search.js │ ├── main-app.js │ └── user-registration.js ├── .gitignore ├── package.json ├── webpack.config.js ├── pom.xml ├── webpack.generated.js ├── mvnw.cmd └── mvnw /.gradle/6.1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/6.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Fri May 15 10:42:56 CEST 2020 2 | gradle.version=6.1 3 | -------------------------------------------------------------------------------- /src/main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/src/main/.DS_Store -------------------------------------------------------------------------------- /src/main/resources/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/src/main/resources/.DS_Store -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.gradle/checksums/checksums.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/.gradle/checksums/checksums.lock -------------------------------------------------------------------------------- /.gradle/6.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/.gradle/6.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/src/main/java/it/frankladder/fakestore/.DS_Store -------------------------------------------------------------------------------- /.gradle/6.1/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/.gradle/6.1/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Franco7Scala/SpringProjectPSW/HEAD/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/exceptions/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.exceptions; 2 | 3 | 4 | public class UserNotFoundException extends Exception { 5 | 6 | public UserNotFoundException() {} 7 | 8 | } -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/exceptions/DateWrongRangeException.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.exceptions; 2 | 3 | 4 | public class DateWrongRangeException extends Exception { 5 | 6 | public DateWrongRangeException() {} 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/exceptions/BarCodeAlreadyExistException.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.exceptions; 2 | 3 | 4 | public class BarCodeAlreadyExistException extends Exception { 5 | 6 | public BarCodeAlreadyExistException() {} 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/exceptions/MailUserAlreadyExistsException.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.exceptions; 2 | 3 | 4 | public class MailUserAlreadyExistsException extends Exception { 5 | 6 | public MailUserAlreadyExistsException() {} 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/exceptions/QuantityProductUnavailableException.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.exceptions; 2 | 3 | 4 | public class QuantityProductUnavailableException extends Exception { 5 | 6 | public QuantityProductUnavailableException() {} 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/it/frankladder/fakestore/FakeStoreApplicationTests.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class FakeStoreApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /frontend/styles/shared-styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS styling examples for the Vaadin app. 3 | Visit https://vaadin.com/docs/flow/theme/theming-overview.html and 4 | https://vaadin.com/themes/lumo for more information. 5 | */ 6 | 7 | /* Example: CSS class name to center align the content . */ 8 | .centered-content { 9 | margin: 0 auto; 10 | max-width: 250px; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/ResponseMessage.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support; 2 | 3 | 4 | public class ResponseMessage { 5 | private String message; 6 | 7 | 8 | public ResponseMessage(String message) { 9 | this.message = message; 10 | } 11 | 12 | public String getMessage() { 13 | return message; 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/repositories/ProductInPurchaseRepository.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.repositories; 2 | 3 | 4 | import it.frankladder.fakestore.entities.ProductInPurchase; 5 | import org.springframework.stereotype.Repository; 6 | import org.springframework.data.jpa.repository.*; 7 | 8 | 9 | @Repository 10 | public interface ProductInPurchaseRepository extends JpaRepository { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /frontend/styles/vaadin-text-field-styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS styling examples for the Vaadin app. 3 | Visit https://vaadin.com/docs/flow/theme/theming-overview.html and 4 | https://vaadin.com/themes/lumo for more information. 5 | */ 6 | 7 | /* Example: border-only style for all Vaadin textfields . */ 8 | [part="input-field"] { 9 | box-shadow: inset 0 0 0 1px var(--lumo-contrast-30pct); 10 | background-color: var(--lumo-base-color); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/FakeStoreApplication.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore; 2 | 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | 8 | @SpringBootApplication 9 | public class FakeStoreApplication { 10 | 11 | 12 | public static void main(String[] args) { 13 | SpringApplication.run(FakeStoreApplication.class, args); 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/repositories/UserRepository.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.repositories; 2 | 3 | 4 | import it.frankladder.fakestore.entities.User; 5 | import org.springframework.stereotype.Repository; 6 | import org.springframework.data.jpa.repository.*; 7 | import java.util.List; 8 | 9 | 10 | @Repository 11 | public interface UserRepository extends JpaRepository { 12 | 13 | List findByFirstName(String firstName); 14 | List findByLastName(String lastName); 15 | List findByFirstNameAndLastName(String firstName, String lastName); 16 | List findByEmail(String email); 17 | List findByCode(String code); 18 | boolean existsByEmail(String email); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/authentication/Utils.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.authentication; 2 | 3 | 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.security.oauth2.jwt.Jwt; 6 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 7 | 8 | 9 | public class Utils { 10 | 11 | public static String getEmail() { 12 | JwtAuthenticationToken authenticationToken = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); 13 | Jwt jwt = (Jwt) authenticationToken.getCredentials(); 14 | String email = (String) jwt.getClaims().get("email"); 15 | return email; 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/controllers/rest/HomeController.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.controllers.rest; 2 | 3 | 4 | import it.frankladder.fakestore.support.authentication.Utils; 5 | import org.springframework.security.access.prepost.PreAuthorize; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | 11 | @RestController 12 | public class HomeController { 13 | 14 | 15 | @GetMapping("/") 16 | @PreAuthorize("hasAuthority('user')") 17 | public String home(@RequestParam(value = "someValue") int value) { 18 | return "Welcome, " + Utils.getEmail() + " " + value + " !"; 19 | } 20 | 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-name", 3 | "license": "UNLICENSED", 4 | "dependencies": { 5 | "@polymer/iron-pages": "^3.0.1", 6 | "@polymer/polymer": "3.2.0", 7 | "@vaadin/flow-deps": "./target/frontend", 8 | "@vaadin/vaadin-dialog": "^2.4.0", 9 | "@webcomponents/webcomponentsjs": "^2.2.10" 10 | }, 11 | "devDependencies": { 12 | "webpack": "4.42.0", 13 | "webpack-cli": "3.3.10", 14 | "webpack-dev-server": "3.9.0", 15 | "webpack-babel-multi-target-plugin": "2.3.3", 16 | "copy-webpack-plugin": "5.1.0", 17 | "compression-webpack-plugin": "3.0.1", 18 | "webpack-merge": "4.2.2", 19 | "raw-loader": "3.0.0", 20 | "terser": "4.6.7" 21 | }, 22 | "vaadinAppPackageHash": "d589283b4783a58e45cf9e6ecf629de9bb1d5673595b9bf216b8b3f47501c1a7" 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/configurations/EncodingConfiguration.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.configurations; 2 | 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 7 | import java.nio.charset.StandardCharsets; 8 | 9 | 10 | @Configuration 11 | public class EncodingConfiguration { 12 | 13 | 14 | @Bean 15 | public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 16 | MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); 17 | jsonConverter.setDefaultCharset(StandardCharsets.UTF_8); 18 | return jsonConverter; 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/repositories/PurchaseRepository.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.repositories; 2 | 3 | 4 | import it.frankladder.fakestore.entities.Purchase; 5 | import it.frankladder.fakestore.entities.User; 6 | import org.springframework.stereotype.Repository; 7 | import org.springframework.data.jpa.repository.*; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | 12 | @Repository 13 | public interface PurchaseRepository extends JpaRepository { 14 | 15 | List findByBuyer(User user); 16 | List findByPurchaseTime(Date date); 17 | 18 | @Query("select p from Purchase p where p.purchaseTime > ?1 and p.purchaseTime < ?2 and p.buyer = ?3") 19 | List findByBuyerInPeriod(Date startDate, Date endDate, User user); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/repositories/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.repositories; 2 | 3 | 4 | import it.frankladder.fakestore.entities.Product; 5 | import org.springframework.stereotype.Repository; 6 | import org.springframework.data.jpa.repository.*; 7 | import java.util.List; 8 | 9 | 10 | @Repository 11 | public interface ProductRepository extends JpaRepository { 12 | 13 | List findByNameContaining(String name); 14 | List findByBarCode(String name); 15 | boolean existsByBarCode(String barCode); 16 | @Query("SELECT p " + 17 | "FROM Product p " + 18 | "WHERE (p.name LIKE ?1 OR ?1 IS NULL) AND " + 19 | " (p.description LIKE ?2 OR ?2 IS NULL)") 20 | List advancedSearch(String name, String description); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/entities/ProductInPurchase.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.entities; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | import jakarta.persistence.*; 10 | 11 | 12 | @Getter 13 | @Setter 14 | @EqualsAndHashCode 15 | @ToString 16 | @Entity 17 | @Table(name = "product_in_purchase", schema = "orders") 18 | public class ProductInPurchase { 19 | @Id 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | @Column(name = "id", nullable = false) 22 | private int id; 23 | 24 | @ManyToOne 25 | @JoinColumn(name = "related_purchase") 26 | @JsonIgnore 27 | @ToString.Exclude 28 | private Purchase purchase; 29 | 30 | @Basic 31 | @Column(name = "quantity", nullable = true) 32 | private int quantity; 33 | 34 | @ManyToOne(cascade = CascadeType.MERGE) 35 | @JoinColumn(name = "product") 36 | private Product product; 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/controllers/rest/CheckController.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.controllers.rest; 2 | 3 | 4 | import it.frankladder.fakestore.support.authentication.*; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.security.access.prepost.PreAuthorize; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | 13 | @RestController 14 | @RequestMapping("/check") 15 | public class CheckController { 16 | 17 | 18 | @GetMapping("/simple") 19 | public ResponseEntity checkSimple() { 20 | return new ResponseEntity("Check status ok!", HttpStatus.OK); 21 | } 22 | 23 | @PreAuthorize("hasAuthority('club')") 24 | @GetMapping("/logged") 25 | public ResponseEntity checkLogged() { 26 | return new ResponseEntity("Check status ok, hi " + Utils.getEmail() + "!", HttpStatus.OK); 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/other/database_mysql.sql: -------------------------------------------------------------------------------- 1 | DROP SCHEMA orders; 2 | CREATE SCHEMA orders; 3 | USE orders; 4 | 5 | CREATE TABLE user ( 6 | id INTEGER AUTO_INCREMENT PRIMARY KEY, 7 | code VARCHAR(70), 8 | first_name VARCHAR(50), 9 | last_name VARCHAR(50), 10 | telephone_number VARCHAR(20), 11 | email VARCHAR(90), 12 | address VARCHAR(150) 13 | ); 14 | 15 | CREATE TABLE product ( 16 | id INTEGER AUTO_INCREMENT PRIMARY KEY, 17 | name VARCHAR(50), 18 | bar_code VARCHAR(70), 19 | description VARCHAR(500), 20 | price FLOAT, 21 | quantity FLOAT, 22 | version LONG 23 | ); 24 | 25 | CREATE TABLE purchase ( 26 | id INTEGER AUTO_INCREMENT PRIMARY KEY, 27 | buyer INTEGER, 28 | purchase_time DATETIME DEFAULT CURRENT_TIMESTAMP, 29 | FOREIGN KEY (buyer) REFERENCES user (id) 30 | ); 31 | 32 | CREATE TABLE product_in_purchase ( 33 | id INTEGER AUTO_INCREMENT PRIMARY KEY, 34 | related_purchase INTEGER, 35 | product INTEGER, 36 | quantity INTEGER, 37 | FOREIGN KEY (related_purchase) REFERENCES purchase (id), 38 | FOREIGN KEY (product) REFERENCES product (id) 39 | ); 40 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/entities/Purchase.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.entities; 2 | 3 | 4 | import lombok.EqualsAndHashCode; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import lombok.ToString; 8 | import org.hibernate.annotations.CreationTimestamp; 9 | import jakarta.persistence.*; 10 | import java.util.Date; 11 | import java.util.List; 12 | 13 | 14 | @Getter 15 | @Setter 16 | @EqualsAndHashCode 17 | @ToString 18 | @Entity 19 | @Table(name = "purchase", schema = "orders") 20 | public class Purchase { 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "id", nullable = false) 24 | private int id; 25 | 26 | @Basic 27 | @CreationTimestamp 28 | @Temporal(TemporalType.TIMESTAMP) 29 | @Column(name = "purchase_time") 30 | private Date purchaseTime; 31 | 32 | @ManyToOne 33 | @JoinColumn(name = "buyer") 34 | private User buyer; 35 | 36 | @OneToMany(mappedBy = "purchase", cascade = CascadeType.MERGE) 37 | private List productsInPurchase; 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | security: 3 | oauth2: 4 | resourceserver: 5 | jwt: 6 | jwk-set-uri: http://localhost:8443/auth/realms/rendicontation/protocol/openid-connect/certs 7 | issuer-uri: http://localhost:8443/auth/realms/rendicontation 8 | application: 9 | name: FakeStore-API 10 | datasource: 11 | password: '***' 12 | driver-class-name: com.mysql.jdbc.Driver 13 | username: '***' 14 | url: jdbc:mysql://localhost:3306/orders?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC 15 | jpa: 16 | database-platform: org.hibernate.dialect.MySQL5Dialect 17 | 18 | jwt: 19 | auth: 20 | converter: 21 | resource-id: fakestore-flutter 22 | principle-attribute: preferred_username 23 | 24 | server: 25 | #ssl: 26 | #key-store-password: password_certificate 27 | #key-store-type: PKCS12 28 | #key-store: /home/debian/ssl-cert/certificate.p12 29 | compression: 30 | enabled: 'true' 31 | port: '8080' 32 | 33 | #security: 34 | #require-ssl: 'true' 35 | 36 | logging: 37 | level: 38 | it: 39 | frankladder: DEBUG 40 | org: 41 | springframework: INFO 42 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/services/AccountingService.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.services; 2 | 3 | 4 | import it.frankladder.fakestore.repositories.UserRepository; 5 | import it.frankladder.fakestore.support.exceptions.MailUserAlreadyExistsException; 6 | import it.frankladder.fakestore.entities.User; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Propagation; 10 | import org.springframework.transaction.annotation.Transactional; 11 | import java.util.List; 12 | 13 | 14 | @Service 15 | public class AccountingService { 16 | @Autowired 17 | private UserRepository userRepository; 18 | 19 | 20 | @Transactional(readOnly = false, propagation = Propagation.REQUIRED) 21 | public User registerUser(User user) throws MailUserAlreadyExistsException { 22 | if ( userRepository.existsByEmail(user.getEmail()) ) { 23 | throw new MailUserAlreadyExistsException(); 24 | } 25 | return userRepository.save(user); 26 | } 27 | 28 | @Transactional(readOnly = true) 29 | public List getAllUsers() { 30 | return userRepository.findAll(); 31 | } 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/other/database_postgres.sql: -------------------------------------------------------------------------------- 1 | CREATE SCHEMA orders; 2 | 3 | CREATE SEQUENCE user_seq; 4 | 5 | CREATE TABLE user ( 6 | id INTEGER DEFAULT NEXTVAL ('user_seq') PRIMARY KEY, 7 | code VARCHAR(70), 8 | first_name VARCHAR(50), 9 | last_name VARCHAR(50), 10 | telephone_number VARCHAR(20), 11 | email VARCHAR(90), 12 | address VARCHAR(150) 13 | ); 14 | 15 | CREATE SEQUENCE product_seq; 16 | 17 | CREATE TABLE product ( 18 | id INTEGER DEFAULT NEXTVAL ('product_seq') PRIMARY KEY, 19 | name VARCHAR(50), 20 | bar_code VARCHAR(70), 21 | description VARCHAR(500), 22 | price FLOAT, 23 | quantity FLOAT, 24 | version LONG 25 | ); 26 | 27 | CREATE SEQUENCE purchase_seq; 28 | 29 | CREATE TABLE purchase ( 30 | id INTEGER DEFAULT NEXTVAL ('purchase_seq') PRIMARY KEY, 31 | buyer INTEGER, 32 | purchase_time TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP, 33 | FOREIGN KEY (buyer) REFERENCES user (id) 34 | ); 35 | 36 | CREATE SEQUENCE product_in_purchase_seq; 37 | 38 | CREATE TABLE product_in_purchase ( 39 | id INTEGER DEFAULT NEXTVAL ('product_in_purchase_seq') PRIMARY KEY, 40 | related_purchase INTEGER, 41 | product INTEGER, 42 | quantity INTEGER, 43 | FOREIGN KEY (related_purchase) REFERENCES purchase (id), 44 | FOREIGN KEY (product) REFERENCES product (id) 45 | ); 46 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file has been autogenerated as it didn't exist or was made for an older incompatible version. 3 | * This file can be used for manual configuration will not be modified if the flowDefaults constant exists. 4 | */ 5 | const merge = require('webpack-merge'); 6 | const flowDefaults = require('./webpack.generated.js'); 7 | 8 | module.exports = merge(flowDefaults, { 9 | 10 | }); 11 | 12 | /** 13 | * This file can be used to configure the flow plugin defaults. 14 | * 15 | * // Add a custom plugin 16 | * flowDefaults.plugins.push(new MyPlugin()); 17 | * 18 | * // Update the rules to also transpile `.mjs` files 19 | * if (!flowDefaults.module.rules[0].test) { 20 | * throw "Unexpected structure in generated webpack config"; 21 | * } 22 | * flowDefaults.module.rules[0].test = /\.m?js$/ 23 | * 24 | * // Include a custom JS in the entry point in addition to generated-flow-imports.js 25 | * if (typeof flowDefaults.entry.index != "string") { 26 | * throw "Unexpected structure in generated webpack config"; 27 | * } 28 | * flowDefaults.entry.index = [flowDefaults.entry.index, "myCustomFile.js"]; 29 | * 30 | * or add new configuration in the merge block. 31 | * 32 | * module.exports = merge(flowDefaults, { 33 | * mode: 'development', 34 | * devtool: 'inline-source-map' 35 | * }); 36 | * 37 | */ 38 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/controllers/rest/AccountingController.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.controllers.rest; 2 | 3 | 4 | import it.frankladder.fakestore.support.exceptions.MailUserAlreadyExistsException; 5 | import it.frankladder.fakestore.entities.User; 6 | import it.frankladder.fakestore.services.AccountingService; 7 | import it.frankladder.fakestore.support.ResponseMessage; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.*; 12 | import javax.validation.Valid; 13 | import java.util.List; 14 | 15 | 16 | @RestController 17 | @RequestMapping("/users") 18 | public class AccountingController { 19 | @Autowired 20 | private AccountingService accountingService; 21 | 22 | 23 | @PostMapping 24 | public ResponseEntity create(@RequestBody @Valid User user) { 25 | try { 26 | User added = accountingService.registerUser(user); 27 | return new ResponseEntity(added, HttpStatus.OK); 28 | } catch (MailUserAlreadyExistsException e) { 29 | return new ResponseEntity<>(new ResponseMessage("ERROR_MAIL_USER_ALREADY_EXISTS"), HttpStatus.BAD_REQUEST); 30 | } 31 | } 32 | 33 | @GetMapping 34 | public List getAll() { 35 | return accountingService.getAllUsers(); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/entities/User.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.entities; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | import jakarta.persistence.*; 10 | import java.util.List; 11 | 12 | 13 | @Getter 14 | @Setter 15 | @EqualsAndHashCode 16 | @ToString 17 | @Entity 18 | @Table(name = "user", schema = "orders") 19 | public class User { 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.IDENTITY) 22 | @Column(name = "id", nullable = false) 23 | private int id; 24 | 25 | @Basic 26 | @Column(name = "code", nullable = true, length = 70) 27 | private String code; 28 | 29 | @Basic 30 | @Column(name = "first_name", nullable = true, length = 50) 31 | private String firstName; 32 | 33 | @Basic 34 | @Column(name = "last_name", nullable = true, length = 50) 35 | private String lastName; 36 | 37 | @Basic 38 | @Column(name = "telephone_number", nullable = true, length = 20) 39 | private String telephoneNumber; 40 | 41 | @Basic 42 | @Column(name = "email", nullable = true, length = 90) 43 | private String email; 44 | 45 | @Basic 46 | @Column(name = "address", nullable = true, length = 150) 47 | private String address; 48 | 49 | @OneToMany(mappedBy = "buyer", cascade = CascadeType.MERGE) 50 | @JsonIgnore 51 | private List purchases; 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/entities/Product.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.entities; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | import lombok.ToString; 9 | import jakarta.persistence.*; 10 | import java.util.List; 11 | 12 | 13 | @Getter 14 | @Setter 15 | @EqualsAndHashCode 16 | @ToString 17 | @Entity 18 | @Table(name = "product", schema = "orders") 19 | public class Product { 20 | @Id 21 | @GeneratedValue(strategy = GenerationType.IDENTITY) 22 | @Column(name = "id", nullable = false) 23 | private int id; 24 | 25 | @Basic 26 | @Column(name = "name", nullable = true, length = 50) 27 | private String name; 28 | 29 | @Basic 30 | @Column(name = "bar_code", nullable = true, length = 70) 31 | private String barCode; 32 | 33 | @Basic 34 | @Column(name = "description", nullable = true, length = 500) 35 | private String description; 36 | 37 | @Basic 38 | @Column(name = "price", nullable = true) 39 | private float price; 40 | 41 | @Basic 42 | @Column(name = "quantity", nullable = true) 43 | private int quantity; 44 | 45 | @Version 46 | @Column(name = "version", nullable = false) 47 | @JsonIgnore 48 | private long version; 49 | 50 | @OneToMany(targetEntity = ProductInPurchase.class, mappedBy = "product", cascade = CascadeType.MERGE) 51 | @JsonIgnore 52 | @ToString.Exclude 53 | private List productsInPurchase; 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /frontend/src/products-search.js: -------------------------------------------------------------------------------- 1 | import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'; 2 | import '@vaadin/vaadin-text-field/src/vaadin-text-field.js'; 3 | import '@vaadin/vaadin-grid/src/vaadin-grid.js'; 4 | import '@vaadin/vaadin-ordered-layout/src/vaadin-horizontal-layout.js'; 5 | import '@polymer/iron-icon/iron-icon.js'; 6 | 7 | class ProductsSearch extends PolymerElement { 8 | 9 | static get template() { 10 | return html` 11 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | `; 29 | } 30 | 31 | static get is() { 32 | return 'products-search'; 33 | } 34 | 35 | static get properties() { 36 | return { 37 | // Declare your properties here. 38 | }; 39 | } 40 | } 41 | 42 | customElements.define(ProductsSearch.is, ProductsSearch); 43 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/services/ProductService.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.services; 2 | 3 | 4 | import it.frankladder.fakestore.repositories.ProductRepository; 5 | import it.frankladder.fakestore.support.exceptions.BarCodeAlreadyExistException; 6 | import it.frankladder.fakestore.entities.Product; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.domain.Page; 9 | import org.springframework.data.domain.PageRequest; 10 | import org.springframework.data.domain.Pageable; 11 | import org.springframework.data.domain.Sort; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.transaction.annotation.Transactional; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | 18 | @Service 19 | public class ProductService { 20 | @Autowired 21 | private ProductRepository productRepository; 22 | 23 | 24 | @Transactional(readOnly = false) 25 | public void addProduct(Product product) throws BarCodeAlreadyExistException { 26 | if ( product.getBarCode() != null && productRepository.existsByBarCode(product.getBarCode()) ) { 27 | throw new BarCodeAlreadyExistException(); 28 | } 29 | productRepository.save(product); 30 | } 31 | 32 | @Transactional(readOnly = true) 33 | public List showAllProducts() { 34 | return productRepository.findAll(); 35 | } 36 | 37 | @Transactional(readOnly = true) 38 | public List showAllProducts(int pageNumber, int pageSize, String sortBy) { 39 | Pageable paging = PageRequest.of(pageNumber, pageSize, Sort.by(sortBy)); 40 | Page pagedResult = productRepository.findAll(paging); 41 | if ( pagedResult.hasContent() ) { 42 | return pagedResult.getContent(); 43 | } 44 | else { 45 | return new ArrayList<>(); 46 | } 47 | } 48 | 49 | @Transactional(readOnly = true) 50 | public List showProductsByName(String name) { 51 | return productRepository.findByNameContaining(name); 52 | } 53 | 54 | @Transactional(readOnly = true) 55 | public List showProductsByBarCode(String barCode) { 56 | return productRepository.findByBarCode(barCode); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/controllers/rest/ProductsController.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.controllers.rest; 2 | 3 | 4 | import it.frankladder.fakestore.entities.Product; 5 | import it.frankladder.fakestore.services.ProductService; 6 | import it.frankladder.fakestore.support.ResponseMessage; 7 | import it.frankladder.fakestore.support.exceptions.BarCodeAlreadyExistException; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.*; 12 | import javax.validation.Valid; 13 | import java.util.List; 14 | 15 | 16 | @RestController 17 | @RequestMapping("/products") 18 | public class ProductsController { 19 | @Autowired 20 | private ProductService productService; 21 | 22 | 23 | @PostMapping 24 | public ResponseEntity create(@RequestBody @Valid Product product) { 25 | try { 26 | productService.addProduct(product); 27 | } catch (BarCodeAlreadyExistException e) { 28 | return new ResponseEntity<>(new ResponseMessage("Barcode already exist!"), HttpStatus.BAD_REQUEST); 29 | } 30 | return new ResponseEntity<>(new ResponseMessage("Added successful!"), HttpStatus.OK); 31 | } 32 | 33 | @GetMapping 34 | public List getAll() { 35 | return productService.showAllProducts(); 36 | } 37 | 38 | @GetMapping("/paged") 39 | public ResponseEntity getAll(@RequestParam(value = "pageNumber", defaultValue = "0") int pageNumber, @RequestParam(value = "pageSize", defaultValue = "10") int pageSize, @RequestParam(value = "sortBy", defaultValue = "id") String sortBy) { 40 | List result = productService.showAllProducts(pageNumber, pageSize, sortBy); 41 | if ( result.size() <= 0 ) { 42 | return new ResponseEntity<>(new ResponseMessage("No results!"), HttpStatus.OK); 43 | } 44 | return new ResponseEntity<>(result, HttpStatus.OK); 45 | } 46 | 47 | @GetMapping("/search/by_name") 48 | public ResponseEntity getByName(@RequestParam(required = false) String name) { 49 | List result = productService.showProductsByName(name); 50 | if ( result.size() <= 0 ) { 51 | return new ResponseEntity<>(new ResponseMessage("No results!"), HttpStatus.OK); 52 | } 53 | return new ResponseEntity<>(result, HttpStatus.OK); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /frontend/src/main-app.js: -------------------------------------------------------------------------------- 1 | import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'; 2 | import '@vaadin/vaadin-ordered-layout/src/vaadin-horizontal-layout.js'; 3 | import '@vaadin/vaadin-app-layout/src/vaadin-app-layout.js'; 4 | import '@vaadin/vaadin-ordered-layout/src/vaadin-vertical-layout.js'; 5 | import '@vaadin/vaadin-tabs/src/vaadin-tabs.js'; 6 | import '@polymer/iron-pages/iron-pages.js'; 7 | import '@vaadin/vaadin-tabs/src/vaadin-tab.js'; 8 | import './user-registration.js' 9 | import './products-search.js' 10 | 11 | 12 | class MainApp extends PolymerElement { 13 | 14 | static get template() { 15 | return html` 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Home 30 | 31 | 32 | Products 33 | 34 | 35 | Users 36 | 37 | 38 | 39 | 40 |
41 |

Welcome to Fake Store!

42 |
43 |
44 | 45 |
46 |
47 | 48 |
49 |
50 |
51 | 52 |
53 |
54 | `; 55 | } 56 | 57 | static get is() { 58 | return 'main-app'; 59 | } 60 | 61 | static get properties() { 62 | return { 63 | // Declare your properties here. 64 | }; 65 | } 66 | } 67 | 68 | customElements.define(MainApp.is, MainApp); 69 | -------------------------------------------------------------------------------- /frontend/src/user-registration.js: -------------------------------------------------------------------------------- 1 | import {html, PolymerElement} from '@polymer/polymer/polymer-element.js'; 2 | import '@vaadin/vaadin-ordered-layout/src/vaadin-vertical-layout.js'; 3 | import '@vaadin/vaadin-button/src/vaadin-button.js'; 4 | import '@vaadin/vaadin-form-layout/src/vaadin-form-layout.js'; 5 | import '@vaadin/vaadin-text-field/src/vaadin-text-field.js'; 6 | import '@vaadin/vaadin-form-layout/src/vaadin-form-item.js'; 7 | 8 | class UserRegistration extends PolymerElement { 9 | 10 | 11 | static get template() { 12 | return html` 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Submit 48 | 49 | 50 | 51 | 52 | 53 | `; 54 | } 55 | 56 | static get is() { 57 | return 'user-registration'; 58 | } 59 | 60 | static get properties() { 61 | return { 62 | // Declare your properties here. 63 | }; 64 | } 65 | } 66 | 67 | customElements.define(UserRegistration.is, UserRegistration); 68 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/configurations/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.configurations; 2 | 3 | 4 | import it.frankladder.fakestore.support.authentication.JwtAuthenticationConverter; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 11 | import org.springframework.security.web.SecurityFilterChain; 12 | import org.springframework.web.cors.CorsConfiguration; 13 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 14 | import org.springframework.web.filter.CorsFilter; 15 | import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; 16 | import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; 17 | 18 | 19 | @Configuration 20 | @EnableWebSecurity 21 | @EnableMethodSecurity 22 | @RequiredArgsConstructor 23 | public class SecurityConfiguration { 24 | 25 | private final JwtAuthenticationConverter jwtAuthConverter; 26 | 27 | 28 | @Bean 29 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 30 | http.csrf(csrf -> csrf.disable()).authorizeHttpRequests(auth -> auth.requestMatchers( 31 | antMatcher("/check/simple"), 32 | antMatcher("/users/**"), 33 | antMatcher("/products/**"), 34 | antMatcher("/purchases/**") 35 | ).permitAll().anyRequest().authenticated()); 36 | http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthConverter))); 37 | http.sessionManagement(sess -> sess.sessionCreationPolicy(STATELESS)); 38 | return http.build(); 39 | } 40 | 41 | @Bean 42 | public CorsFilter corsFilter() { 43 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 44 | CorsConfiguration configuration = new CorsConfiguration(); 45 | configuration.setAllowCredentials(true); 46 | configuration.addAllowedOrigin("*"); 47 | configuration.addAllowedHeader("*"); 48 | configuration.addAllowedMethod("OPTIONS"); 49 | configuration.addAllowedMethod("GET"); 50 | configuration.addAllowedMethod("POST"); 51 | configuration.addAllowedMethod("PUT"); 52 | source.registerCorsConfiguration("/**", configuration); 53 | return new CorsFilter(source); 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/support/authentication/JwtAuthenticationConverter.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.support.authentication; 2 | 3 | 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.core.convert.converter.Converter; 6 | import org.springframework.lang.NonNull; 7 | import org.springframework.security.authentication.AbstractAuthenticationToken; 8 | import org.springframework.security.core.GrantedAuthority; 9 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 10 | import org.springframework.security.oauth2.jwt.Jwt; 11 | import org.springframework.security.oauth2.jwt.JwtClaimNames; 12 | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; 13 | import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; 14 | import org.springframework.stereotype.Component; 15 | import java.util.Collection; 16 | import java.util.Map; 17 | import java.util.Set; 18 | import java.util.stream.Collectors; 19 | import java.util.stream.Stream; 20 | 21 | 22 | @Component 23 | public class JwtAuthenticationConverter implements Converter { 24 | private final JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter(); 25 | 26 | @Value("${jwt.auth.converter.principle-attribute}") 27 | private String principleAttribute; 28 | @Value("${jwt.auth.converter.resource-id}") 29 | private String resourceId; 30 | 31 | 32 | @Override 33 | public AbstractAuthenticationToken convert(@NonNull Jwt jwt) { 34 | Collection authorities = Stream.concat( 35 | jwtGrantedAuthoritiesConverter.convert(jwt).stream(), 36 | extractResourceRoles(jwt).stream() 37 | ).collect(Collectors.toSet()); 38 | 39 | return new JwtAuthenticationToken( 40 | jwt, 41 | authorities, 42 | getPrincipleClaimName(jwt) 43 | ); 44 | } 45 | 46 | private String getPrincipleClaimName(Jwt jwt) { 47 | String claimName = JwtClaimNames.SUB; 48 | if (principleAttribute != null) { 49 | claimName = principleAttribute; 50 | } 51 | return jwt.getClaim(claimName); 52 | } 53 | 54 | private Collection extractResourceRoles(Jwt jwt) { 55 | Map resourceAccess; 56 | Map resource; 57 | Collection resourceRoles; 58 | if (jwt.getClaim("resource_access") == null) { 59 | return Set.of(); 60 | } 61 | resourceAccess = jwt.getClaim("resource_access"); 62 | 63 | if (resourceAccess.get(resourceId) == null) { 64 | return Set.of(); 65 | } 66 | resource = (Map) resourceAccess.get(resourceId); 67 | 68 | resourceRoles = (Collection) resource.get("roles"); 69 | return resourceRoles 70 | .stream() 71 | .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) 72 | .collect(Collectors.toSet()); 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/controllers/rest/PurchasingController.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.controllers.rest; 2 | 3 | 4 | import it.frankladder.fakestore.entities.Purchase; 5 | import it.frankladder.fakestore.entities.User; 6 | import it.frankladder.fakestore.services.PurchasingService; 7 | import it.frankladder.fakestore.support.ResponseMessage; 8 | import it.frankladder.fakestore.support.exceptions.DateWrongRangeException; 9 | import it.frankladder.fakestore.support.exceptions.QuantityProductUnavailableException; 10 | import it.frankladder.fakestore.support.exceptions.UserNotFoundException; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.format.annotation.DateTimeFormat; 13 | import org.springframework.http.HttpStatus; 14 | import org.springframework.http.ResponseEntity; 15 | import org.springframework.web.bind.annotation.*; 16 | import org.springframework.web.server.ResponseStatusException; 17 | import javax.validation.Valid; 18 | import java.util.Date; 19 | import java.util.List; 20 | 21 | 22 | @RestController 23 | @RequestMapping("/purchases") 24 | public class PurchasingController { 25 | @Autowired 26 | private PurchasingService purchasingService; 27 | 28 | 29 | @PostMapping 30 | @ResponseStatus(code = HttpStatus.OK) 31 | public ResponseEntity create(@RequestBody @Valid Purchase purchase) { // è buona prassi ritornare l'oggetto inserito 32 | try { 33 | return new ResponseEntity<>(purchasingService.addPurchase(purchase), HttpStatus.OK); 34 | } catch (QuantityProductUnavailableException e) { 35 | throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Product quantity unavailable!", e); // realmente il messaggio dovrebbe essrere più esplicativo (es. specificare il prodotto di cui non vi è disponibilità) 36 | } 37 | } 38 | 39 | @GetMapping("/{user}") 40 | public List getPurchases(@RequestBody @Valid User user) { 41 | try { 42 | return purchasingService.getPurchasesByUser(user); 43 | } catch (UserNotFoundException e) { 44 | throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "User not found!", e); 45 | } 46 | } 47 | 48 | @GetMapping("/{user}/{startDate}/{endDate}") 49 | public ResponseEntity getPurchasesInPeriod(@Valid @PathVariable("user") User user, @PathVariable("startDate") @DateTimeFormat(pattern = "dd-MM-yyyy") Date start, @PathVariable("endDate") @DateTimeFormat(pattern = "dd-MM-yyyy") Date end) { 50 | try { 51 | List result = purchasingService.getPurchasesByUserInPeriod(user, start, end); 52 | if (result.isEmpty()) { 53 | return new ResponseEntity<>(new ResponseMessage("No results!"), HttpStatus.OK); 54 | } 55 | return new ResponseEntity<>(result, HttpStatus.OK); 56 | } catch (UserNotFoundException e) { 57 | throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "User not found XXX!", e); 58 | } catch (DateWrongRangeException e) { 59 | throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Start date must be previous end date XXX!", e); 60 | } 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/it/frankladder/fakestore/services/PurchasingService.java: -------------------------------------------------------------------------------- 1 | package it.frankladder.fakestore.services; 2 | 3 | 4 | import it.frankladder.fakestore.entities.Product; 5 | import it.frankladder.fakestore.repositories.ProductInPurchaseRepository; 6 | import it.frankladder.fakestore.repositories.PurchaseRepository; 7 | import it.frankladder.fakestore.repositories.UserRepository; 8 | import it.frankladder.fakestore.support.exceptions.DateWrongRangeException; 9 | import it.frankladder.fakestore.support.exceptions.QuantityProductUnavailableException; 10 | import it.frankladder.fakestore.support.exceptions.UserNotFoundException; 11 | import it.frankladder.fakestore.entities.ProductInPurchase; 12 | import it.frankladder.fakestore.entities.Purchase; 13 | import it.frankladder.fakestore.entities.User; 14 | import jakarta.persistence.EntityManager; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.transaction.annotation.Transactional; 18 | import java.util.Date; 19 | import java.util.List; 20 | 21 | 22 | @Service 23 | public class PurchasingService { 24 | @Autowired 25 | private PurchaseRepository purchaseRepository; 26 | @Autowired 27 | private ProductInPurchaseRepository productInPurchaseRepository; 28 | @Autowired 29 | private UserRepository userRepository; 30 | @Autowired 31 | private EntityManager entityManager; 32 | 33 | 34 | @Transactional(readOnly = false) 35 | public Purchase addPurchase(Purchase purchase) throws QuantityProductUnavailableException { 36 | Purchase result = purchaseRepository.save(purchase); 37 | for ( ProductInPurchase pip : result.getProductsInPurchase() ) { 38 | pip.setPurchase(result); 39 | ProductInPurchase justAdded = productInPurchaseRepository.save(pip); 40 | entityManager.refresh(justAdded); 41 | Product product = justAdded.getProduct(); 42 | int newQuantity = product.getQuantity() - pip.getQuantity(); 43 | if ( newQuantity < 0 ) { 44 | throw new QuantityProductUnavailableException(); 45 | } 46 | product.setQuantity(newQuantity); 47 | entityManager.refresh(pip); 48 | } 49 | entityManager.refresh(result); 50 | return result; 51 | } 52 | 53 | @Transactional(readOnly = true) 54 | public List getPurchasesByUser(User user) throws UserNotFoundException { 55 | if ( !userRepository.existsById(user.getId()) ) { 56 | throw new UserNotFoundException(); 57 | } 58 | return purchaseRepository.findByBuyer(user); 59 | } 60 | 61 | @Transactional(readOnly = true) 62 | public List getPurchasesByUserInPeriod(User user, Date startDate, Date endDate) throws UserNotFoundException, DateWrongRangeException { 63 | if ( !userRepository.existsById(user.getId()) ) { 64 | throw new UserNotFoundException(); 65 | } 66 | if ( startDate.compareTo(endDate) >= 0 ) { 67 | throw new DateWrongRangeException(); 68 | } 69 | return purchaseRepository.findByBuyerInPeriod(startDate, endDate, user); 70 | } 71 | 72 | @Transactional(readOnly = true) 73 | public List getAllPurchases() { 74 | return purchaseRepository.findAll(); 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | jar 6 | 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 3.2.5 11 | 12 | 13 | 14 | it.frankladder 15 | fakestore 16 | 0.0.1-SNAPSHOT 17 | Fake Store 18 | Demo project for Spring Boot 19 | 20 | 21 | 11 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-test 28 | test 29 | 30 | 31 | org.junit.vintage 32 | junit-vintage-engine 33 | 34 | 35 | 36 | 37 | mysql 38 | mysql-connector-java 39 | 8.0.14 40 | 41 | 42 | com.fasterxml.jackson.core 43 | jackson-databind 44 | 2.11.3 45 | 46 | 47 | javax.validation 48 | validation-api 49 | 2.0.1.Final 50 | 51 | 52 | org.projectlombok 53 | lombok 54 | 1.16.18 55 | 56 | 57 | org.springframework.security 58 | spring-security-core 59 | 6.2.4 60 | 61 | 62 | org.springframework.security 63 | spring-security-test 64 | test 65 | 66 | 67 | org.apache.commons 68 | commons-lang3 69 | 3.9 70 | 71 | 72 | com.googlecode.json-simple 73 | json-simple 74 | 1.1.1 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-starter-validation 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-starter-oauth2-resource-server 83 | 84 | 85 | org.springframework.boot 86 | spring-boot-starter-data-jpa 87 | 88 | 89 | org.springframework.boot 90 | spring-boot-starter-security 91 | 92 | 93 | org.springframework.boot 94 | spring-boot-starter-web 95 | 96 | 97 | org.springframework.boot 98 | spring-boot-devtools 99 | runtime 100 | true 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-configuration-processor 105 | true 106 | 107 | 108 | org.projectlombok 109 | lombok 110 | true 111 | 112 | 113 | org.springframework.boot 114 | spring-boot-starter-test 115 | test 116 | 117 | 118 | org.junit.vintage 119 | junit-vintage-engine 120 | 121 | 122 | 123 | 124 | org.springframework.security 125 | spring-security-test 126 | test 127 | 128 | 129 | 130 | 131 | 132 | 133 | org.springframework.boot 134 | spring-boot-maven-plugin 135 | 136 | 137 | org.apache.maven.plugins 138 | maven-compiler-plugin 139 | 140 | ${java.version} 141 | ${java.version} 142 | 143 | 144 | 145 | org.projectlombok 146 | lombok 147 | ${lombok.version} 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /webpack.generated.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NOTICE: this is an auto-generated file 3 | * 4 | * This file has been generated by the `flow:prepare-frontend` maven goal. 5 | * This file will be overwritten on every run. Any custom changes should be made to webpack.config.js 6 | */ 7 | const fs = require('fs'); 8 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 9 | const CompressionPlugin = require('compression-webpack-plugin'); 10 | const {BabelMultiTargetPlugin} = require('webpack-babel-multi-target-plugin'); 11 | 12 | const path = require('path'); 13 | const baseDir = path.resolve(__dirname); 14 | // the folder of app resources (main.js and flow templates) 15 | const frontendFolder = require('path').resolve(__dirname, 'frontend'); 16 | 17 | const fileNameOfTheFlowGeneratedMainEntryPoint = require('path').resolve(__dirname, 'target/frontend/generated-flow-imports.js'); 18 | const mavenOutputFolderForFlowBundledFiles = require('path').resolve(__dirname, 'target/classes/META-INF/VAADIN'); 19 | 20 | // public path for resources, must match Flow VAADIN_BUILD 21 | const build = 'build'; 22 | // public path for resources, must match the request used in flow to get the /build/stats.json file 23 | const config = 'config'; 24 | // folder for outputting index.js bundle, etc. 25 | const buildFolder = `${mavenOutputFolderForFlowBundledFiles}/${build}`; 26 | // folder for outputting stats.json 27 | const confFolder = `${mavenOutputFolderForFlowBundledFiles}/${config}`; 28 | // file which is used by flow to read templates for server `@Id` binding 29 | const statsFile = `${confFolder}/stats.json`; 30 | // make sure that build folder exists before outputting anything 31 | const mkdirp = require('mkdirp'); 32 | mkdirp(buildFolder); 33 | mkdirp(confFolder); 34 | 35 | const devMode = process.argv.find(v => v.indexOf('webpack-dev-server') >= 0); 36 | let stats; 37 | 38 | const watchDogPrefix = '--watchDogPort='; 39 | let watchDogPort = process.argv.find(v => v.indexOf(watchDogPrefix) >= 0); 40 | if (watchDogPort){ 41 | watchDogPort = watchDogPort.substr(watchDogPrefix.length); 42 | } 43 | 44 | const net = require('net'); 45 | 46 | function setupWatchDog(){ 47 | var client = new net.Socket(); 48 | client.connect(watchDogPort, 'localhost'); 49 | 50 | client.on('error', function(){ 51 | console.log("Watchdog connection error. Terminating webpack process..."); 52 | client.destroy(); 53 | process.exit(0); 54 | }); 55 | 56 | client.on('close', function() { 57 | client.destroy(); 58 | setupWatchDog(); 59 | }); 60 | } 61 | 62 | if (watchDogPort){ 63 | setupWatchDog(); 64 | } 65 | 66 | 67 | exports = { 68 | frontendFolder: `${frontendFolder}`, 69 | buildFolder: `${buildFolder}`, 70 | confFolder: `${confFolder}` 71 | }; 72 | 73 | module.exports = { 74 | mode: 'production', 75 | context: frontendFolder, 76 | entry: { 77 | bundle: fileNameOfTheFlowGeneratedMainEntryPoint 78 | }, 79 | 80 | output: { 81 | filename: `${build}/vaadin-[name]-[contenthash].cache.js`, 82 | path: mavenOutputFolderForFlowBundledFiles, 83 | publicPath: 'VAADIN/', 84 | }, 85 | 86 | resolve: { 87 | alias: { 88 | Frontend: frontendFolder 89 | } 90 | }, 91 | 92 | devServer: { 93 | // webpack-dev-server serves ./ , webpack-generated, and java webapp 94 | contentBase: [mavenOutputFolderForFlowBundledFiles, 'src/main/webapp'], 95 | after: function(app, server) { 96 | app.get(`/stats.json`, function(req, res) { 97 | res.json(stats.toJson()); 98 | }); 99 | app.get(`/stats.hash`, function(req, res) { 100 | res.json(stats.toJson().hash.toString()); 101 | }); 102 | app.get(`/assetsByChunkName`, function(req, res) { 103 | res.json(stats.toJson().assetsByChunkName); 104 | }); 105 | app.get(`/stop`, function(req, res) { 106 | // eslint-disable-next-line no-console 107 | console.log("Stopped 'webpack-dev-server'"); 108 | process.exit(0); 109 | }); 110 | } 111 | }, 112 | 113 | module: { 114 | rules: [ 115 | { // Files that Babel has to transpile 116 | test: /\.js$/, 117 | use: [BabelMultiTargetPlugin.loader()] 118 | }, 119 | { 120 | test: /\.css$/i, 121 | use: ['raw-loader'] 122 | } 123 | ] 124 | }, 125 | performance: { 126 | maxEntrypointSize: 2097152, // 2MB 127 | maxAssetSize: 2097152 // 2MB 128 | }, 129 | plugins: [ 130 | // Generate compressed bundles 131 | new CompressionPlugin(), 132 | 133 | // Transpile with babel, and produce different bundles per browser 134 | new BabelMultiTargetPlugin({ 135 | babel: { 136 | plugins: [ 137 | // workaround for Safari 10 scope issue (https://bugs.webkit.org/show_bug.cgi?id=159270) 138 | "@babel/plugin-transform-block-scoping", 139 | 140 | // Edge does not support spread '...' syntax in object literals (#7321) 141 | "@babel/plugin-proposal-object-rest-spread" 142 | ], 143 | 144 | presetOptions: { 145 | useBuiltIns: false // polyfills are provided from webcomponents-loader.js 146 | } 147 | }, 148 | targets: { 149 | 'es6': { // Evergreen browsers 150 | browsers: [ 151 | // It guarantees that babel outputs pure es6 in bundle and in stats.json 152 | // In the case of browsers no supporting certain feature it will be 153 | // covered by the webcomponents-loader.js 154 | 'last 1 Chrome major versions' 155 | ], 156 | }, 157 | 'es5': { // IE11 158 | browsers: [ 159 | 'ie 11' 160 | ], 161 | tagAssetsWithKey: true, // append a suffix to the file name 162 | } 163 | } 164 | }), 165 | 166 | // Generates the stats file for flow `@Id` binding. 167 | function (compiler) { 168 | compiler.hooks.afterEmit.tapAsync("FlowIdPlugin", (compilation, done) => { 169 | if (!devMode) { 170 | // eslint-disable-next-line no-console 171 | console.log(" Emitted " + statsFile) 172 | fs.writeFile(statsFile, JSON.stringify(compilation.getStats().toJson(), null, 1), done); 173 | } else { 174 | // eslint-disable-next-line no-console 175 | console.log(" Serving the 'stats.json' file dynamically."); 176 | stats = compilation.getStats(); 177 | done(); 178 | } 179 | }); 180 | }, 181 | 182 | // Copy webcomponents polyfills. They are not bundled because they 183 | // have its own loader based on browser quirks. 184 | new CopyWebpackPlugin([{ 185 | from: `${baseDir}/node_modules/@webcomponents/webcomponentsjs`, 186 | to: `${build}/webcomponentsjs/` 187 | }]), 188 | ] 189 | }; 190 | -------------------------------------------------------------------------------- /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 https://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 Maven 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 keystroke 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 set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /src/main/resources/other/Orders.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "f947f62b-bff8-4457-aa64-34a4b776a06b", 4 | "name": "Orders", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "User creation", 10 | "request": { 11 | "method": "POST", 12 | "header": [ 13 | { 14 | "key": "Content-Type", 15 | "name": "Content-Type", 16 | "type": "text", 17 | "value": "application/json" 18 | } 19 | ], 20 | "body": { 21 | "mode": "raw", 22 | "raw": "{\n\t\"code\": \"000\",\n\t\"firstName\": \"fn0\",\n\t\"lastName\": \"ln0\",\n\t\"email\": \"aaa0@aaa.aa\"\n}\n" 23 | }, 24 | "url": { 25 | "raw": "localhost:8080/users", 26 | "host": [ 27 | "localhost" 28 | ], 29 | "port": "8080", 30 | "path": [ 31 | "users" 32 | ] 33 | }, 34 | "description": "Creazione utente" 35 | }, 36 | "response": [] 37 | }, 38 | { 39 | "name": "Get all users", 40 | "protocolProfileBehavior": { 41 | "disableBodyPruning": true 42 | }, 43 | "request": { 44 | "method": "GET", 45 | "header": [ 46 | { 47 | "key": "Content-Type", 48 | "name": "Content-Type", 49 | "type": "text", 50 | "value": "application/json" 51 | } 52 | ], 53 | "body": { 54 | "mode": "raw", 55 | "raw": "" 56 | }, 57 | "url": { 58 | "raw": "localhost:8080/users", 59 | "host": [ 60 | "localhost" 61 | ], 62 | "port": "8080", 63 | "path": [ 64 | "users" 65 | ] 66 | } 67 | }, 68 | "response": [] 69 | }, 70 | { 71 | "name": "Product creation", 72 | "request": { 73 | "method": "POST", 74 | "header": [ 75 | { 76 | "key": "Content-Type", 77 | "name": "Content-Type", 78 | "type": "text", 79 | "value": "application/json" 80 | } 81 | ], 82 | "body": { 83 | "mode": "raw", 84 | "raw": "{\n\t\"name\": \"product0\",\n\t\"barCode\": \"000\",\n\t\"description\": \"description0\"\n}\n" 85 | }, 86 | "url": { 87 | "raw": "localhost:8080/products", 88 | "host": [ 89 | "localhost" 90 | ], 91 | "port": "8080", 92 | "path": [ 93 | "products" 94 | ] 95 | } 96 | }, 97 | "response": [] 98 | }, 99 | { 100 | "name": "Get all products", 101 | "protocolProfileBehavior": { 102 | "disableBodyPruning": true 103 | }, 104 | "request": { 105 | "method": "GET", 106 | "header": [ 107 | { 108 | "key": "Content-Type", 109 | "name": "Content-Type", 110 | "type": "text", 111 | "value": "application/json" 112 | } 113 | ], 114 | "body": { 115 | "mode": "raw", 116 | "raw": "" 117 | }, 118 | "url": { 119 | "raw": "localhost:8080/products", 120 | "host": [ 121 | "localhost" 122 | ], 123 | "port": "8080", 124 | "path": [ 125 | "products" 126 | ] 127 | } 128 | }, 129 | "response": [] 130 | }, 131 | { 132 | "name": "Get all products paged", 133 | "protocolProfileBehavior": { 134 | "disableBodyPruning": true 135 | }, 136 | "request": { 137 | "method": "GET", 138 | "header": [ 139 | { 140 | "key": "Content-Type", 141 | "name": "Content-Type", 142 | "type": "text", 143 | "value": "application/json" 144 | } 145 | ], 146 | "body": { 147 | "mode": "raw", 148 | "raw": "" 149 | }, 150 | "url": { 151 | "raw": "localhost:8080/products/paged/?pageNumber=0&pageSize=2&sortBy=id", 152 | "host": [ 153 | "localhost" 154 | ], 155 | "port": "8080", 156 | "path": [ 157 | "products", 158 | "paged", 159 | "" 160 | ], 161 | "query": [ 162 | { 163 | "key": "pageNumber", 164 | "value": "0" 165 | }, 166 | { 167 | "key": "pageSize", 168 | "value": "2" 169 | }, 170 | { 171 | "key": "sortBy", 172 | "value": "id" 173 | } 174 | ] 175 | } 176 | }, 177 | "response": [] 178 | }, 179 | { 180 | "name": "Get product by name", 181 | "protocolProfileBehavior": { 182 | "disableBodyPruning": true 183 | }, 184 | "request": { 185 | "method": "GET", 186 | "header": [ 187 | { 188 | "key": "Content-Type", 189 | "name": "Content-Type", 190 | "type": "text", 191 | "value": "application/json" 192 | } 193 | ], 194 | "body": { 195 | "mode": "raw", 196 | "raw": "" 197 | }, 198 | "url": { 199 | "raw": "localhost:8080/products/by_name/produc", 200 | "host": [ 201 | "localhost" 202 | ], 203 | "port": "8080", 204 | "path": [ 205 | "products", 206 | "by_name", 207 | "produc" 208 | ] 209 | } 210 | }, 211 | "response": [] 212 | }, 213 | { 214 | "name": "Purchase creation", 215 | "request": { 216 | "auth": { 217 | "type": "apikey", 218 | "apikey": [ 219 | { 220 | "key": "in", 221 | "value": "query", 222 | "type": "string" 223 | }, 224 | { 225 | "key": "key", 226 | "value": "apikey", 227 | "type": "string" 228 | }, 229 | { 230 | "key": "value", 231 | "value": "00UMW28lB0ONQjj6-C1--_z8vjbDRug6z_g83k6pKC", 232 | "type": "string" 233 | } 234 | ] 235 | }, 236 | "method": "POST", 237 | "header": [ 238 | { 239 | "key": "Content-Type", 240 | "name": "Content-Type", 241 | "type": "text", 242 | "value": "application/json" 243 | } 244 | ], 245 | "body": { 246 | "mode": "raw", 247 | "raw": "{\n\t\"buyer\": {\n\t\t\"id\": 1\n\t},\n\t\"productsInPurchase\": [ \n\t\t{\n\t\t\t\"product\": { \"id\": 1 },\n \"quantity\": 1\n\t\t},\n\t\t{\n\t\t\t\"product\": { \"id\": 2 },\n \"quantity\": 2\n\t\t}\n\t]\n}\n" 248 | }, 249 | "url": { 250 | "raw": "localhost:8080/purchases", 251 | "host": [ 252 | "localhost" 253 | ], 254 | "port": "8080", 255 | "path": [ 256 | "purchases" 257 | ] 258 | } 259 | }, 260 | "response": [] 261 | }, 262 | { 263 | "name": "Get purchases by user", 264 | "protocolProfileBehavior": { 265 | "disableBodyPruning": true 266 | }, 267 | "request": { 268 | "method": "GET", 269 | "header": [ 270 | { 271 | "key": "Content-Type", 272 | "name": "Content-Type", 273 | "type": "text", 274 | "value": "application/json" 275 | } 276 | ], 277 | "body": { 278 | "mode": "raw", 279 | "raw": "{\n\t\"id\": 1\n}" 280 | }, 281 | "url": { 282 | "raw": "localhost:8080/purchases/user", 283 | "host": [ 284 | "localhost" 285 | ], 286 | "port": "8080", 287 | "path": [ 288 | "purchases", 289 | "user" 290 | ] 291 | } 292 | }, 293 | "response": [] 294 | }, 295 | { 296 | "name": "Get purchases by user in period", 297 | "protocolProfileBehavior": { 298 | "disableBodyPruning": true 299 | }, 300 | "request": { 301 | "method": "GET", 302 | "header": [ 303 | { 304 | "key": "Content-Type", 305 | "name": "Content-Type", 306 | "type": "text", 307 | "value": "application/json" 308 | } 309 | ], 310 | "body": { 311 | "mode": "raw", 312 | "raw": "" 313 | }, 314 | "url": { 315 | "raw": "localhost:8080/purchases/1/02-03-2020/04-03-2020", 316 | "host": [ 317 | "localhost" 318 | ], 319 | "port": "8080", 320 | "path": [ 321 | "purchases", 322 | "1", 323 | "02-03-2020", 324 | "04-03-2020" 325 | ] 326 | } 327 | }, 328 | "response": [] 329 | } 330 | ] 331 | } -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ]; then 38 | 39 | if [ -f /etc/mavenrc ]; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ]; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false 51 | darwin=false 52 | mingw=false 53 | case "$(uname)" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true ;; 56 | Darwin*) 57 | darwin=true 58 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 59 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 60 | if [ -z "$JAVA_HOME" ]; then 61 | if [ -x "/usr/libexec/java_home" ]; then 62 | export JAVA_HOME="$(/usr/libexec/java_home)" 63 | else 64 | export JAVA_HOME="/Library/Java/Home" 65 | fi 66 | fi 67 | ;; 68 | esac 69 | 70 | if [ -z "$JAVA_HOME" ]; then 71 | if [ -r /etc/gentoo-release ]; then 72 | JAVA_HOME=$(java-config --jre-home) 73 | fi 74 | fi 75 | 76 | if [ -z "$M2_HOME" ]; then 77 | ## resolve links - $0 may be a link to maven's home 78 | PRG="$0" 79 | 80 | # need this for relative symlinks 81 | while [ -h "$PRG" ]; do 82 | ls=$(ls -ld "$PRG") 83 | link=$(expr "$ls" : '.*-> \(.*\)$') 84 | if expr "$link" : '/.*' >/dev/null; then 85 | PRG="$link" 86 | else 87 | PRG="$(dirname "$PRG")/$link" 88 | fi 89 | done 90 | 91 | saveddir=$(pwd) 92 | 93 | M2_HOME=$(dirname "$PRG")/.. 94 | 95 | # make it fully qualified 96 | M2_HOME=$(cd "$M2_HOME" && pwd) 97 | 98 | cd "$saveddir" 99 | # echo Using m2 at $M2_HOME 100 | fi 101 | 102 | # For Cygwin, ensure paths are in UNIX format before anything is touched 103 | if $cygwin; then 104 | [ -n "$M2_HOME" ] && 105 | M2_HOME=$(cygpath --unix "$M2_HOME") 106 | [ -n "$JAVA_HOME" ] && 107 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME") 108 | [ -n "$CLASSPATH" ] && 109 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH") 110 | fi 111 | 112 | # For Mingw, ensure paths are in UNIX format before anything is touched 113 | if $mingw; then 114 | [ -n "$M2_HOME" ] && 115 | M2_HOME="$( ( 116 | cd "$M2_HOME" 117 | pwd 118 | ))" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="$( ( 121 | cd "$JAVA_HOME" 122 | pwd 123 | ))" 124 | fi 125 | 126 | if [ -z "$JAVA_HOME" ]; then 127 | javaExecutable="$(which javac)" 128 | if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then 129 | # readlink(1) is not available as standard on Solaris 10. 130 | readLink=$(which readlink) 131 | if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then 132 | if $darwin; then 133 | javaHome="$(dirname \"$javaExecutable\")" 134 | javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac" 135 | else 136 | javaExecutable="$(readlink -f \"$javaExecutable\")" 137 | fi 138 | javaHome="$(dirname \"$javaExecutable\")" 139 | javaHome=$(expr "$javaHome" : '\(.*\)/bin') 140 | JAVA_HOME="$javaHome" 141 | export JAVA_HOME 142 | fi 143 | fi 144 | fi 145 | 146 | if [ -z "$JAVACMD" ]; then 147 | if [ -n "$JAVA_HOME" ]; then 148 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 149 | # IBM's JDK on AIX uses strange locations for the executables 150 | JAVACMD="$JAVA_HOME/jre/sh/java" 151 | else 152 | JAVACMD="$JAVA_HOME/bin/java" 153 | fi 154 | else 155 | JAVACMD="$(which java)" 156 | fi 157 | fi 158 | 159 | if [ ! -x "$JAVACMD" ]; then 160 | echo "Error: JAVA_HOME is not defined correctly." >&2 161 | echo " We cannot execute $JAVACMD" >&2 162 | exit 1 163 | fi 164 | 165 | if [ -z "$JAVA_HOME" ]; then 166 | echo "Warning: JAVA_HOME environment variable is not set." 167 | fi 168 | 169 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 170 | 171 | # traverses directory structure from process work directory to filesystem root 172 | # first directory with .mvn subdirectory is considered project base directory 173 | find_maven_basedir() { 174 | 175 | if [ -z "$1" ]; then 176 | echo "Path not specified to find_maven_basedir" 177 | return 1 178 | fi 179 | 180 | basedir="$1" 181 | wdir="$1" 182 | while [ "$wdir" != '/' ]; do 183 | if [ -d "$wdir"/.mvn ]; then 184 | basedir=$wdir 185 | break 186 | fi 187 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 188 | if [ -d "${wdir}" ]; then 189 | wdir=$( 190 | cd "$wdir/.." 191 | pwd 192 | ) 193 | fi 194 | # end of workaround 195 | done 196 | echo "${basedir}" 197 | } 198 | 199 | # concatenates all lines of a file 200 | concat_lines() { 201 | if [ -f "$1" ]; then 202 | echo "$(tr -s '\n' ' ' <"$1")" 203 | fi 204 | } 205 | 206 | BASE_DIR=$(find_maven_basedir "$(pwd)") 207 | if [ -z "$BASE_DIR" ]; then 208 | exit 1 209 | fi 210 | 211 | ########################################################################################## 212 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 213 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 214 | ########################################################################################## 215 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 216 | if [ "$MVNW_VERBOSE" = true ]; then 217 | echo "Found .mvn/wrapper/maven-wrapper.jar" 218 | fi 219 | else 220 | if [ "$MVNW_VERBOSE" = true ]; then 221 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 222 | fi 223 | if [ -n "$MVNW_REPOURL" ]; then 224 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 225 | else 226 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 227 | fi 228 | while IFS="=" read key value; do 229 | case "$key" in wrapperUrl) 230 | jarUrl="$value" 231 | break 232 | ;; 233 | esac 234 | done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 235 | if [ "$MVNW_VERBOSE" = true ]; then 236 | echo "Downloading from: $jarUrl" 237 | fi 238 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 239 | if $cygwin; then 240 | wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") 241 | fi 242 | 243 | if command -v wget >/dev/null; then 244 | if [ "$MVNW_VERBOSE" = true ]; then 245 | echo "Found wget ... using wget" 246 | fi 247 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 248 | wget "$jarUrl" -O "$wrapperJarPath" 249 | else 250 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 251 | fi 252 | elif command -v curl >/dev/null; then 253 | if [ "$MVNW_VERBOSE" = true ]; then 254 | echo "Found curl ... using curl" 255 | fi 256 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 257 | curl -o "$wrapperJarPath" "$jarUrl" -f 258 | else 259 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 260 | fi 261 | 262 | else 263 | if [ "$MVNW_VERBOSE" = true ]; then 264 | echo "Falling back to using Java to download" 265 | fi 266 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 267 | # For Cygwin, switch paths to Windows format before running javac 268 | if $cygwin; then 269 | javaClass=$(cygpath --path --windows "$javaClass") 270 | fi 271 | if [ -e "$javaClass" ]; then 272 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Compiling MavenWrapperDownloader.java ..." 275 | fi 276 | # Compiling the Java class 277 | ("$JAVA_HOME/bin/javac" "$javaClass") 278 | fi 279 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 280 | # Running the downloader 281 | if [ "$MVNW_VERBOSE" = true ]; then 282 | echo " - Running MavenWrapperDownloader.java ..." 283 | fi 284 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 285 | fi 286 | fi 287 | fi 288 | fi 289 | ########################################################################################## 290 | # End of extension 291 | ########################################################################################## 292 | 293 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 294 | if [ "$MVNW_VERBOSE" = true ]; then 295 | echo $MAVEN_PROJECTBASEDIR 296 | fi 297 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 298 | 299 | # For Cygwin, switch paths to Windows format before running java 300 | if $cygwin; then 301 | [ -n "$M2_HOME" ] && 302 | M2_HOME=$(cygpath --path --windows "$M2_HOME") 303 | [ -n "$JAVA_HOME" ] && 304 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") 305 | [ -n "$CLASSPATH" ] && 306 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH") 307 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 308 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") 309 | fi 310 | 311 | # Provide a "standardized" way to retrieve the CLI args that will 312 | # work with both Windows and non-Windows executions. 313 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 314 | export MAVEN_CMD_LINE_ARGS 315 | 316 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 317 | 318 | exec "$JAVACMD" \ 319 | $MAVEN_OPTS \ 320 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 321 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 322 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 323 | --------------------------------------------------------------------------------