blob: b03023832e39044c789deb483a30543c8d8bd4d2 [file] [log] [blame]
// ***************************************************************************************************************************
// * 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 *
// * *
// * 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.apache.juneau.petstore.service;
import static java.text.MessageFormat.*;
import java.io.*;
import java.util.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.petstore.dto.*;
import org.apache.juneau.petstore.repository.OrderRepository;
import org.apache.juneau.petstore.repository.PetRepository;
import org.apache.juneau.petstore.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
/**
* Pet store database application.
* <p>
* Uses JPA persistence to store and retrieve PetStore DTOs.
* JPA beans are defined in <c>META-INF/persistence.xml</c>.
*
* <ul class='seealso'>
* <li class='extlink'>{@source}
* </ul>
*/
public class PetStoreService {
@Autowired
private PetRepository petRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private OrderRepository orderRepository;
//-----------------------------------------------------------------------------------------------------------------
// Initialization methods.
//-----------------------------------------------------------------------------------------------------------------
/**
* Initialize the petstore database using JPA.
*
* @param w Console output.
* @return This object (for method chaining).
* @throws ParseException Malformed input encountered.
* @throws IOException File could not be read from file system.
*/
public PetStoreService initDirect(PrintWriter w) throws ParseException, IOException {
JsonParser parser = JsonParser.create().build();
for (Pet x : petRepository.findAll()) {
petRepository.delete(x);
w.println(format("Deleted pet: id={0}", x.getId()));
}
for (Order x : orderRepository.findAll()) {
orderRepository.delete(x);
w.println(format("Deleted order: id={0}", x.getId()));
}
for (User x : userRepository.findAll()) {
userRepository.delete(x);
w.println(format("Deleted user: username={0}", x.getUsername()));
}
for (Pet x : parser.parse(getStream("init/Pets.json"), Pet[].class)) {
petRepository.save(x);
w.println(format("Created pet: id={0}, name={1}", x.getId(), x.getName()));
}
for (Order x : parser.parse(getStream("init/Orders.json"), Order[].class)) {
orderRepository.save(x);
w.println(format("Created order: id={0}", x.getId()));
}
for (User x: parser.parse(getStream("init/Users.json"), User[].class)) {
userRepository.save(x);
w.println(format("Created user: username={0}", x.getUsername()));
}
return this;
}
//-----------------------------------------------------------------------------------------------------------------
// Service methods.
//-----------------------------------------------------------------------------------------------------------------
/**
* Returns the pet with the specified ID.
*
* @param id The pet ID.
* @return The pet with the specified ID. Never <jk>null</jk>.
* @throws IdNotFound If pet was not found.
*/
public Pet getPet(long id) throws IdNotFound {
return petRepository.findById(id).get();
}
/**
* Returns the order with the specified ID.
*
* @param id The order ID.
* @return The order with the specified ID. Never <jk>null</jk>.
* @throws IdNotFound If order was not found.
*/
public Order getOrder(long id) throws IdNotFound {
return orderRepository.findById(id).get();
}
/**
* Returns the user with the specified username.
*
* @param username The username.
* @return The user with the specified username. Never <jk>null</jk>.
* @throws InvalidUsername Username was not valid.
* @throws IdNotFound If order was not found.
*/
public User getUser(String username) throws InvalidUsername, IdNotFound {
assertValidUsername(username);
return userRepository.findByUsername(username).orElseThrow(() -> new IdNotFound(username, User.class));
}
/**
* Returns all pets in the database.
*
* @return All pets in the database.
*/
public List<Pet> getPets() {
return petRepository.findAll();
}
/**
* Returns all orders in the database.
*
* @return All orders in the database.
*/
public List<Order> getOrders() {
return orderRepository.findAll();
}
/**
* Returns all users in the database.
*
* @return All users in the database.
*/
public List<User> getUsers() {
return userRepository.findAll();
}
/**
* Creates a new pet in the database.
*
* @param c The pet input data.
* @return a new {@link Pet} object.
*/
public Pet create(CreatePet c) {
return petRepository.save((new Pet().status(PetStatus.AVAILABLE).apply(c)));
}
/**
* Creates a new order in the database.
*
* @param c The order input data.
* @return a new {@link Order} object.
*/
public Order create(CreateOrder c) {
return orderRepository.save((new Order().status(OrderStatus.PLACED).apply(c)));
}
/**
* Creates a new user in the database.
*
* @param c The user input data.
* @return a new {@link User} object.
*/
public User create(User c) {
assertValidUsername(c.getUsername());
return userRepository.save((new User().apply(c)));
}
/**
* Updates a pet in the database.
*
* @param u The update information.
* @return The updated {@link Pet} object.
* @throws IdNotFound Pet was not found.
*/
@Transactional(rollbackFor=Exception.class)
public Pet update(UpdatePet u) throws IdNotFound {
Pet pet = petRepository.findById(u.getId()).orElseThrow(() -> new IdNotFound(u.getId(), Pet.class));
return petRepository.save(pet.apply(u));
}
/**
* Updates an order in the database.
*
* @param o The update information.
* @return The updated {@link Order} object.
* @throws IdNotFound Order was not found.
*/
@Transactional(rollbackFor=Exception.class)
public Order update(Order o) throws IdNotFound {
Order order = orderRepository.findById(o.getId()).orElseThrow(() -> new IdNotFound(o.getId(), Order.class));
return orderRepository.save(order.apply(o));
}
/**
* Updates a user in the database.
*
* @param u The update information.
* @return The updated {@link User} object.
* @throws IdNotFound User was not found.
* @throws InvalidUsername The username was not valid.
*/
@Transactional(rollbackFor=Exception.class)
public User update(User u) throws IdNotFound, InvalidUsername {
User user = userRepository.findByUsername(u.getUsername()).orElseThrow(() -> new IdNotFound(u.getUsername(), Order.class));
return userRepository.save(user.apply(u));
}
/**
* Removes a pet from the database.
*
* @param id The pet ID.
* @throws IdNotFound Pet was not found.
*/
@Transactional(rollbackFor=Exception.class)
public void deletePet(long id) throws IdNotFound {
petRepository.deleteById(id);
}
/**
* Removes all pets from the database.
*/
@Transactional(rollbackFor=Exception.class)
public void deleteAllPets() {
petRepository.deleteAll();
}
/**
* Removes an order from the database.
*
* @param id The order ID.
* @throws IdNotFound Order was not found.
*/
@Transactional(rollbackFor=Exception.class)
public void deleteOrder(long id) throws IdNotFound {
orderRepository.deleteById(id);
}
/**
* Removes all orders from the database.
*/
@Transactional(rollbackFor=Exception.class)
public void deleteAllOrders() {
orderRepository.deleteAll();
}
/**
* Removes a user from the database.
*
* @param username The username.
* @throws IdNotFound User was not found.
*/
@Transactional(rollbackFor=Exception.class)
public void deleteUser(String username) throws IdNotFound {
userRepository.deleteByUsername(username);
}
/**
* Removes all users from the database.
*/
@Transactional(rollbackFor=Exception.class)
public void deleteAllUsers() {
userRepository.deleteAll();
}
/**
* Returns all pets with the specified statuses.
*
* @param status Pet statuses.
* @return Pets with the specified statuses.
*/
public Collection<Pet> getPetsByStatus(PetStatus[] status) {
return petRepository.findByStatus(status);
}
/**
* Returns a summary of pet statuses and counts.
*
* @return A summary of pet statuses and counts.
*/
public Map<PetStatus,Integer> getInventory() {
Map<PetStatus,Integer> m = new LinkedHashMap<>();
for (Pet p : getPets()) {
PetStatus ps = p.getStatus();
if (! m.containsKey(ps))
m.put(ps, 1);
else
m.put(ps, m.get(ps) + 1);
}
return m;
}
/**
* Returns <jk>true</jk> if the specified username and password is valid.
*
* @param username The username.
* @param password The password.
* @return <jk>true</jk> if the specified username and password is valid.
*/
public boolean isValid(String username, String password) {
return getUser(username).getPassword().equals(password);
}
//-----------------------------------------------------------------------------------------------------------------
// Helper methods
//-----------------------------------------------------------------------------------------------------------------
private void assertValidUsername(String username) throws InvalidUsername {
if (username == null || ! username.matches("[\\w\\d]{3,8}"))
throw new InvalidUsername();
}
private InputStream getStream(String fileName) {
return getClass().getResourceAsStream(fileName);
}
}