Java tutorial
/* * Copyright 2016 the original author or authors. * * 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 se.omegapoint.facepalm.infrastructure; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import se.omegapoint.facepalm.domain.NewUserCredentials; import se.omegapoint.facepalm.domain.event.EventService; import se.omegapoint.facepalm.domain.repository.UserRepository; import se.omegapoint.facepalm.infrastructure.db.Friendship; import se.omegapoint.facepalm.infrastructure.db.User; import se.omegapoint.facepalm.infrastructure.event.GenericEvent; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.sql.Date; import java.time.LocalDate; import java.util.List; import java.util.Optional; import java.util.Set; import static java.lang.String.format; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import static org.apache.commons.lang3.Validate.notBlank; import static org.apache.commons.lang3.Validate.notNull; @SuppressWarnings("unchecked") @Repository @Transactional public class JPAUserRepository implements UserRepository { private final static Logger LOGGER = LoggerFactory.getLogger(JPAUserRepository.class); private final EventService eventService; @PersistenceContext private EntityManager entityManager; @Autowired public JPAUserRepository(final EventService eventService) { this.eventService = notNull(eventService); } @Override public Optional<se.omegapoint.facepalm.domain.User> findByUsername(final String username) { notBlank(username); eventService.publish(new GenericEvent(format("Searching for username[%s]", username))); return findUserFromUsername(username).map(this::convertUserToDomain); } @Override public Optional<se.omegapoint.facepalm.domain.User> findByNameAndPassword(final String username, final String password) { notNull(username); notNull(password); final String query = format("SELECT * FROM ACCOUNTS WHERE USERNAME = '%s' AND PASSWORD = '%s'", username, password); final List<User> users = entityManager.createNativeQuery(query, User.class).getResultList(); eventService.publish(users.isEmpty() ? new GenericEvent(format("No matching user with username[%s], password[%s]", username, password)) : new GenericEvent( format("Found matching users with username[%s], password[%s]", username, password))); return users.isEmpty() ? Optional.empty() : Optional.of(convertUserToDomain(users.get(0))); } @Override public List<se.omegapoint.facepalm.domain.User> findLike(final String value) { notBlank(value); eventService.publish(new GenericEvent(format("Searching for friends like [%s]", value))); final String query = "SELECT u FROM User u WHERE LOWER(u.username) LIKE :query OR " + " LOWER(u.firstname) LIKE :query OR " + " LOWER(u.lastname) LIKE :query "; return entityManager.createQuery(query, User.class).setParameter("query", likeify(value)).getResultList() .stream().map(this::convertUserToDomain).collect(toList()); } @Override public Set<se.omegapoint.facepalm.domain.User> findFriendsFor(final String value) { notBlank(value); eventService.publish(new GenericEvent(format("Searching for friends with username[%s]", value))); final List<User> friends = entityManager .createNativeQuery("" + "SELECT * FROM ACCOUNTS WHERE USERNAME IN " + " ( " + " SELECT USER_ID FROM FRIENDSHIPS WHERE FRIEND_ID = :a " + " UNION " + " SELECT FRIEND_ID FROM FRIENDSHIPS WHERE USER_ID = :a " + " ) ", User.class) .setParameter("a", value).getResultList(); return friends.stream().map(this::convertUserToDomain).collect(toSet()); } @Override public void addUser(final NewUserCredentials credentials) { notNull(credentials); eventService.publish(new GenericEvent(credentials)); entityManager.persist(new User(credentials.username, credentials.email, credentials.firstname, credentials.lastname, credentials.password)); } @Override public boolean usersAreFriends(final String userA, final String userB) { notBlank(userA); notBlank(userB); final Long count = entityManager.createQuery( "SELECT COUNT(f.id) FROM Friendship f WHERE (f.user = :a AND f.friend = :b) OR (f.user = :a AND f.friend = :b)", Long.class).setParameter("a", userA).setParameter("b", userB).getSingleResult(); return count > 0; } @Override public void addFriend(final String user, final String friendToAdd) { notBlank(user); notBlank(friendToAdd); eventService.publish(new GenericEvent(format("User[%s] is now friend of [%s]", user, friendToAdd))); entityManager.persist(new Friendship(user, friendToAdd, Date.valueOf(LocalDate.now()))); } private Optional<User> findUserFromUsername(final String username) { final List<User> users = entityManager .createQuery("SELECT u FROM User u WHERE u.username = :username", User.class) .setParameter("username", username).getResultList(); return users.isEmpty() ? Optional.empty() : Optional.of(users.get(0)); } private se.omegapoint.facepalm.domain.User convertUserToDomain(final User user) { return new se.omegapoint.facepalm.domain.User(user.getUsername(), user.getEmail(), user.getFirstname(), user.getLastname()); } private String likeify(final String query) { return "%" + query.toLowerCase() + "%"; } }