mirror of
https://github.com/st-tu-dresden-praktikum/swt23w23
synced 2024-07-19 21:04:36 +02:00
WIP WIP WIP Implement InventoryMutateFormArgumentResolver for InventoryMutateForm
This commit is contained in:
parent
20ea9e5869
commit
75cb944d12
|
@ -3,16 +3,24 @@
|
|||
// SPDX-FileCopyrightText: 2023 swt23w23
|
||||
package catering;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.salespointframework.EnableSalespoint;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import catering.inventory.InventoryMutateFormArgumentResolver;
|
||||
import catering.inventory.InventoryMutateFormModelAttributeMethodProcessor;
|
||||
|
||||
/**
|
||||
* The main application class.
|
||||
*/
|
||||
|
@ -46,10 +54,18 @@ public class Application {
|
|||
|
||||
@Configuration
|
||||
static class WebConfiguration implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
WebApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/login").setViewName("login");
|
||||
registry.addViewController("/").setViewName("index");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||
resolvers.add(new InventoryMutateFormArgumentResolver(applicationContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ import org.springframework.stereotype.Controller;
|
|||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import catering.catalog.CateringCatalog;
|
||||
import catering.catalog.Consumable;
|
||||
import catering.catalog.Rentable;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/*
|
||||
|
@ -89,9 +89,6 @@ class InventoryController {
|
|||
/**
|
||||
* Returns the edit page for an inventory product.
|
||||
*
|
||||
* This method is not mapped,
|
||||
* but is used by other methods to generalise the display of the edit page.
|
||||
*
|
||||
* @param model an instance of {@link Model}
|
||||
* @param form an already filled or empty {@link InventoryMutateForm}
|
||||
* @return the inventory-mutate template with the {@link InventoryMutateForm}
|
||||
|
@ -104,47 +101,9 @@ class InventoryController {
|
|||
return "inventory-mutate";
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits a consumable.
|
||||
*
|
||||
* @param form a user-filled {@link ConsumableMutateForm}
|
||||
* @param errors an {@link Errors} object including validation errors
|
||||
* @param pid the {@link Product} to edit
|
||||
* @param model an instance of {@link Model}
|
||||
* @return a redirect on success, otherwise the filled form with all errors
|
||||
* highlighted
|
||||
*/
|
||||
@PostMapping(path = "/inventory/edit/{pid}", params = "type=Consumable")
|
||||
String editConsumable(@Valid @ModelAttribute("form") ConsumableMutateForm form, Errors result,
|
||||
@PathVariable Consumable pid, Model model) {
|
||||
return edit(form, result, pid, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits a rentable.
|
||||
*
|
||||
* @param form a user-filled {@link RentableMutateForm}
|
||||
* @param errors an {@link Errors} object including validation errors
|
||||
* @param pid the {@link Product} to edit
|
||||
* @param model an instance of {@link Model}
|
||||
* @return a redirect on success, otherwise the filled form with all errors
|
||||
* highlighted
|
||||
*/
|
||||
@PostMapping(path = "/inventory/edit/{pid}", params = "type=Rentable")
|
||||
String editRentable(@Valid @ModelAttribute("form") RentableMutateForm form, Errors result,
|
||||
@PathVariable Rentable pid, Model model) {
|
||||
return edit(form, result, pid, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits an inventory product.
|
||||
*
|
||||
* This method is not mapped,
|
||||
* but is used by
|
||||
* {@link #editConsumable(ConsumableMutateForm, Errors, Consumable, Model)}
|
||||
* and {@link #editRentable(RentableMutateForm, Errors, Rentable, Model)}
|
||||
* to generalise the editing of products.
|
||||
*
|
||||
* @param form a user-filled {@link RentableMutateForm}
|
||||
* @param errors an {@link Errors} object including validation errors
|
||||
* @param product the {@link Product} to edit
|
||||
|
@ -152,10 +111,12 @@ class InventoryController {
|
|||
* @return a redirect on success, otherwise the filled form with all errors
|
||||
* highlighted
|
||||
*/
|
||||
String edit(InventoryMutateForm form, Errors result, Product product, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
return edit(model, form);
|
||||
}
|
||||
@PostMapping(path = "/inventory/edit/{pid}")
|
||||
String edit(InventoryMutateForm form, @PathVariable("pid") Product product, Model model) {
|
||||
//String edit(@ModelAttribute InventoryMutateForm form, Errors result, @PathVariable("pid") Product product, Model model) {
|
||||
//if (result.hasErrors()) {
|
||||
// return edit(model, form);
|
||||
//}
|
||||
|
||||
form.modifyProduct(product);
|
||||
product = cateringCatalog.save(product);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: 2024 swt23w23
|
||||
package catering.inventory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.salespointframework.catalog.Product;
|
||||
import org.salespointframework.catalog.Product.ProductIdentifier;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import catering.catalog.CateringCatalog;
|
||||
import catering.catalog.Consumable;
|
||||
|
||||
public class InventoryMutateFormArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
@Autowired
|
||||
ModelAttributeMethodProcessor modelAttributeMethodProcessor;
|
||||
|
||||
private WebApplicationContext applicationContext;
|
||||
|
||||
public InventoryMutateFormArgumentResolver(WebApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return InventoryMutateForm.class == parameter.getParameterType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
CateringCatalog cateringCatalog = applicationContext.getBean(CateringCatalog.class);
|
||||
InventoryMutateForm form = resolveByPid(webRequest, cateringCatalog)
|
||||
.or(() -> resolveByExplicitParameter(webRequest))
|
||||
.map(InventoryMutateForm::forProductType)
|
||||
.orElse(null);
|
||||
|
||||
// trying to reimplement things from spring, don’t understand it
|
||||
Object attribute;
|
||||
var binder = binderFactory.createBinder(webRequest, attribute, "form", form.getClass());
|
||||
Object attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
|
||||
BindingResult bindingResult = binder.getBindingResult();
|
||||
Map<String, Object> bindingResultModel = bindingResult.getModel();
|
||||
mavContainer.removeAttributes(bindingResultModel);
|
||||
mavContainer.addAllAttributes(bindingResultModel);
|
||||
System.out.println(attribute);
|
||||
return attribute;
|
||||
}
|
||||
|
||||
private Optional<Class<? extends Product>> resolveByPid(NativeWebRequest webRequest,
|
||||
CateringCatalog cateringCatalog) {
|
||||
webRequest.getParameterMap().forEach((k, v) -> System.out.println(k + " → " + v));
|
||||
return Optional
|
||||
.ofNullable(getPathVariable(webRequest, "pid"))
|
||||
.map(ProductIdentifier::of)
|
||||
.flatMap(cateringCatalog::findById)
|
||||
.map(p -> p.getClass());
|
||||
}
|
||||
|
||||
private Optional<Class<? extends Product>> resolveByExplicitParameter(NativeWebRequest webRequest) {
|
||||
return Optional.ofNullable(webRequest.getParameter("type"))
|
||||
.flatMap(type -> {
|
||||
try {
|
||||
return Optional.of(Class.forName(Consumable.class.getPackageName() + "." + type));
|
||||
} catch (ClassNotFoundException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
})
|
||||
.filter(Product.class::isAssignableFrom)
|
||||
.map(c -> (Class<? extends Product>) c);
|
||||
}
|
||||
|
||||
private String getPathVariable(NativeWebRequest webRequest, String name) {
|
||||
return ((Map<String, String>) webRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE,
|
||||
NativeWebRequest.SCOPE_REQUEST)).get(name);
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ SPDX-FileCopyrightText: 2023 swt23w23
|
|||
<td th:text="${item.product.wholesalePrice.multiply(item.quantity.getAmount())}"></td>
|
||||
<td>
|
||||
<div class="d-inline-flex flex-wrap gap-1 flex-column flex-xxl-row">
|
||||
<a th:href="@{/inventory/edit/{id}(id=${item.product.id},type=${item.product.getClass().getSimpleName()})}"><button class="btn btn-warning">Bearbeiten</button></a>
|
||||
<a th:href="@{/inventory/edit/{id}(id=${item.product.id})}"><button class="btn btn-warning">Bearbeiten</button></a>
|
||||
<a th:href="@{/inventory/delete/{id}(id=${item.product.id})}"><button class="btn btn-danger">Entfernen</button></a>
|
||||
</div>
|
||||
</td>
|
||||
|
|
Loading…
Reference in a new issue