Java tutorial
/* * Copyright (c) 2010. Axon Framework * * Licensed 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 * * http://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 KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.axonframework.examples.addressbook.web; import org.axonframework.commandhandling.CommandBus; import org.axonframework.commandhandling.GenericCommandMessage; import org.axonframework.sample.app.api.AddressType; import org.axonframework.sample.app.api.ChangeContactNameCommand; import org.axonframework.sample.app.api.CreateContactCommand; import org.axonframework.sample.app.api.RegisterAddressCommand; import org.axonframework.sample.app.api.RemoveAddressCommand; import org.axonframework.sample.app.api.RemoveContactCommand; import org.axonframework.sample.app.command.ContactNameRepository; import org.axonframework.sample.app.query.AddressEntry; import org.axonframework.sample.app.query.ContactEntry; import org.axonframework.sample.app.query.ContactRepository; //import org.slf4j.Logger; //import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; import javax.validation.Valid; /** * @author Jettro Coenradie */ @Controller @RequestMapping(value = "/contacts") public class ContactsController { // private final static Logger logger = LoggerFactory.getLogger(ContactsController.class); @Autowired private ContactRepository repository; @Autowired private ContactNameRepository contactNameRepository; @Autowired private CommandBus commandBus; @RequestMapping(method = RequestMethod.GET) public String list(Model model) { model.addAttribute("contacts", repository.findAllContacts()); return "contacts/list"; } @RequestMapping(value = "{identifier}", method = RequestMethod.GET) public String details(@PathVariable String identifier, Model model) { List<AddressEntry> addressesForContact = repository.findAllAddressesForContact(identifier); String name; if (addressesForContact.size() > 0) { name = addressesForContact.get(0).getName(); } else { name = repository.loadContactDetails(identifier).getName(); } model.addAttribute("addresses", addressesForContact); model.addAttribute("identifier", identifier); model.addAttribute("name", name); return "contacts/details"; } @RequestMapping(value = "{identifier}/edit", method = RequestMethod.GET) public String formEdit(@PathVariable String identifier, Model model) { ContactEntry contactEntry = repository.loadContactDetails(identifier); model.addAttribute("contact", contactEntry); return "contacts/edit"; } @RequestMapping(value = "{identifier}/edit", method = RequestMethod.POST) public String formEditSubmit(@ModelAttribute("contact") @Valid ContactEntry contact, BindingResult bindingResult) { // beware, we cannot support other updates since that would always give an error when the name is not changed if (contactHasErrors(contact, bindingResult)) { return "contacts/edit"; } ChangeContactNameCommand command = new ChangeContactNameCommand(); command.setContactNewName(contact.getName()); command.setContactId(contact.getIdentifier()); commandBus.dispatch(new GenericCommandMessage<Object>(command)); return "contacts/edit"; } @RequestMapping(value = "new", method = RequestMethod.GET) public String formNew(Model model) { ContactEntry attributeValue = new ContactEntry(); model.addAttribute("contact", attributeValue); return "contacts/new"; } /** * If we submit a new contact, we want immediate feedback if the contact could be added. If it could not be added * we want an error. Therefore we use the Future callback mechanism as provide by Axon. * * @param contact ContactEntry object that contains the entered data * @param bindingResult BindingResult containing information about the binding of the form data to the ContactEntry * @return String representing the name of the view to present. */ @RequestMapping(value = "new", method = RequestMethod.POST) public String formNewSubmit(@ModelAttribute("contact") @Valid ContactEntry contact, BindingResult bindingResult) { if (contactHasErrors(contact, bindingResult)) { return "contacts/new"; } CreateContactCommand command = new CreateContactCommand(); command.setNewContactName(contact.getName()); commandBus.dispatch(new GenericCommandMessage<Object>(command)); return "redirect:/contacts"; } @RequestMapping(value = "{identifier}/delete", method = RequestMethod.GET) public String formDelete(@PathVariable String identifier, Model model) { ContactEntry contactEntry = repository.loadContactDetails(identifier); model.addAttribute("contact", contactEntry); return "contacts/delete"; } @RequestMapping(value = "{identifier}/delete", method = RequestMethod.POST) public String formDelete(@ModelAttribute("contact") ContactEntry contact, BindingResult bindingResult) { if (!bindingResult.hasErrors()) { RemoveContactCommand command = new RemoveContactCommand(); command.setContactId(contact.getIdentifier()); commandBus.dispatch(new GenericCommandMessage<Object>(command)); return "redirect:/contacts"; } return "contacts/delete"; } @RequestMapping(value = "{identifier}/address/new", method = RequestMethod.GET) public String formNewAddress(@PathVariable String identifier, Model model) { ContactEntry contactEntry = repository.loadContactDetails(identifier); AddressEntry addressEntry = new AddressEntry(); addressEntry.setIdentifier(contactEntry.getIdentifier()); addressEntry.setName(contactEntry.getName()); model.addAttribute("address", addressEntry); return "contacts/address"; } @RequestMapping(value = "{identifier}/address/new", method = RequestMethod.POST) public String formNewAddressSubmit(@ModelAttribute("address") @Valid AddressEntry address, BindingResult bindingResult) { if (!bindingResult.hasErrors()) { RegisterAddressCommand command = new RegisterAddressCommand(); command.setAddressType(address.getAddressType()); command.setCity(address.getCity()); command.setContactId(address.getIdentifier()); command.setStreetAndNumber(address.getStreetAndNumber()); command.setZipCode(address.getZipCode()); commandBus.dispatch(new GenericCommandMessage<Object>(command)); return "redirect:/contacts/" + address.getIdentifier(); } return "contacts/address"; } @RequestMapping(value = "{identifier}/address/delete/{addressType}", method = RequestMethod.GET) public String formDeleteAddress(@PathVariable String identifier, @PathVariable AddressType addressType, Model model) { ContactEntry contactEntry = repository.loadContactDetails(identifier); AddressEntry addressEntry = new AddressEntry(); addressEntry.setIdentifier(contactEntry.getIdentifier()); addressEntry.setName(contactEntry.getName()); addressEntry.setAddressType(addressType); model.addAttribute("address", addressEntry); return "contacts/removeAddress"; } @RequestMapping(value = "{identifier}/address/delete/{addressType}", method = RequestMethod.POST) public String formDeleteAddressSubmit(@ModelAttribute("address") AddressEntry address, BindingResult bindingResult) { if (!bindingResult.hasErrors()) { RemoveAddressCommand command = new RemoveAddressCommand(); command.setContactId(address.getIdentifier()); command.setAddressType(address.getAddressType()); commandBus.dispatch(new GenericCommandMessage<Object>(command)); return "redirect:/contacts/" + address.getIdentifier(); } return "contacts/removeAddress"; } /** * Checks if the entered data for a contact is valid and if the provided contact has not yet been taken. * * @param contact Contact to validate * @param bindingResult BindingResult that can contain error and can be used to store additional errors * @return true if the contact has errors, false otherwise */ private boolean contactHasErrors(ContactEntry contact, BindingResult bindingResult) { if (bindingResult.hasErrors() || !contactNameRepository.vacantContactName(contact.getName())) { ObjectError error = new FieldError("contact", "name", "The provided name \'" + contact.getName() + "\' already exists"); bindingResult.addError(error); return true; } return false; } }