A Project Submitted in Partial Fulfillment of The Requirements For The Degree of
A Project Submitted in Partial Fulfillment of The Requirements For The Degree of
A project submitted
in partial fulfillment of the requirements
for the degree of
MCA
By
ANSHIKA JINDAL
1906000001794
i
UNDERTAKING
ii
iii
CERTIFICATE BY SUPERVISOR
iv
Preface
v
Acknowledgements
I take upon this opportunity to acknowledge the many people who help me. I am
deeply indebted to my mentor MR. SANJEEV PANWAR. I would like to thank
MR. HIMANSHU SIROHI . I further thank to DR. SHASHIRAJ TEOTIA. I owe
my sincere gratitude towards all my teachers. My heartfelt thanks to you all. I also
express my deepest gratitude to MR. SANJEEV PANWAR
ANSHIKA JINDAL
vi
Table of Contents
Undertaking.....................................................................ii
Abstract. .........................................................................iii
Certificate by supervisor.................................................iv
Preface.............................................................................v
Acknowledgements ........................................................vi
1 Introduction..................................................................vii
1.1 Motivation....................…………..……...……….viii
1.2 Problem and solutions.............................................ix
1.1.1 Some Important Remarks .…..……………………x
1.1.2 Solutions..................................................................1
1.1.3 Scope........................................................................2
1.1.4 Platform Specifications ...........................................3
2 Code of the project...................................................4-205
3 Related work.............................................................206-241
4 Conclusion................................................................242
5 References ................................................................245
vii
1. Introduction
1.1 Goal
Shopping has long been considered a recreational activity by many.
Shopping online is no exception. The goal of this application is to
develop a web based interface for online retailers. The system would
be easy to use and hence make the shopping experience pleasant for
the users. The goal of this application is
•
To develop an easy to use web based interface where users can
viii
•
Drag and Drop feature which would allow the users to add a
product to or remove a product from the shopping cart by
dragging the product in to the shopping cart or out of the
shopping cart.
•
A user can view the complete specification of the product
along with various images and also view the customer reviews
of the product. They can also write their own reviews.
Problem:
• The basic problems with the existing systems are the non-interactive
environment they provide to the users.
• The use of traditional user interfaces which make continuous post backs to
the server; each post back makes a call to the server, gets the response and
then refreshes the entire web form to display the result. This scenario adds an
extra trade off causing a delay in displaying the results
• A search engine that would display the results without allowing the users to
further filter the results based on various parameters.
ix
Solution:
• The users could subscribe for price alerts which would enable
particular level.
process.
2
1.4 Platform Specifications – Deployment
1.4.1 Hardware Specification
Processor P IV
RAM 250 MB
3
CODE OF THE PROJECT
Eclipse.preferences.version=1
Encoding//src/main/java=UTF-8
Encoding//src/main/resources=UTF-8
Encoding//src/test/java=UTF-8
Encoding/<project>=UTF-8
Eclipse.preferences.version=1
Org.eclipse.jdt.apt.aptEnabled=true
4
Org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations
Org.eclipse.jdt.apt.genTestSrcDir=target\\generatedtestsources\\testannotat
ions
Eclipse.preferences.version=1
Org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
Org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
Org.eclipse.jdt.core.compiler.compliance=1.8
Org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
Org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
Org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
Org.eclipse.jdt.core.compiler.processAnnotations=enabled
Org.eclipse.jdt.core.compiler.release=disabled
Org.eclipse.jdt.core.compiler.source=1.8
5
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1 boot.validation.initialized=true
eclipse.preferences.version=1
package com.khomsi.site_project.configuration;
org.springframework.context.annotation.Configuration;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
6
@Configuration
Public class EncryptionConfig {
@Bean
Package com.khomsi.site_project.configuration;
Import org.springframework.context.annotation.Bean;
7
Import
org.springframework.web.servlet.config.annotation.InterceptorRegistry;
Import
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
;
Import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
Import org.springframework.web.servlet.i18n.SessionLocaleResolver;
Import java.util.Locale;
@Configuration
@Bean
SessionLocaleResolver();
8
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
@Bean
url localeChangeInterceptor.setParamName(“lang”);
return localeChangeInterceptor;
@Override
Registry.addInterceptor(localeChangeInterceptor());
}
}
9
Package com.khomsi.site_project.configuration;
Import com.khomsi.site_project.entity.Role;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.context.annotation.Bean;
Import
org.springframework.security.config.annotation.authentication.builders.A
u thenticationManagerBuilder;
Import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
Import
10
org.springframework.security.config.annotation.web.configuration.Enabl
e WebSecurity; Import
org.springframework.security.config.annotation.web.configuration.WebSe
curityConfigurerAdapter;
Import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
Import org.springframework.security.crypto.password.PasswordEncoder;
Import
org.springframework.security.web.util.matcher.AntPathRequestMatcher;
Import javax.sql.DataSource;
@EnableWebSecurity
Public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Autowired
/*
unsuccessful login
*/
//
@Override
Protected void configure(HttpSecurity http) throws Exception {
// http.csrf().disable().authorizeRequests()
http.authorizeRequests().antMatchers(“/admin/**”).hasAuthority(Role.A
DMIN.getAuthority())
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(“/login”)
.loginProcessingUrl(“/login”)
.defaultSuccessUrl(“/”, true)
12
.permitAll()
.and()
.logout().logoutSuccessUrl(“/”)
.logoutRequestMatcher(new
AntPathRequestMatcher(“/logout”)).permitAll().and().exceptionHandling(
)
.accessDeniedPage(“/error403”);
@Override
Protected void configure(AuthenticationManagerBuilder auth) throws
Exception {
Auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder)
.usersByUsernameQuery(“select login, password, ‘true’ as
enabled from user where login=?”)
.authoritiesByUsernameQuery(“select login, role from user
where login=?”);
Package com.khomsi.site_project.controller;
13
Import com.khomsi.site_project.entity.*;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import com.khomsi.site_project.exception.OrderNotFoundException;
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import com.khomsi.site_project.exception.UserNotFoundException;
Import com.khomsi.site_project.service.*;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.*;
Import org.springframework.web.servlet.mvc.support.RedirectAttributes;
Import org.webjars.NotFoundException;
14
Import java.util.List;
@Controller
@RequestMapping(“/admin”)
@Autowired
@Autowired
@Autowired
15
@Autowired
@Autowired
@Autowired
Return “admin/admin-panel”;
@GetMapping(“/products”)
16
@GetMapping(“/products/edit/{id}”)
Public String updateProduct(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes attributes) {
Try {
Model.addAttribute(“product”, product);
Model.addAttribute(“vendorList”, vendorList);
Model.addAttribute(“categoryList”, categoryList);
} catch (ProductNotFoundException e) {
Attributes.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/product/products”;
Return “admin/product/product_form”;
@GetMapping(“/products/new”)
Public String addProduct(Model model) {
17
List<Vendor> vendorList = vendorService.getAllVendors();
List<Category> categoryList =
categoryService.listCategoriesUserInForm();
Model.addAttribute(“product”, new Product());
Model.addAttribute(“vendorList”, vendorList);
Model.addAttribute(“categoryList”, categoryList);
Return “admin/product/product_form”;
}
@PostMapping(“/products/save”)
productService.saveProduct(product);
@GetMapping(“/products/delete/{id}”)
18
Public String deleteProduct(@PathVariable(name = “id”) Integer id,
productService.deleteProduct(id);
redirect.addFlashAttribute(“message”,
Redirect.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/products”;
@GetMapping(“/users”)
Public String listUsersFirstPage(Model model) {
@GetMapping(“/users/new”)
Return “admin/user/user_form”;
}
@PostMapping(“/users/save”)
userService.saveUser(user);
successfully”);
return “redirect:/admin/users”;
@GetMapping(“/users/edit/{id}”)
Public String updateUser(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes redirect) {
Try {
20
UserInfo userInfo = userInfoService.getUserDetail(id);
Model.addAttribute(“user”, user);
Model.addAttribute(“userInfo”, userInfo);
Model.addAttribute(“roles”, Role.values());
} catch (UserNotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/users”;
Return “admin/user/user_form”; }
@GetMapping(“/users/delete/{id}”)
Public String deleteUser(@PathVariable(name = “id”) Integer id,
RedirectAttributes redirect) {
Try { userService.deleteUser(id);
redirect.addFlashAttribute(“message”,
} catch (UserNotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
21
}
Return “redirect:/admin/users”;
@GetMapping(“/categories”)
Public String listCategoriesFirstPage(Model model) {
@GetMapping(“/categories/edit/{id}”)
Model.addAttribute(“category”, category);
Model.addAttribute(“categoryList”, categoryList);
Return “admin/category/category_form”;
22
} catch (CategoryNotFoundException e) {
Attributes.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/categories”;
@GetMapping(“/categories/new”)
Public String addCategory(Model model) {
List<Category> categoryList =
categoryService.listCategoriesUserInForm();
Model.addAttribute(“categoryList”, categoryList);
Return “admin/category/category_form”; }
@PostMapping(“/categories/save”)
Public String saveCategory(@ModelAttribute Category category,
RedirectAttributes attributes) {
23
categoryService.saveCategory(category);
attributes.addFlashAttribute(“message”, “The category has been
saved successfully”); return “redirect:/admin/categories”;
@GetMapping(“/categories/delete/{id}”)
categoryService.deleteCategory(id);
redirect.addFlashAttribute(“message”,
} catch (CategoryNotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
}
Return “redirect:/admin/categories”;
@GetMapping(“/vendors”)
24
Public String listVendorsFirstPage(Model model) {
@GetMapping(“/vendors/new”)
Return “admin/vendor/vendor_form”;
}
@PostMapping(“/vendors/save”)
vendorService.saveVendor(vendor);
}
@GetMapping(“/vendors/edit/{id}”)
Public String updateVendor(@PathVariable(name = “id”) int id, Model
model, RedirectAttributes redirect) {
Try {
25
Vendor vendor = vendorService.getVendor(id);
Model.addAttribute(“vendor”, vendor);
} catch (NotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/vendors”;
Return “admin/vendor/vendor_form”;
@GetMapping(“/vendors/delete/{id}”)
Public String deleteVendor(@PathVariable(name = “id”) Integer id,
vendorService.deleteVendor(id);
redirect.addFlashAttribute(“message”,
Redirect.addFlashAttribute(“message”, e.getMessage());
26
}
Return “redirect:/admin/vendors”;
}
@GetMapping(“/orders”)
@PostMapping(“/orders/save”)
ordersService.saveOrder(order);
@GetMapping(“/orders/edit/{id}”)
Try {
Order order = ordersService.getOrder(id);
27
Model.addAttribute(“orderTypes”, OrderType.values());
Model.addAttribute(“order”, order);
} catch (NotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
Return “redirect:/admin/orders”;
Return “admin/orders/order_form”;
@GetMapping(“/orders/delete/{id}”)
redirect.addFlashAttribute(“message”,
“The orders ID “ + id + “ has been deleted successfully”);
} catch (OrderNotFoundException e) {
Redirect.addFlashAttribute(“message”, e.getMessage());
28
}
Return “redirect:/admin/orders”;
@GetMapping(“/order_baskets”)
Model.addAttribute(“orderBaskets”,
orderBasketService.getAllOrderBaskets());
Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());
Return “/error/404”;
Return “admin/order_basket/order_baskets”;
29
Package com.khomsi.site_project.controller;
Import com.khomsi.site_project.entity.*;
Import com.khomsi.site_project.service.*;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping; Import
org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.bind.annotation.ResponseBody;
30
Import java.util.List;
@Controller
Public class AdminTools {
@Autowired
Private UserService userService;
@Autowired
Private VendorService vendorService;
@Autowired
Private OrdersService ordersService;
@Autowired
Private ProductService productService;
@Autowired
Private CategoryService categoryService;
@PostMapping(“/users/check_login”)
Public @ResponseBody String checkLoginUnique(@Param(“id”)
Integer id, @Param(“login”) String login) {
Return userService.isLoginUnique(id, login);
}
/*
Added this method to check unique login for user while he’s registration
You can modify it to have more unique fields.
31
(if you need unique fields in admin panel for user, change another
methods like isLoginUnique)
*/
@PostMapping(“/user/check”) Public
@ResponseBody String
checkLoginRegistration(@Param(“login”) String login)
{
Return userService.checkLoginRegistration(login) ? “OK” :
“Duplicate”;
}
@PostMapping(“/categories/check”)
Public @ResponseBody String checkCategory(@Param(“id”) Integer
id, @Param(“title”) String title,
@Param(“alias”) String alias) {
Return categoryService.checkCategoryTitle(id, title, alias);
}
@PostMapping(“/vendors/check”)
Public @ResponseBody String checkVendor(@Param(“id”) Integer id,
@Param(“title”) String title) {
Return vendorService.checkVendorTitle(id, title);
}
//Controller in admin panel for users
@GetMapping(“/admin/users/page/{pageNum}”)
32
Public String listUsersByPage(@PathVariable(name = “pageNum”) int
pageNum, Model model) {
Page<User> page = userService.listByPage(pageNum);
List<User> listUsers = page.getContent();
return “admin/user/users”;
}
//Controller in admin panel for vendors
@GetMapping(“/admin/vendors/page/{pageNum}”)
Public String listVendorsByPage(@PathVariable(name = “pageNum”)
int pageNum, Model model) {
Page<Vendor> page = vendorService.listByPage(pageNum);
List<Vendor> vendorList = page.getContent();
33
pageCountMethod(pageNum, model, page, startCount, endCount);
model.addAttribute(“vendors”, vendorList);
return “admin/vendor/vendors”;
}
//Controller in admin panel for orders
@GetMapping(“/admin/orders/page/{pageNum}”)
Public String listOrdersByPage(@PathVariable(name = “pageNum”) int
pageNum, Model model) {
Page<Order> page = ordersService.listByPage(pageNum);
List<Order> orderList = page.getContent();
model.addAttribute(“orders”, orderList);
return “admin/orders/orders”;
34
}
Model.addAttribute(“currentPage”, pageNum);
Model.addAttribute(“categories”, categoryList);
35
Return “admin/category/categories”;
}
//Controller in admin panel for products
@GetMapping(“/admin/products/page/{pageNum}”)
Public String listProductsByPage(@PathVariable(name = “pageNum”)
int pageNum, Model model,
@Param(“sortField”) String sortField,
@Param(“sortDir”) String sortDir,
@Param(“keyword”) String keyword,
@Param(“categoryId”) Integer categoryId)
{ Page<Product> page =
productService.listByPage(pageNum, sortField, sortDir, keyword,
categoryId); List<Category> listCategories =
categoryService.listCategoriesUserInForm();
36
If (endCount > page.getTotalElements()) {
endCount = page.getTotalElements();
}
String reverseSortDir = sortDir.equals(“asc”) ? “desc” : “asc”;
return “admin/product/products”;
}
Public void pageCountMethod(@PathVariable(“pageNum”) int
pageNum, Model model, Page<?> page,
Long startCount, long endCount) {
If (endCount > page.getTotalElements()) {
endCount = page.getTotalElements();
}
Model.addAttribute(“currentPage”, pageNum);
Model.addAttribute(“totalPages”, page.getTotalPages());
Model.addAttribute(“startCount”, startCount);
Model.addAttribute(“endCount”, endCount);
37
Model.addAttribute(“totalItems”, page.getTotalElements());
}
}
Package com.khomsi.site_project.controller;
Import com.khomsi.site_project.entity.*;
38
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import com.khomsi.site_project.repository.CategoryRepository;
Import com.khomsi.site_project.service.ProductService;
Import com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired; Import
org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.webjars.NotFoundException;
Import java.security.Principal;
Import java.util.List;
@Controller
Public class MainController {
@Autowired
Private UserService userService;
@Autowired
Private CategoryRepository categoryRep;
@Autowired
Private ProductService productService;
39
@GetMapping(“/”)
Public String index(Model model) {
Model.addAttribute(“listCategories”, categoryRep.findAllEnabled());
Try {
Model.addAttribute(“listProducts”,
productService.getRandomAmountOfProducts());
} catch (ProductNotFoundException ex) {
Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());
Return “/error/404”;
}
Return “index”;
}
@GetMapping(“/registration”)
Public String registration(Model model) {
Model.addAttribute(“user”, new User());
Model.addAttribute(“userInfo”, new UserInfo());
Return “registration”;
}
@PostMapping(“/registration”)
Public String registration(User user, UserInfo userInfo) {
User.setRole(Role.USER);
User.setUserInfo(userInfo);
40
userInfo.setUser(user);
userService.saveUser(user);
return “redirect:/”;
}
@GetMapping(“/basket”)
Public String showShoppingCard(Model model,
Principal principal) {
If (principal != null) {
List<OrderBasket> orderBaskets =
userService.getUserByLogin(principal.getName()).getOrderBaskets();
Model.addAttribute(“orderBaskets”, orderBaskets);
Model.addAttribute(“order”, new Order());
} else {
Model.addAttribute(“error”, new NotFoundException(“Order
basket was not found”));
Return “/error/404”;
}
Return “shopping-cart”;
}
@GetMapping(“/category”)
Public String showCategories(Model model) { List<Category>
listEnabledCategories =
categoryRep.findAllEnabled();
Model.addAttribute(“listCategories”, listEnabledCategories);
Return “category”;
41
}
}
42
Package com.khomsi.site_project.controller;
Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.OrderType;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.service.OrdersService;
Import com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.core.io.ClassPathResource;
Import org.springframework.mail.javamail.JavaMailSender;
Import org.springframework.mail.javamail.MimeMessageHelper;
Import org.springframework.orm.jpa.JpaSystemException;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.servlet.mvc.support.RedirectAttributes;
Import org.webjars.NotFoundException;
Import javax.mail.MessagingException;
Import javax.mail.internet.MimeMessage;
Import java.io.UnsupportedEncodingException;
43
Import java.security.Principal;
Import java.util.List;
@Controller
Public class OrderController {
@Autowired
JavaMailSender javaMailSender;
@Autowired
Private OrdersService ordersService;
@Autowired
Private UserService userService;
@GetMapping(“/orders”)
Public String showOrders(Model model, Principal principal) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
List<Order> orders = ordersService.getAllOrdersByUser(user);
Model.addAttribute(“orders”, orders);
} else {
44
Model.addAttribute(“error”, new NotFoundException(“Orders was
not found”));
Return “/error/404”;
}
Return “/user/orders”;
}
@GetMapping(“/payment”)
Public String createOrders(Model model, Principal principal) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
List<OrderBasket> orderBaskets = user.getOrderBaskets();
Model.addAttribute(“order”, new Order());
Model.addAttribute(“user”, user);
Model.addAttribute(“orderBaskets”, orderBaskets);
Model.addAttribute(“waiting”, “waiting”);
Model.addAttribute(“payed”, “payed”);
} else {
Model.addAttribute(“error”, new NotFoundException(“Orders for
payment was not found”));
Return “/error/404”;
}
Return “checkout”;
}
@PostMapping(“/payment”)
45
Public String saveOrder(Order newOrder, Principal principal,
Model model, RedirectAttributes attributes) {
User user = userService.getUserByLogin(principal.getName());
List<OrderBasket> orderBaskets = user.getOrderBaskets();
newOrder.setUser(user);
newOrder.setTotalPrice(ordersService.countSum(orderBaskets)); try
{
ordersService.saveOrder(newOrder);
attributes.addFlashAttribute(“message”, “Order was completed! Check
your email!”); sendVerificationEmail(newOrder);
} catch (JpaSystemException | MessagingException |
UnsupportedEncodingException ex) {
Model.addAttribute(“error”,
ex.getCause().getCause().getMessage());
Return “error/404”;
}
Return “redirect:/orders”;
}
/*
* Method that creates the email with orders that will be sent to user’s
email
* */
Private void sendVerificationEmail(Order order)
46
Throws MessagingException, UnsupportedEncodingException {
String shipping = order.getShippingType() == 0 ? “Speed Delivery” :
“Slow Delivery”;
Helper.setFrom(demo@outlook.com, senderName);
Helper.setTo(order.getUser().getEmail());
Helper.setSubject(subject);
Helper.setText(mailContent, true);
47
ClassPathResource pathResource = new
ClassPathResource(“/static/assets/email.gif”);
Helper.addInline(“logoImage”, pathResource);
// javaMailSender.send(message);
}
}
Apackage com.khomsi.site_project.controller;
Import com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import com.khomsi.site_project.exception.ProductNotFoundException;
48
Import com.khomsi.site_project.service.CategoryService;
Import com.khomsi.site_project.service.ProductService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.repository.query.Param;
Import org.springframework.stereotype.Controller;
Import org.springframework.ui.Model;
Import org.springframework.util.StringUtils;
Import org.springframework.web.bind.annotation.GetMapping;
Import org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping; Import
org.springframework.web.bind.annotation.ResponseBody;
Import java.util.List;
@Controller
Public class ProductController {
@Autowired
Private ProductService productService;
@Autowired
Private CategoryService categoryService;
@Autowired
Private AdminTools adminTools;
@GetMapping({“/category/{category_alias}”})
Public String viewCategoryFirstPage(@PathVariable(“category_alias”)
String alias,
49
Model model) {
Return viewCategoryByPage(alias, model, 1);
}
@GetMapping(“/category/{category_alias}/page/{pageNum}”)
Public String viewCategoryByPage(@PathVariable(“category_alias”)
String alias,
Model model, @PathVariable(“pageNum”) int
pageNum) {
Try {
Category category = categoryService.getCategoryByAlias(alias);
List<Category> listCategoryParents =
categoryService.getCategoryParents(category); Page<Product>
pageProduct = productService.listByCategory(pageNum, category.getId());
List<Product> listProducts = pageProduct.getContent();
Long startCount = (pageNum – 1) *
ProductService.PRODUCTS_PER_PAGE + 1;
Long endCount = startCount +
ProductService.PRODUCTS_PER_PAGE – 1;
50
model.addAttribute(“category”, category);
return “product/products_by_category”; } catch
(CategoryNotFoundException e) {
Model.addAttribute(“error”, e.getLocalizedMessage());
Return “error/404”;
} }
@GetMapping(“/product/{product_alias}”)
Public String viewProductDetails(@PathVariable(“product_alias”)
String alias, Model model) {
Try {
Product product = productService.getProduct(alias);
// List<Category> listCategoryParents =
categoryService.getCategoryParents(product.getCategory());
// model.addAttribute(“listCategoryParents”, listCategoryParents);
Model.addAttribute(“product”, product);
Return “product/product-page”;
} catch (ProductNotFoundException e) {
Model.addAttribute(“error”, e.getLocalizedMessage());
Return “error/404”;
} }
51
@PostMapping(“/products/check_unique”)
Public @ResponseBody String checkUnique(@Param(“id”) Integer id,
@Param(“title”) String title) {
Return productService.checkUnique(id, title);
}
@GetMapping(“/search”)
Public String searchFirstPage(@Param(“keyword”) String keyword,
Model model) {
Return searchByPage(keyword, 1, model);
}
/*
* We need param of page num, so i use pathVariable
*/
@GetMapping(“/search/page/{pageNum}”)
Public String searchByPage(@Param(“keyword”) String keyword,
@PathVariable(“pageNum”) int pageNum,
Model model) {
Page<Product> productsPage = productService.search(keyword,
pageNum);
List<Product> resultList = productsPage.getContent();
52
ProductService.SEARCH_RESULTS_PAGE + 1;
Long endCount = startCount +
ProductService.SEARCH_RESULTS_PAGE – 1;
adminTools.pageCountMethod(pageNum, model, productsPage,
startCount, endCount);
model.addAttribute(“pageTitle”, StringUtils.capitalize(keyword) + “
– Search Result”);
model.addAttribute(“keyword”, keyword);
model.addAttribute(“resultList”, resultList);
return “product/search_result”;
}
}
53
Package com.khomsi.site_project.controller;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.service.OrderBasketService; Import
com.khomsi.site_project.service.UserService;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.web.bind.annotation.PathVariable;
Import org.springframework.web.bind.annotation.PostMapping;
Import org.springframework.web.bind.annotation.RestController;
Import java.security.Principal;
@RestController
Public class ShoppingCartRestController {
@Autowired
Private OrderBasketService orderBasketService;
@Autowired
Private UserService userService;
@PostMapping(“/basket/add/{pid}/{qty}”)
54
Public String addProductToBasket(@PathVariable(“pid”) Integer
productId,
@PathVariable(“qty”) Integer quantity,
Principal principal) {
If (principal == null) {
Return “You must login to add this product to your shopping
basket”;
}
User user = userService.getUserByLogin(principal.getName());
If (user == null) return “You must login to add this product to your
shopping basket”;
Return String.valueOf(subtotal);
}
@PostMapping(“/basket/remove/{pid}”)
Public String removeProductFromBasket(@PathVariable(“pid”) Integer
productId,
Principal principal) {
If (principal == null) {
Return “You must login to remove product”;
}
User user = userService.getUserByLogin(principal.getName());
return “The product has been removed from your shopping basket.”;
56
}
Package com.khomsi.site_project.controller;
Import java.security.Principal;
@Controller
@RequestMapping(“/profile”)
Public class UserController {
@Autowired
Private UserService userService;
@Autowired
Private PasswordEncoder passwordEncoder;
@GetMapping({“/”, “”})
Public String getUserInfo(Principal principal, Model model) {
If (principal != null) {
User user = userService.getUserByLogin(principal.getName());
UserInfo userInfo = user.getUserInfo();
Model.addAttribute(“userDetails”, userInfo);
Model.addAttribute(“user”, user);
Return “/user/user-main”;
} else {
58
Model.addAttribute(“error”, new NotFoundException(“User was
not found”));
Return “error/404”;
} }
@Get
Mapp
ing(“/
edit”)
Public String showEditPage(Principal principal, Model model) {
User user = userService.getUserByLogin(principal.getName());
UserInfo userInfo = user.getUserInfo();
Model.addAttribute(“userDetails”, userInfo);
Model.addAttribute(“user”, user);
Return “/user/user-edit”;
}
@PostMapping(“/edit”)
Public String editUser(Principal principal, User user, BindingResult
bindingResult) {
User newUser = userService.getUserByLogin(principal.getName());
If (!user.getPassword().equals(“”)) {
If (!passwordEncoder.matches(user.getPassword(),
newUser.getPassword())) {
59
newUser.setPassword(passwordEncoder.encode(user.getPassword()));
} else {
ObjectError error = new ObjectError(“globalError”,
“The password must not be the same.”);
bindingResult.addError(error);
System.err.println(bindingResult.hasErrors());
Return “/user/user-edit”;
}
}
newUser.getUserInfo().setName(user.getUserInfo().getName());
newUser.getUserInfo().setSurname(user.getUserInfo().getSurname())
;
newUser.getUserInfo().setPhone(user.getUserInfo().getPhone());
userService.saveUser(newUser); return “redirect:/profile”; }
60
Package com.khomsi.site_project.entity;
Import lombok.Getter;
Import lombok.NoArgsConstructor;
Import lombok.Setter;
Import lombok.ToString;
Import javax.persistence.*;
Import java.util.HashSet;
Import java.util.List;
Import java.util.Set;
@NoArgsConstructor
@Getter
@Setter
@Entity
61
@Table(name = “category”)
Public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”, nullable = false)
Private Integer id;
@Column(name = “image”)
Private String imageURL;
@Column(name = “enabled”, nullable =
false)
Private Boolean enabled;
62
Private Category parent;
@OneToMany(mappedBy = “parent”)
@OrderBy(“title asc”)
@ToString.Exclude
Private Set<Category> children = new HashSet<>();
63
Public String getTitle() {
Return title;
}
Public void setTitle(String title) {
This.title = title;
}
Public String getImageURL() {
Return imageURL;
}
Public void setImageURL(String imageURL) {
This.imageURL = imageURL;
}
Public Boolean getEnabled() {
Return enabled;
}
Public void setEnabled(Boolean enabled) {
This.enabled = enabled;
}
Public Category getParent() {
Return parent;
}
64
Public void setParent(Category parent) { This.parent = parent; }
Public Set<Category> getChildren() {
Return children;
}
Public void setChildren(Set<Category> children) {
This.children = children;
}
Public List<Product> getProducts() {
Return products;
}
Public void setProducts(List<Product> products) {
This.products = products;
}
Public String getAllParentsIDs() {
Return allParentsIDs;
}
Public void setAllParentsIDs(String allParentsIDs) {
This.allParentsIDs = allParentsIDs;
}
return copyCategory;
}
Public static Category copyIdAndTitle(Integer id, String title)
{ Category copyCategory = new Category();
copyCategory.setId(id); copyCategory.setTitle(title);
return copyCategory;
}
Public static Category copyFull(Category category) {
Category copyCategory = new Category();
copyCategory.setId(category.getId());
copyCategory.setTitle(category.getTitle());
copyCategory.setAlias(category.getAlias());
66
copyCategory.setImageURL(category.getImageURL());
copyCategory.setEnabled(category.getEnabled());
return copyCategory;
}
Public static Category copyFull(Category category, String title)
{ Category copyCategory = Category.copyFull(category);
copyCategory.setTitle(title); return copyCategory;
}
Public Category(Integer id) {
This.id = id;
}
Public Category(String title, Category parent) {
This(title);
This.parent = parent;
}
Public Category(String title) {
This.title = title;
This.alias = title;
This.imageURL = “default.png”;
}
Public Category(Integer id, String title, String alias, String imageURL,
Boolean enabled, Category parent) {
This.id = id;
This.title = title;
67
This.alias = alias;
This.imageURL = imageURL;
This.enabled = enabled;
This.parent = parent;
}
}
Package com.khomsi.site_project.entity;
Import lombok.*;
Import org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;
Import javax.persistence.*;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
68
@ToString
@Entity
@Table(name = “delivery”)
Public class Delivery {
@Id
@Column(name = “orders_id”)
Private Integer id;
@MapsId
@OneToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “orders_id”)
@ToString.Exclude
Private Order order;
@Enumerated(EnumType.STRI
NG)
@Column(name = “status”) Private
DeliveryStatus status;
Package com.khomsi.site_project.entity;
69
Public enum DeliveryStatus {
Обработка,
Отправлено,
Отмена,
Доставлено,
}
70
Package com.khomsi.site_project.entity;
Import lombok.*;
Import javax.persistence.*;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “orders”)
Public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private int id;
@Enumerated(EnumType.STRING)
71
@Column(name = “order_status”)
Private OrderType orderStatus;
@Column(name = “shipping_type”)
Private int shippingType;
@Column(name = “city”)
Private String city;
@Column(name = “address”)
Private String address;
@Column(name = “total_price”)
Private Float totalPrice;
72
Private Delivery delivery;
Public int getId() {
Return id;
}
Public void setId(int id) {
This.id = id;
}
73
Public int getShippingType() {
Return shippingType;
}
74
}
Package com.khomsi.site_project.entity;
Import lombok.*;
Import javax.persistence.*;
Import java.util.LinkedHashSet;
75
Import java.util.List;
Import java.util.Set;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “order_basket”)
Public class OrderBasket {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private int id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = “product_id”)
@ToString.Exclude
Private Product product;
76
@JoinColumn(name = “user_id”)
@ToString.Exclude Private
User user;
@Column(name = “quantity”)
Private int quantity;
//We use temporary field that is not in db for business logic(we don’t
need to save it in db)
@Transient
Public float getSubtotal() {
Return this.product.getPrice() * quantity;
}
Public int getId() {
Return id;
}
77
Public void setProduct(Product product) {
This.product = product;
}
78
// @Transient
// public float getTotal() {
// float sum = 0;
// for (OrderBasket orderBasket : this.product.getOrderBaskets()) { //
sum += orderBasket.getSubtotal();
// }
// return sum;
// }
}
79
Package com.khomsi.site_project.entity;
80
Package com.khomsi.site_project.entity; Import lombok.*; Import
org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;
Import javax.persistence.*;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
81
@ToString
@Entity
@Table(name = “product”)
Public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private Integer id;
@Column(name = “title”)
Private String title;
@Column(name = “alias”)
Private String alias;
@Column(name = “description”)
Private String description;
@Column(name = “price”)
Private int price;
@Column(name = “image”)
Private String imageURL;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
82
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “vendor_id”)
@ToString.Exclude Private
Vendor vendor;
@OneToMany(mappedBy = “product”)
@ToString.Exclude
Private List<OrderBasket> orderBaskets;
@Transient
Public String getShortTitle() {
If (title.length() > 40) {
Return title.substring(0, 40).concat(“...”);
}
Return title;
}
@Transient
Public String getShortAlias() {
If (alias.length() > 40) {
83
Return alias.substring(0, 40).concat(“...”);
}
Return alias;
}
@Transient
Public String getShortDescription() {
84
Public void setTitle(String title) {
This.title = title;
}
Public String getAlias() {
Return alias;
}
Public void setAlias(String alias) {
This.alias = alias;
}
Public String getDescription() {
Return description;
}
Public void setDescription(String description) {
This.description = description;
}
Public int getPrice() {
Return price;
}
Public void setPrice(int price) {
This.price = price;
}
Public String getImageURL() {
Return imageURL;
85
}
Public void setImageURL(String imageURL) {
This.imageURL = imageURL;
}
Public Vendor getVendor() {
Return vendor;
}
Public void setVendor(Vendor vendor) { This.vendor = vendor;
}
Public Category getCategory() {
Return category;
}
Public void setCategory(Category category) {
This.category = category;
}
Public List<OrderBasket> getOrderBaskets() {
Return orderBaskets;
}
Public void setOrderBaskets(List<OrderBasket> orderBaskets) {
This.orderBaskets = orderBaskets;
}
86
//TODO add a new field in db discount if i need discount in future
// @Transient
// public float getDiscountPrice(){
// if (discountPercent > 0)
// {
// return price * ((100 – discountPercent) / 100);
// }
// return this.price;
// }
}
Package com.khomsi.site_project.entity;
Import org.springframework.security.core.GrantedAuthority;
87
/*
https://stackoverflow.com/questions/19525380/differencebetwee
nroleand-grantedauthority-in-spring-security */ Public enum
Role implements GrantedAuthority {
USER, ADMIN;
@Override
Public String getAuthority() {
Return name();
}
}
Package com.khomsi.site_project.entity;
Import lombok.*;
Import javax.persistence.*;
88
Import javax.validation.constraints.NotBlank;
Import javax.validation.constraints.NotNull;
Import javax.validation.constraints.Size;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “user”)
Public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”)
Private Integer id;
@Column(name = “password”)
89
Private String password;
@Column(name = “email”)
Private String email;
@Enumerated(EnumType.STRING)
@Column(name = “role”)
Private Role role;
@OneToMany(mappedBy = “user”)
@ToString.Exclude
Private List<Order> orders;
90
}
91
Public void setEmail(String email) {
This.email = email;
}
92
}
Public void setOrderBaskets(List<OrderBasket> orderBaskets) {
This.orderBaskets = orderBaskets;
}
93
Package com.khomsi.site_project.entity;
Import lombok.*;
Import org.hibernate.annotations.OnDelete;
Import org.hibernate.annotations.OnDeleteAction;
Import javax.persistence.*;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “user_info”)
Public class UserInfo {
@Id
@Column(name = “user_info_id”, nullable = false)
94
Private int user_id;
@MapsId
@OneToOne(fetch = FetchType.LAZY, optional = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = “user_info_id”) @ToString.Exclude Private
User user;
@Column(name = “name”)
Private String name;
@Column(name = “surname”)
Private String surname;
@Column(name = “phone”)
Private String phone;
95
Public User getUser() {
Return user;
}
96
This.surname = surname;
}
97
Package com.khomsi.site_project.entity; Import lombok.*;
Import javax.persistence.*;
Import java.util.LinkedHashSet;
Import java.util.List;
Import java.util.Set;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
@Entity
@Table(name = “vendor”)
98
Public class Vendor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = “id”, nullable = false)
Private Integer id;
99
Public void setTitle(String title) {
This.title = title;
}
Package com.khomsi.site_project.exception;
100
Public class CategoryNotFoundException extends Exception {
Public CategoryNotFoundException(String message) {
Super(message);
}
}
Package com.khomsi.site_project.exception;
}
}
101
Package com.khomsi.site_project.exception;
Package com.khomsi.site_project.exception;
102
Public UserNotFoundException(String message) {
Super(message);
}
}
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.Category;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;
Import java.util.List;
103
@Query(“SELECT category FROM Category category WHERE
category.enabled = true ORDER BY category.title ASC”)
Public List<Category> findAllEnabled();
104
}
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.Delivery;
Import org.springframework.data.jpa.repository.JpaRepository;
105
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Modifying;
Import org.springframework.data.jpa.repository.Query;
Import java.util.List;
106
?1 WHERE orderBasket.product.id = ?2 “ +
“AND orderBasket.user.id = ?3”)
@Modifying
Public void updateQuantity(Integer quantity, Integer productId, Integer
userId);
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;
Import java.util.List;
107
Public interface OrderRepository extends JpaRepository<Order, Integer> {
Order findByUser(User user);
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.Category;
108
Import com.khomsi.site_project.entity.Product;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import java.util.List;
109
public Long countById(Integer id);
110
String keyword, Pageable pageable);
}
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.UserInfo;
Import org.springframework.data.jpa.repository.JpaRepository;
111
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.User;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;
112
}
Package com.khomsi.site_project.repository;
Import com.khomsi.site_project.entity.Vendor;
Import org.springframework.data.jpa.repository.JpaRepository;
Import org.springframework.data.jpa.repository.Query;
Import org.springframework.data.repository.query.Param;
113
}
Package com.khomsi.site_project.service;
114
{ Private int totalPages;
Private long totalElements;
115
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import com.khomsi.site_project.repository.CategoryRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;
Import java.util.*;
@Service
Public class CategoryService implements ICategoryService { @Autowired
Private CategoryRepository categoryRep;
116
Public static final int TOP_CATEGORIES_PER_PAGE = 1;
@Override
Public List<Category> listByPage(CategoryPageInfo pageInfo, int
pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
TOP_CATEGORIES_PER_PAGE);
Page<Category> pageCategories =
categoryRep.findRootCategories(pageable);
List<Category> rooCategories = pageCategories.getContent();
pageInfo.setTotalElements(pageCategories.getTotalElements());
pageInfo.setTotalPages(pageCategories.getTotalPages());
return listHierarchicalCategories(rooCategories);
}
Private List<Category> listHierarchicalCategories(List<Category>
rootCategories) {
List<Category> hierarchicalCategories = new ArrayList<>();
} }
@Override
118
Public List<Category> listCategoriesUserInForm() {
List<Category> categoriesUserInForm = new ArrayList<>();
Iterable<Category> categoriesInDB = categoryRep.findAll();
categoriesUserInForm.add(Category.copyIdAndTitle(subCat.getId(), name));
listSubCategoriesUsedInForm(categoriesUserInForm, subCat,
1);
}
}
}
Return categoriesUserInForm;
}
Private void listSubCategoriesUsedInForm(List<Category>
categoriesUserInForm, Category parent, int subLevel) {
Int newSubLevel = subLevel + 1;
119
Set<Category> children = parent.getChildren();
} }
@Override
Public Category saveCategory(Category category) {
Category parent = category.getParent();
If (parent != null) {
String allParentIds = parent.getAllParentsIDs() == null ? “-“ :
parent.getAllParentsIDs();
allParentIds += String.valueOf(parent.getId()) + “-“;
category.setAllParentsIDs(allParentIds);
}
120
If (category.getAlias() == null || category.getAlias().isEmpty()) {
String defaultAlias = category.getTitle().toLowerCase();
Category.setAlias(convertCyrillic(defaultAlias).replaceAll(“ “, “_”));
} else {
Category.setAlias(category.getAlias().replaceAll(“ “,
“_”).toLowerCase());
}
Return categoryRep.save(category);
}
//Method to convert alias into english letters
Public String convertCyrillic(String message) {
Char[] abcCyr = {‘ ‘, ‘а’, ‘б’, ‘в’, ‘г’, ‘д’, ‘і’, ‘е’, ‘ж’, ‘з’, ‘ѕ’, ‘и’, ‘ј’,
‘к’, ‘л’, ‘ґ’, ‘м’, ‘н’, ‘є’,
‘о’, ‘п’, ‘р’, ‘с’, ‘т’, ‘ї’, ‘у’, ‘ф’, ‘х’, ‘ц’, ‘ч’, ‘џ’, ‘ш’, ‘А’, ‘Б’, ‘В’,
‘Г’, ‘Д’, ‘І’, ‘Е’, ‘Ж’,
‘З’, ‘Ѕ’, ‘И’, ‘Ј’, ‘К’, ‘Л’, ‘Ґ’, ‘М’, ‘Н’, ‘Є’, ‘О’, ‘П’, ‘Р’, ‘С’, ‘Т’,
‘Ї’, ‘У’, ‘Ф’, ‘Х’, ‘Ц’, ‘Ч’,
‘Џ’, ‘Ш’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’,
‘o’, ‘p’, ‘q’, ‘r’, ‘s’,
‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’,
‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’,
‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’, ‘0’, ‘1’,
‘2’,
‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘/’};
String[] abcLat = {“ “, “a”, “b”, “v”, “g”, “d”, “i”, “e”, “zh”, “z”, “y”,
“i”, “j”, “k”, “l”, “g”, “m”, “n”, “e”,
121
“o”, “p”, “r”, “s”, “t”, “ї”, “u”, “f”, “h”, “c”, “ch”, “x”, “h”, “A”,
“B”, “V”, “G”, “D”, “І”, “E”, “Zh”,
“Z”, “Y”, “I”, “J”, “K”, “L”, “G”, “M”, “N”, “E”, “O”, “P”, “R”,
“S”, “T”, “I”, “U”, “F”, “H”, “C”, “:”,
“X”, “{“, “a”, “b”, “c”, “d”, “e”, “f”, “g”, “h”, “i”, “j”, “k”, “l”,
“m”, “n”, “o”, “p”, “q”, “r”, “s”,
“t”, “u”, “v”, “w”, “x”, “y”, “z”, “A”, “B”, “C”, “D”, “E”, “F”,
“G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”,
“O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”, “0”,
“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”, “_”};
StringBuilder builder = new StringBuilder();
For (int i = 0; i < message.length(); i++) {
For (int x = 0; x < abcCyr.length; x++) {
If (message.charAt(i) == abcCyr[x]) {
Builder.append(abcLat[x]);
}
}
}
Return builder.toString();
}
@Override
122
Public void deleteCategory(int id) throws CategoryNotFoundException {
Long countById = categoryRep.countById(id);
If (countById == null || countById == 0) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with id “ + id);
}
categoryRep.deleteById(id);
}
@Override
Public Category getCategory(Integer id) throws
CategoryNotFoundException {
Try {
Return categoryRep.getReferenceById(id);
} catch (NoSuchElementException e) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with id “ + id);
} }
@Override
Public Category getCategoryByAlias(String alias) throws
CategoryNotFoundException {
Category category = categoryRep.findByAliasEnabled(alias);
If (category == null) {
Throw new CategoryNotFoundException(“Couldn’t find any
category with alias “ + alias);
123
}
Return category;
}
return listParents;
}
@Override
Public String checkCategoryTitle(Integer id, String title, String alias) {
Category categoryByTitle = categoryRep.findByTitle(title);
124
Boolean isCreatingNew = (id == null || id == 0);
If (isCreatingNew) {
If (categoryByTitle != null) {
Return “DuplicateTitle”;
} else {
Category categoryByAlias = categoryRep.findByAlias(alias);
If (categoryByAlias != null) {
Return “DuplicateAlias”;
}
}
} else {
If (categoryByTitle != null &&
!Objects.equals(categoryByTitle.getId(), id)) {
Return “DuplicateTitle”;
}
Category categoryByAlias = categoryRep.findByAlias(alias);
If (categoryByAlias != null &&
!Objects.equals(categoryByAlias.getId(), id)) {
Return “DuplicateAlias”;
}
}
Return “OK”;
}
125
}
126
Package com.khomsi.site_project.service; Import
com.khomsi.site_project.entity.Category;
Import com.khomsi.site_project.exception.CategoryNotFoundException;
Import org.springframework.data.domain.Page;
Import java.util.List;
127
String checkCategoryTitle(Integer id, String title, String alias);
}
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;
Import java.util.List;
128
Public void removeProduct(Integer productId, User user);
}
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.Order;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.OrderNotFoundException;
Import org.springframework.data.domain.Page;
129
Import java.util.List;
Package com.khomsi.site_project.service;
130
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import org.springframework.data.domain.Page;
Import java.util.List;
Import com.khomsi.site_project.entity.UserInfo;
Import java.util.List;
132
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.UserNotFoundException;
Import org.springframework.data.domain.Page;
Import java.util.List;
133
Boolean checkLoginRegistration(String login);
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.Vendor;
Import org.springframework.data.domain.Page;
Import java.util.List;
134
Vendor getVendor(int id);
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.OrderBasket;
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.repository.OrderBasketRepository; Import
com.khomsi.site_project.repository.ProductRepository; Import
org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.stereotype.Service;
135
Import org.webjars.NotFoundException;
Import javax.transaction.Transactional;
Import java.util.List;
@Service
@Transactional
Public class OrderBasketService implements IOrderBasketService {
@Autowired
Private OrderBasketRepository orderBasketRep;
@Autowired
Private ProductRepository productRep;
@Override
Public List<OrderBasket> getAllOrderBaskets() {
List<OrderBasket> orderBasket = orderBasketRep.findAll();
If (orderBasket.isEmpty()) {
Throw new NotFoundException(“Couldn’t find any product in DB”);
}
Return orderBasket;
}
136
@Override
Public List<OrderBasket> listOrderBasket(User user) {
Return orderBasketRep.findByUser(user);
}
@Override
Public Integer addProduct(Integer productId, Integer quantity, User user) {
Integer addedQuantity = quantity;
OrderBasket orderBasket =
orderBasketRep.findByUserAndProduct(user, product);
137
@Override
Public float updateQuantity(Integer productId, Integer quantity, User user)
{ orderBasketRep.updateQuantity(quantity, productId,
user.getId()); Product product =
productRep.getReferenceById(productId);
138
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.*;
Import com.khomsi.site_project.exception.OrderNotFoundException;
Import com.khomsi.site_project.repository.OrderRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
139
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;
Import org.webjars.NotFoundException;
Import java.util.List;
Import java.util.Optional;
@Service
Public class OrdersService implements IOrdersService {
@Autowired
Private OrderRepository orderRepository;
@Override
Public List<Order> getAllOrders() {
Return orderRepository.findAll();
}
@Override
Public List<Order> getAllOrdersByUser(User user) {
Return orderRepository.findOrdersByUser(user);
140
}
@Override
Public void saveOrder(Order orders) {
orderRepository.save(orders);
}
@Override
Public Order getOrder(int id) {
Order orders = null;
Optional<Order> optional = orderRepository.findById(id);
If (optional.isPresent()) orders = optional.get();
Return orders;
}
@Override
Public Order getOrderByUser(User user) throws
OrderNotFoundException {
Order order = orderRepository.findByUser(user);
If (order == null) {
Throw new OrderNotFoundException(“Couldn’t find any orders with
ID “ + order.getId());
}
Return order;
}
@Override
Public float countSum(List<OrderBasket> orderBaskets) {
141
Float sum = 0;
For (OrderBasket orderBasket : orderBaskets) {
Sum += orderBasket.getSubtotal();
}
Return sum;
}
@Override
Public void deleteOrder(int id) throws OrderNotFoundException {
Long countById = orderRepository.countById(id);
If (countById == null || countById == 0) {
Throw new OrderNotFoundException(“Couldn’t find any orders with
id “ + id);
}
orderRepository.deleteById(id);
}
@Override
Public Page<Order> listByPage(int pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
ORDERS_PER_PAGE);
Return orderRepository.findAll(pageable);
}
142
}
Package com.khomsi.site_project.service;
143
Import com.khomsi.site_project.entity.Product;
Import com.khomsi.site_project.exception.ProductNotFoundException;
Import com.khomsi.site_project.repository.ProductRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.data.domain.Sort;
Import org.springframework.stereotype.Service;
Import java.util.ArrayList;
Import java.util.Collections;
Import java.util.List;
Import java.util.NoSuchElementException;
Import java.util.Objects;
@Service
Public class ProductService implements IProductService {
@Autowired
Private ProductRepository productRepository;
Public static final int PRODUCTS_PER_PAGE = 10;
Public static final int SEARCH_RESULTS_PAGE = 10;
144
Public static final int PRODUCTS_PER_ADMIN_PAGE = 5;
@Override
Public Page<Product> listByCategory(int pageNum, Integer categoryId) {
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Pageable pageable = PageRequest.of(pageNum – 1,
PRODUCTS_PER_PAGE);
145
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Return productRepository.searchInCategory(categoryId, categoryIdMatch,
keyword, pageable);
}
Return productRepository.findAll(keyword, pageable);
}
If (categoryId != null && categoryId > 0) {
String categoryIdMatch = “-“ + String.valueOf(categoryId) + “-“;
Return productRepository.findAllInCategory(categoryId, categoryIdMatch,
pageable);
}
Return productRepository.findAll(pageable);
}
@Override
Public List<Product> getAllProducts() throws ProductNotFoundException
{
List<Product> listProducts = productRepository.findAll();
If (listProducts.isEmpty()) {
Throw new ProductNotFoundException(“Couldn’t find any product
in DB”);
}
Return listProducts;
}
146
@Override
Public List<Product> getRandomAmountOfProducts() throws
ProductNotFoundException {
// List<Product> productList =
productRepository.findAllByCategoryId(1);
List<Product> productList = productRepository.findAll();
If (productList.isEmpty()) {
Throw new ProductNotFoundException(“Couldn’t find any product
in DB”);
}
Collections.shuffle(productList);
// int randomSeriesLength = 3;
Return productList.subList(0, productList.size());
}
@Override
Public void saveProduct(Product product) {
If (product.getAlias() == null || product.getAlias().isEmpty()) {
String defaultAlias = product.getTitle().toLowerCase();
Product.setAlias((new
CategoryService().convertCyrillic(defaultAlias).replaceAll(“ “, “_”)));
} else {
Product.setAlias(product.getAlias().replaceAll(“ “,
“_”).toLowerCase());
}
147
productRepository.save(product);
}
@Override
Public Product getProduct(Integer id) throws ProductNotFoundException
{
Try {
Return productRepository.getReferenceById(id);
} catch (NoSuchElementException e) {
Throw new ProductNotFoundException(“Couldn’t find any product
with id “ + id);
} }
@Override
Public Product getProduct(String alias) throws
ProductNotFoundException {
Try {
Return productRepository.findByAlias(alias);
} catch (NoSuchElementException e) {
Throw new ProductNotFoundException(“Couldn’t find any product
with alias “ + alias);
} }
@Override
148
Public void deleteProduct(Integer id) throws ProductNotFoundException
{
Long countById = productRepository.countById(id);
If (countById == null || countById == 0) {
Throw new ProductNotFoundException(“Couldn’t find any product
with ID “ + id);
}
productRepository.deleteById(id);
}
@Override
Public String checkUnique(Integer id, String title) {
Boolean isCreatingNew = (id == null || id == 0);
Product productByName = productRepository.findByTitle(title);
If (isCreatingNew) {
If (productByName != null) return “Duplicate”;
} else {
If (productByName != null &&
!Objects.equals(productByName.getId(), id)) {
Return “Duplicate”;
}
}
Return “OK”;
}
Public Page<Product> search(String keyword, int pageNum) {
149
Pageable pageable = PageRequest.of(pageNum – 1,
SEARCH_RESULTS_PAGE);
Return productRepository.search(keyword, pageable);
}
}
150
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.UserInfo;
Import com.khomsi.site_project.repository.UserInfoRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.stereotype.Service;
Import java.util.List;
Import java.util.Optional;
@Service
Public class UserInfoService implements IUserInfoService {
@Autowired
Private UserInfoRepository userInfoRepository;
@Override
Public List<UserInfo> getAllUserDetails() {
Return userInfoRepository.findAll();
}
@Override
Public void saveUserDetail(UserInfo userInfo) {
userInfoRepository.save(userInfo);
}
@Override
Public UserInfo getUserDetail(int id) {
UserInfo userInfo = null;
151
Optional<UserInfo> optional =
userInfoRepository.findById(id); If (optional.isPresent()) {
userInfo = optional.get();
}
Return userInfo;
}
@Override
Public void deleteUserDetail(int id) {
userInfoRepository.deleteById(id);
}
}
152
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.User;
Import com.khomsi.site_project.exception.UserNotFoundException;
Import com.khomsi.site_project.repository.UserRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.security.crypto.password.PasswordEncoder;
153
Import org.springframework.stereotype.Service;
Import java.util.List;
Import java.util.NoSuchElementException;
Import java.util.Objects;
@Service
Public class UserService implements IUserService {
@Autowired
Private UserRepository userRepository;
@Autowired
Private PasswordEncoder passwordEncoder;
@Override
Public List<User> getAllUsers() {
Return userRepository.findAll();
}
@Override
Public void saveUser(User user) {
154
Boolean isUpdatedUser = (user.getId() != null);
If (isUpdatedUser) {
User existingUser = userRepository.getReferenceById(user.getId());
If (user.getPassword().isEmpty()) {
User.setPassword(existingUser.getPassword());
} else {
encodePassword(user);
}
} else {
encodePassword(user);
}
userRepository.save(user);
}
@Override
Public User getUser(int id) throws UserNotFoundException {
Try {
Return userRepository.getReferenceById(id);
} catch (NoSuchElementException ex) {
Throw new UserNotFoundException(“Couldn’t find any user with id
“ + id);
} }
@Override
Public User getUserByLogin(String login) {
155
Return userRepository.findByLogin(login);
}
@Override
Public void deleteUser(Integer id) throws UserNotFoundException {
Long countById = userRepository.countById(id);
If (countById == null || countById == 0) {
Throw new UserNotFoundException(“Couldn’t find any user with id
“ + id);
}
userRepository.deleteById(id);
}
@Override
Public void encodePassword(User user) {
String encodePass = passwordEncoder.encode(user.getPassword());
User.setPassword(encodePass);
}
@Override
Public String isLoginUnique(Integer id, String login) {
User userByLogin = userRepository.findByLogin(login);
Boolean isCreatingNew = (id == null);
If (isCreatingNew) {
156
If (userByLogin != null) return “Duplicate”;
} else {
If (!Objects.equals(userByLogin.getId(), id)) {
Return “Duplicate”;
}
}
Return “OK”;
}
/*
Added this method to check unique login for user while he’s registration
You can modify it to have more unique fields.
(if you need unique fields in admin panel for user, change another methods
like isLoginUnique)
*/
@Override
Public boolean checkLoginRegistration(String login) {
User user = userRepository.findByLogin(login);
157
}
}
158
Package com.khomsi.site_project.service;
Import com.khomsi.site_project.entity.Vendor;
Import com.khomsi.site_project.repository.VendorRepository;
Import org.springframework.beans.factory.annotation.Autowired;
Import org.springframework.data.domain.Page;
Import org.springframework.data.domain.PageRequest;
Import org.springframework.data.domain.Pageable;
Import org.springframework.stereotype.Service;
Import org.webjars.NotFoundException;
Import java.util.List;
Import java.util.Objects;
Import java.util.Optional;
@Service
Public class VendorService implements IVendorService { @Autowired
Private VendorRepository vendorRepository;
160
If (countById == null || countById == 0) {
Throw new NotFoundException(“Couldn’t find any vendor with id “
+ id);
}
vendorRepository.deleteById(id);
}
@Override
Public Page<Vendor> listByPage(int pageNum) {
Pageable pageable = PageRequest.of(pageNum – 1,
VENDORS_PER_PAGE);
Return vendorRepository.findAll(pageable);
}
@Override
Public String checkVendorTitle(Integer id, String title) {
Vendor vendor = vendorRepository.findByTitle(title);
Boolean isCreatingNew = (id == null);
If (isCreatingNew) {
If (vendor != null) return “Duplicate”;
} else {
If (!Objects.equals(vendor.getId(), id)) {
Return “Duplicate”;
}
}
161
Return “OK”;
}
} Package com.khomsi.site_project;
@SpringBootApplication
Public class WebStoreApplication {
Public static void main(String[] args) {
SpringApplication.run(WebStoreApplication.class, args);
}
}
162
Êþº¾ 4 6com/khomsi/site_project/configuration/EncryptionConfig
java/lang/Object <init> ()V
Code
LineNumberTable LocalVariableTable
this
8Lcom/khomsi/site_project/configuration/EncryptionConfig; encoder
@()Lorg/springframework/security/crypto/password/PasswordEncoder;
RuntimeVisibleAnnotations -
Lorg/springframework/context/annotation/Bean;
@org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder
SourceFile EncryptionConfig.java
6Lorg/springframework/context/annotation/Configuration; !
/ *· ±
<?xml
version=”1.0”
163
encoding=”UTF-
8”?>
<classpath>
<classpathentry kind=”src” output=”target/classes”
path=”src/main/java”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry excluding=”**” kind=”src” output=”target/classes”
path=”src/main/resources”>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”src” output=”target/test-classes”
path=”src/test/java”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”test” value=”true”/>
164
</attributes>
</classpathentry>
<classpathentry kind=”con”
path=”org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.d
e bug.ui.launcher.StandardVMType/JavaSE-1.8”>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry> <classpathentry kind=”con”
path=”org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER”
>
<attributes>
<attribute name=”maven.pomderived” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”src”
path=”target/generatedsources/annotations”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”ignore_optional_problems” value=”true”/>
<attribute name=”m2e-apt” value=”true”/>
</attributes>
</classpathentry>
165
<classpathentry kind=”src” output=”target/test-classes”
path=”target/generated-test-sources/test-annotations”>
<attributes>
<attribute name=”optional” value=”true”/>
<attribute name=”maven.pomderived” value=”true”/>
<attribute name=”ignore_optional_problems” value=”true”/>
<attribute name=”m2e-apt” value=”true”/>
<attribute name=”test” value=”true”/>
</attributes>
</classpathentry>
<classpathentry kind=”output” path=”target/classes”/>
</classpath>
166
<factorypath>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
bootstarterdatajpa/2.7.2/spring-boot-starter-data-jpa-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarteraop/
2.7.2/spring-boot-starter-aop-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-
1.9.7.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarterjdbc/2.7.2/spr
ing-boot-starter-jdbc-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/zaxxer/HikariCP/4.0.3/HikariCP-4.0.3.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/springjdbc/5.3.22/spring-jdbc-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/transaction/jakarta.transactionapi/1.3.3/jakarta.tr
ansaction-api-1.3.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/persistence/jakarta.persistenceapi/2.2.3/jakarta.persist
ence-api-2.2.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/hibernate/hibernatecore/5.6.10.Final/hibernatecore5.6.10
167
.Final.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/jboss/logging/jbosslogging/3.4.3.Final/jboss-logging-
3.4.3.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/bytebuddy/bytebuddy/1.12.12/byte-buddy-1.12.12.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/antlr/antlr/2.7.7/antlr2.7.7.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/jboss/jandex/2.4.2.Final/jandex-
2.4.2.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/hibernate/common/hibernatecommonsannotati
ons/5.1.2.Final/hibernate-commons-annotations-
5.1.2.Final.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/glassfish/jaxb/jaxbruntime/2.3.6/jaxb-runtime-
2.3.6.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/glassfish/jaxb/txw2/2.3.6/txw2-2.3.6.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/sun/istack/istackcommons-
168
runtime/3.0.12/istackcommons-runtime-3.0.12.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/data/spring-
datajpa/2.7.2/springdatajpa-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/data/spring-
datacommons/2.7.2/springdata-commons-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springorm/5.3.22/springorm5.3.22.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springcontext/5.3.22/springcontext5.3.
22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-tx/5.3.22/spring-tx-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-beans/5.3.22/spring-beans-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springaspects/5.3
.22/springaspects5.3.22.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
boot-
starterdatarest/2.7.2/spring-boot-starter-data-rest-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
169
id=”M2_REPO/org/springframework/data/springdata-
restwebmvc/3.7.2/spring-data-rest-webmvc-3.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/data/springdata-
restcore/3.7.2/springdata-rest-core-3.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/hateoas/springhateoas/1.5.1/s
p ringhateoas-1.5.1.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/plugin/spring-
plugincore/2.0.0.RELEASE/spring-plugin-core-2.0.0.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/atteo/evoinflector/1.3/evo-inflector-1.3.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jacksondatabind/2.13.3/jackson
databind-2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jackson-
annotations/2.13.3/jackson-annotations-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
startersecurity/2.7.2/spring-boot-starter-security-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
170
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarter
/2.7.2/springboot-starter-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
starterlogging/2.7.2/spring-boot-starter-logging-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/ch/qos/logback/logback-
classic/1.2.11/logbackclassic1.2.11.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/ch/qos/logback/logback-core/1.2.11/logback-core-
1.2.11.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/apache/logging/log4j/log4jtoslf4j/2.17.2/log4j-to-slf4j-
2.17.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/logging/log4j/log4j-api/2.17.2/log4j-api-
2.17.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/slf4j/jultoslf4j/1.7.36/jul-to-slf4j-1.7.36.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/jakarta/annotation/jakarta.annotationapi/1.3.5/jakarta.annota
t ion-api-1.3.5.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/yaml/snakeyaml/1.30/snakeyaml-1.30.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
171
id=”M2_REPO/org/springframework/springaop/5.3.22/springaop
5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecurityconfi
g/5.7.2/spring-security-config-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecurityweb/
5.7.2/spring-security-web-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/springframework/spring-
expression/5.3.22/springexpression-5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstarterthymele
af/2.7.2/spring-boot-starter-thymeleaf-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/thymeleaf-
spring5/3.0.15.RELEASE/thymeleaf-spring5-3.0.15.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/thymeleaf/3.0.15.RELEASE/thymele
af
-
3.0.15.RELEASE.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/attoparser/attoparser/2.0.5.RELEASE/attoparser2.0.5.RE
LEASE.jar” enabled=”true” runInBatchMode=”false”/>
172
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/unbescape/unbescape/1.1.6.RELEASE/unbescape1.1.6.
R
ELEASE.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/extras/thymeleaf-extras-
java8time/3.0.4.RELEASE/thymeleaf-extras-java8time-
3.0.4.RELEASE.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootstartervali
dation/2.7.2/spring-boot-starter-validation-
2.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcatembedel/
9.0.65/tomcatembed-el-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/hibernate/validator/hibernate-
validator/6.2.3.Final/hibernate-validator-6.2.3.Final.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/validation/jakarta.validationapi/2.0.2/jakarta.validati
o n-api-2.0.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-
bootstarterweb/2.7.2/spring-boot-starter-web-2.7.2.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/springframework/boot/spring-
bootstarterjson/2.7.2/spring-boot-starter-json-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
173
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/datatype/jacksondatatypejdk8/2.13.3
/ jackson-datatype-jdk8-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
id=”M2_REPO/com/fasterxml/jackson/datatype/jackson-
datatypejsr310/2.13.3/jackson-datatype-jsr310-2.13.3.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/module/jacksonmoduleparameterna
mes/2.13.3/jackson-module-parameter-names-
2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
startertomcat/2.7.2/spring-boot-starter-tomcat-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcat-
embedcore/9.0.65/tomcatembed-core-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/apache/tomcat/embed/tomcatembedwebsoc
ket/9.0.65/tomcat-embed-websocket-9.0.65.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/springweb/5.3.22/springw
eb5.3.22.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springwebmvc/5.3.22/spri
ngwebmvc5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>
174
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/thymeleaf/extras/thymeleafextrasspringsecurity5/3.0.4.R
ELEASE/thymeleaf-extrasspringsecurity53.0.4.RELEASE.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/org/slf4j/slf4japi/1.7.36/slf4j-api-
1.7.36.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR” id=”M2_REPO/mysql/mysqlconnector-
java/8.0.29/mysqlconnector-java-
8.0.29.jar” enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/org/springframework/boot/springbootstartermail/2.7.2/
spring-boot-starter-mail-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-
contextsupport/5.3.22/springcontext-support-5.3.22.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/sun/mail/jakarta.mail/1.6.7/jakarta.mail-1.6.7.jar”
enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/com/sun/activation/jakarta.activation/1.2.2/jakarta.activation
1.2.2.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootconfigurationprocesso
r/2.7.2/spring-boot-configuration-processor2.7.2.jar” enabled=”true”
runInBatchMode=”false”/> <factorypathentry kind=”VARJAR”
id=”M2_REPO/org/projectlombok/lombok/1.18.24/lombok-
1.18.24.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
175
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/jayway/jsonpath/json-path/2.7.0/json-path-2.7.0.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/minidev/jsonsmart/2.4.8/json-smart-2.4.8.jar”
enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/net/minidev/accessors-smart/2.4.8/accessors-smart-
2.4.8.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/ow2/asm/asm/9.1/asm-9.1.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/jakarta/xml/bind/jakarta.xml.bindapi/2.3.3/jakarta.xml.binda
pi-2.3.3.jar” enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/jakarta/activation/jakarta.activationapi/1.2.2/jakarta.activati
o n-api-1.2.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/springcore/5.3.22/springcore5.3.22.jar
” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/spring-jcl/5.3.22/spring-jcl-
5.3.22.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/security/springsecuritycore/5.7.2/spri
n g-security-core-5.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/security/spring-
securitycrypto/5.7.2/spring-security-crypto-5.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
176
<factorypathentry kind=”VARJAR”
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/npm/normalize.css/8.0.1/normalize.css-
8.0.1.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springbootdevtools/2.7.2/springb
oot-devtools-2.7.2.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/springboot/2.7.2/springboot2.7.2.
jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/springframework/boot/spring-boot-
autoconfigure/2.7.2/spring-boot-autoconfigure-2.7.2.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/bootstrap/4.3.1/bootstrap-4.3.1.jar”
enabled=”true” runInBatchMode=”false”/>
id=”M2_REPO/org/webjars/popper.js/1.14.3/popper.js-
1.14.3.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/jquery/3.4.1/jquery-3.4.1.jar” enabled=”true”
runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/org/webjars/webjarslocator-core/0.50/webjars-locator-core-
0.50.jar” enabled=”true” runInBatchMode=”false”/>
<factorypathentry kind=”VARJAR”
id=”M2_REPO/io/github/classgraph/classgraph/4.8.139/classgraph4.8.1
3 9.jar” enabled=”true” runInBatchMode=”false”/> <factorypathentry
kind=”VARJAR”
177
<factorypathentry kind=”VARJAR”
id=”M2_REPO/com/fasterxml/jackson/core/jacksoncore/2.13.3/jacksonc
ore-2.13.3.jar” enabled=”true” runInBatchMode=”false”/>
</factorypath>,
178
*.css linguist-detectable=false *.html linguistdetectable=false
HELP.md
Target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
179
*.iml
*.ipr
/src/main/resources/sql/WebShop_old.mwb
180
<?xml version=”1.0” encoding=”UTF-8”?>
181
<projectDescription>
<name>site_project</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuil
der</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
182
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# “License”); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
183
# KIND, either express or implied. See the License for the #
specific language governing permissions and limitations #
under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME – location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME – location of maven2’s installed home dir
# MAVEN_OPTS – parameters passed to the Java VM when running
Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -
Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC – flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
If [ -z “$MAVEN_SKIP_RC” ] ; then
184
If [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
Fi
If [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
Fi
If [ -f “$HOME/.mavenrc” ] ; then
. “$HOME/.mavenrc”
Fi
Fi
185
If [ -z “$JAVA_HOME” ]; then
If [ -x “/usr/libexec/java_home” ]; then
Export JAVA_HOME=”`/usr/libexec/java_home`”
Else
Export JAVA_HOME=”/Library/Java/Home”
Fi
Fi
;;
Esac
If [ -z “$JAVA_HOME” ] ; then
If [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config –jre-home`
Fi
Fi
If [ -z “$M2_HOME” ] ; then
## resolve links - $0 may be a link to maven’s home
PRG=”$0”
Saveddir=`pwd`
M2_HOME=`dirname “$PRG”`/..
Cd “$saveddir”
# echo Using m2 at $M2_HOME
Fi
# For Cygwin, ensure paths are in UNIX format before anything is touched If
$cygwin ; then
[ -n “$M2_HOME” ] &&
M2_HOME=`cygpath –unix “$M2_HOME”`
[ -n “$JAVA_HOME” ] &&
JAVA_HOME=`cygpath –unix “$JAVA_HOME”`
[ -n “$CLASSPATH” ] &&
187
CLASSPATH=`cygpath –path –unix “$CLASSPATH”`
Fi
# For Mingw, ensure paths are in UNIX format before anything is touched If
$mingw ; then
[ -n “$M2_HOME” ] &&
M2_HOME=”`(cd “$M2_HOME”; pwd)`”
[ -n “$JAVA_HOME” ] &&
JAVA_HOME=”`(cd “$JAVA_HOME”; pwd)`”
Fi
If [ -z “$JAVACMD” ] ; then
If [ -n “$JAVA_HOME” ] ; then
If [ -x “$JAVA_HOME/jre/sh/java” ] ; then
# IBM’s JDK on AIX uses strange locations for the executables
JAVACMD=”$JAVA_HOME/jre/sh/java”
Else
JAVACMD=”$JAVA_HOME/bin/java”
Fi
Else
JAVACMD=”`\\unset -f command; \\command -v java`”
Fi
Fi
If [ ! -x “$JAVACMD” ] ; then
Echo “Error: JAVA_HOME is not defined correctly.” >&2
Echo “ We cannot execute $JAVACMD” >&2
Exit 1 Fi
If [ -z “$JAVA_HOME” ] ; then
Echo “Warning: JAVA_HOME environment variable is not set.”
Fi
189
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.
Launcher
If [ -z “$1” ]
Then
Echo “Path not specified to find_maven_basedir”
Return 1
Fi
Basedir=”$1”
Wdir=”$1”
While [ “$wdir” != ‘/’ ] ; do
If [ -d “$wdir”/.mvn ] ; then
Basedir=$wdir
Break
Fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
If [ -d “${wdir}” ]; then
Wdir=`cd “$wdir/..”; pwd`
Fi
# end of workaround
190
Done
Echo “${basedir}”
}
If [ -r “$BASE_DIR/.mvn/wrapper/maven-wrapper.jar” ]; then
If [ “$MVNW_VERBOSE” = true ]; then
Echo “Found .mvn/wrapper/maven-wrapper.jar”
Fi
Else
191
If [ “$MVNW_VERBOSE” = true ]; then
Echo “Couldn’t find .mvn/wrapper/maven-wrapper.jar, downloading it
...”
Fi
If [ -n “$MVNW_REPOURL” ]; then
jarUrl=”$MVNW_REPOURL/org/apache/maven/wrapper/mavenwra
pper/3.1.0/maven-wrapper-3.1.0.jar” else
jarUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/ma
ven-wrapper/3.1.0/maven-wrapper-3.1.0.jar fi while
IFS=”=” read key value; do case “$key” in
(wrapperUrl) jarUrl=”$value”; break ;; esac
done < “$BASE_DIR/.mvn/wrapper/maven-wrapper.properties” if
[ “$MVNW_VERBOSE” = true ]; then echo “Downloading
from: $jarUrl” fi
wrapperJarPath=”$BASE_DIR/.mvn/wrapper/maven-
wrapper.jar” if $cygwin; then wrapperJarPath=`cygpath –path –
windows “$wrapperJarPath”` fi
192
fi
elif command -v curl > /dev/null; then if [
“$MVNW_VERBOSE” = true ]; then
echo “Found curl ... using curl” fi
if [ -z “$MVNW_USERNAME” ] || [ -z “$MVNW_PASSWORD” ]; then
curl -o “$wrapperJarPath” “$jarUrl” -f else
curl –user $MVNW_USERNAME:$MVNW_PASSWORD -o
“$wrapperJarPath” “$jarUrl” -f fi
else if [
“$M
VNW
_VER
BOS
E” =
true ]; then
echo
“Falli
ng
back to
using
Java to
downl
oad”
fi
javaClass=”$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java”
# For Cygwin, switch paths to Windows format before running javac
If $cygwin; then javaClass=`cygpath –path –windows
“$javaClass”` fi if [ -e
“$javaClass” ]; then if
193
[ ! -e
“$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class” ];
then if [ “$MVNW_VERBOSE” = true ]; then echo
“ – Compiling MavenWrapperDownloader.java ...” fi
# Compiling the Java class
(“$JAVA_HOME/bin/javac” “$javaClass”)
Fi
If [ -e
“$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class” ]; then
# Running the downloader
If [ “$MVNW_VERBOSE” = true ]; then
Echo “ – Running MavenWrapperDownloader.java ...”
Fi
(“$JAVA_HOME/bin/java” -cp .mvn/wrapper
MavenWrapperDownloader “$MAVEN_PROJECTBASEDIR”)
Fi
Fi
Fi Fi
# End of extension
Export
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:“$BASE_DIR”}
If [ “$MVNW_VERBOSE” = true ]; then
194
Echo $MAVEN_PROJECTBASEDIR
Fi
MAVEN_OPTS=”$(concat_lines
“$MAVEN_PROJECTBASEDIR/.mvn/jvm.config”) $MAVEN_OPTS”
# Provide a “standardized” way to retrieve the CLI args that will # work
with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS=”$MAVEN_CONFIG $@”
Export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
195
Exec “$JAVACMD” \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath
“$MAVEN_PROJECTBASEDIR/.mvn/wrapper/mavenwrapper.jar” \
“-Dmaven.home=${M2_HOME}” \
“-
Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}”
\
${WRAPPER_LAUNCHER} $MAVEN_CONFIG “$@”
196
<?xml version=”1.0” encoding=”UTF-8”?> <project
xmlns=http://maven.apache.org/POM/4.0.0
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
Xsi:schemaLocation=http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!—lookup parent from repository
</parent>
<groupId>com.khomsi</groupId>
<artifactId>site_project</artifactId>
<version>0.0.1SNAPSHOT</version>
<name>site_project</name>
<description>Site project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
197
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
198
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
199
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!—https://mvnrepository.com/artifact/org.webjars.npm/normalize.css
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>normalize.css</artifactId>
<version>8.0.1</version>
</dependency>
<!—
https://mvnrepository.com/artifact/org.springframework.boot/springbootdevto
ols
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
200
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.3.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${project.parent.version}</version>
201
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> </exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
202
This E-commerce project built on Spring Boot.<br> Look demo
below.
## Used Technologies:
203
* User will receive email with order after it was finished successfully. *
Admin can add or modify everything in DB (product, user, category,
vendor, basket, delivery)
/*
SQLyog Ultimate v10.00 Beta1 MySQL –
5.6.23-log : Database – web_store_test
*/
204
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0
*/;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`web_store_test`
/*!40100 DEFAULT CHARACTER SET utf8 */;
USE `web_store_test`;
205
/*Data for the table `category` */
Insert into
`category`(`id`,`alias`,`all_parent_ids`,`enabled`,`image`,`title`,`parent_id`)
values
(1,’TV’,’TV’,’’,’NA’,’TV’,1),(2,’Washing’,’Washing’,’’,’NA’,’Washing’,1);
/*Table structure for table `delivery` */
206
`id` int(11) NOT NULL AUTO_INCREMENT,
`quantity` int(11) DEFAULT NULL,
`product_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKl7rqeve9by7viqp0whwoxths0` (`product_id`),
KEY `FKopaem614pruff3g3ia1bpx6ag` (`user_id`),
CONSTRAINT `FKl7rqeve9by7viqp0whwoxths0` FOREIGN KEY
(`product_id`) REFERENCES `product` (`id`),
CONSTRAINT `FKopaem614pruff3g3ia1bpx6ag` FOREIGN KEY
(`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
207
`address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`order_status` varchar(255) DEFAULT NULL,
`shipping_type` int(11) DEFAULT NULL,
`total_price` float DEFAULT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKel9kyl84ego2otj2accfd8mr7` (`user_id`),
CONSTRAINT `FKel9kyl84ego2otj2accfd8mr7` FOREIGN KEY
(`user_id`) REFERENCES `user` (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
Insert into
`product`(`id`,`alias`,`description`,`image`,`price`,`title`,`category_id`,`vendo
r_id`) values
(1,’Tv’,’Television’,’279813767.jpg’,999,’TV’,1,2),(2,’Mobile’,’mobile
‘,’221194930.jpg’,888,’Mobile’,1,2),(3,’cover’,’cover’,’237286899.jpg’,777,
’cover’,2,2),(4,’tempered’,’tempered ‘,’73896886.jpg’,666,’tempered’,2,2);
209
`email` varchar(255) DEFAULT NULL,
`login` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
210
CONSTRAINT `FKis88irnme4d39p7mbidp2yhg8` FOREIGN KEY
(`user_info_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
project.
212
filter the results based on various parameters like product type,
manufacturer, price range, platform supported etc.
213
2.2 System Feasibility
The system feasibility can be divided into the following sections:
Users:
214
Internet Browser
Internet Connection
3. System Analysis
After carefully analyzing the requirements and functionality of the
web application, I had two important diagrams by the end of the
analysis phase. They are the ER diagram and data flow diagram
which were the basis for finding out entities and relationships
between them, the flow of information.
3.1 ER Diagram
215
Figure 3.1 Entity Relation Ship Diagram
216
Figure 3.2: A Context Level Diagram
217
Figure 3.3: A First Level Diagram
218
Figure 3.4: A Second Level Diagram
219
Figure 3.5: A Second Level Diagram
220
3.3 Use Case Diagram
222
4. Design
•
Design of an application that has features like drag and drop etc.
•
Design of application that decreases data transfers between the
223
4.2Architectural Design
224
4.2.2 Description of Architectural Design
225
4.3 Procedural/Modular Approach
Following are all the modules designed for the Online Shopping
System.
This module starts when the user visits the home page or when
a user searches for a product by entering a search term. This part of
the application includes displaying all the products that are available
or the products that match the search term entered by the user. The
user can then filter these products based on various parameters like
manufacturer, product type, operating system supported or a price
range. The user browse through the products and each product would
be displayed with an image and its features like operating system
supported, number of user licenses and if it is a full version or an
upgrade version. A user can add a product to the cart either by
dragging the product and dropping it in the cart or by clicking a
button. The user would be able to see the shopping cart summary.
226
4.3.2 Product Description Module
This module starts when the user views the shopping cart. All the
products that have been added to the shopping cart by the user are
listed along with their price and the quantity. The total price of all
the products added to cart is displayed. A user can edit the quantity
of each product or remove the product from the shopping cart. A user
can remove the product from the cart by clicking a button or by
dragging the product and dropping it outside the cart. The total price
changes accordingly when a user edits the quantity of
227
5. Implementation
These are the main tables in the application and others are lookup and
query tables. The tables were derived from the ER-Diagram.
228
5.2 User Interface Design and Implementation
The user interface of the application has been designed using
Microsoft Visual Studio 2008. The main controls used in the design
are Repeaters, Ajax Update panels, Ajax toolkit controls like modal
popup, textbox watermark and Auto complete controls.
229
A user can drag and drop a product in the shopping cart. This is
shown in the figure 5.3. The cart is updated accordingly as shown
in figure 5.4
230
Figure 5.4 figure showing that Cart has been
Updated
A user can view the complete description of the product by clicking
on the product link. This is shown in figure 5.5. The user can move
the cursor on to the small images to view the same image in the
enlarged position. The user can click on the enlarged picture to see a
still bigger image in a pop up window as shown Figure 5.6
231
Figure 5.5 Product Description Page
233
Figure 5.8 Cart Details Page
5.3 Technical Discussions
234
6. Testing
Software testing is a process of running with intent of finding
errors in software. Software testing assures the quality of software
and represents final review of other phases of software like
specification, design, code generation etc.
235
I have tested each view/module of the application individually.
As the modules were built up testing was carried out simultaneously,
tracking out each and every kind of input and checking the
corresponding output until module is working correctly.
The functionality of the modules was also tested as separate
units. Each of the three modules was tested as separate units. In each
module all the functionalities were tested in isolation.
In the Shop Products Module when a product has been added
to cart it has been made sure that if the item already exists in the
shopping cart then the quantity is increased by one else a new item
is created in the shopping cart. Also the state of the system after a
product has been dragged in to the shopping cart is same as the state
of the system if it was added by clicking the add to cart button. Also
it has been ensured that all the images of the products displayed in
the shop products page are drag gable and have the product property
so that they can be dropped in the cart area.
In the Product Description Module it has been tested that all
the images are displayed properly. Users can add review and the as
soon as a user adds a review it is updated in the view customer review
tab. It has been checked to see if the whole page refreshes or a partial
page update happens when a user writes a review.
In the Cart Details it has been tested that when a user edits a
quantity or removes a product from the cart, the total price is updated
accordingly. It has been checked to see if the whole page refreshes
or a partial page update happens when a user edits the cart.
Visual Studio 2008 has in built support for testing the
application. The unit testing can be done using visual studio 2008
without the need of any external application. Various methods have
236
been created for the purpose of unit testing. Test cases are
automatically generated for these methods. The tests run under the
ASP.NET context which means settings from Web.config file are
automatically picked up once the test case starts running.
Methods were written to retrieve all the manufacturers from the
database, strings that match a certain search term, products that
match certain filter criteria, all images that belong to a particular
product etc. Unit test cases were automatically generated for these
methods and it can be seen in figure 6.1 that the tests have passed.
- Validation test criteria (no. in place of no. & char in place of char)
238
- Configuration review (to ensure the completeness of s/w configuration.) -
Alpha & Beta testing-Alpha testing is done at developer’s site i.e. at home &
Beta testing once it is deployed. Since I have not deployed my application, I
could not do the Beta testing.
Test Cases- I have used a number of test cases for testing the product.
There were different cases for which different inputs were used to
check whether desired output is produced or not.
1. Addition of a new product to the cart should create a new row in the
shopping cart.
2. Addition of an existing product to the cart has to update the quantity
of the product.
3. Any changes to items in the cart have to update the summary
correctly.
4. Because same page is inserting data into more than one table in the
database atomicity of the transaction is tested.
5. The state of the system after a product has been dragged in to the
cart should be same as the state of the system if the same product is
added to the cart by clicking a button.
239
Using white-box testing software developer can derive test case that
• Guarantee that all independent paths within a module have been exercised
at least once.
• Exercise all loops at their boundaries and within their operational bound.
• Exercise internal data structure to ensure their validity.
At every stage of project development I have tested the logics of the
program by supplying the invalid inputs and generating the
respective error messages. All the loops and conditional statements
are tested to the boundary conditions and validated properly.
Figure 6.3 Summary Reports for 100 Users and 600 Loop Count for
Cart Details Page
241
Users Up
Loop Average
Ramp
Count period(sec) Response(ms)
242
Observations
Response Time increases rapidly with number of users but not very
much when the users are kept constant and only loop-count is
increased. This is because, if the number of users is kept constant
and only the loop count is increased, the number of requests handled
by the server per second remains constant for every execution of the
loop count and for every increase in the loop count. Hence the
response time will not increase drastically in this case. Whereas, if
the users are increased and loop count is kept constant, the requests
handled by the server per second increases with increasing users and
hence the longer response time.
243
1000 150 10 11993 135273
Observations:
Response Time of a complex webpage with database and business logic
functions is far more than a simple webpage.
Cart
Details
Shop
Loop Ramp Up Products
Count period(sec)Page(ms) page(ms)
244
100 150 10 792 8312
Observations:
Response Time of a complex webpage with database and business
logic functions is far more than a simple webpage. The Response
times of remote testing are better than those of local testing when the
number of users is comparatively lesser.
•
JMeter had better access to hardware resources as the application is not
on the same machine.
Using this above tabular data, I can say that the system is adequate to
handle the normal load and the users won’t lose their focus.
246
7.1 Challenges
•
Compatibility with browsers like Mozilla Firefox, Internet explorer
etc
•
Using a layered approach in developing the application which would
•
Learning new technologies like using JavaScript for drag and drop
The overall idea of doing this project is to get a real time experience. Learn
new technologies.
247
8. Conclusions
The ‘Online Shopping’ is designed to provide a web based
application that would make searching, viewing and selection of a
product easier. The search engine provides an easy and convenient
way to search for products where a user can Search for a product
interactively and the search engine would refine the products
available based on the user’s input. The user can then view the
complete specification of each product. They can also view the
product reviews and also write their own reviews. Use of Ajax
components would make the application interactive and prevents
annoying post backs. Its drag and drop feature would make it easy to
use.
8.1 Limitations
This application does not have a built in check out process. An
external checkout package has to be integrated in to this application.
Also users cannot save the shopping carts so that they can access
later i.e. they cannot create wish lists which they can access later.
This application does not have features by which user can set price
ranges for products and receive alerts once the price reaches the
particular range.
248
8.2 Scope for Future Work
The following things can be done in future.
•
The current system can be extended to allow the users to create
accounts and save products in to wish list.
•
The users could subscribe for price alerts which would
enable them to receive messages when price for products
fall below a particular level.
•
The current system is confined only to the shopping cart
process. It can be extended to have an easy to use check out
process.
•
Users can have multiple shipping and billing information
saved. During checkout they can use the drag and drop
feature to select shipping and billing information.
249
9.HARDWARE AND SOFTWARE
REQUIREMENTS:-
Software Requirement :
Spring (Boot, Data, Security, MVC etc)
• JPA / Hibernate
• MYSQL
• Thymeleaf
• Bootstrap, CSS, JS
• Maven
• Junit
• Lombok * SQL Query
250
10. References
• http://krex.k-state.edu/dspace/handle/2097/959
Smart Draw for drawing all the Diagrams used in this report.
http://www.smartdraw.com/
251
252