package com.devicehive.dao.rdbms; /* * #%L * DeviceHive Dao RDBMS Implementation * %% * Copyright (C) 2016 DataArt * %% * 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. * #L% */ import com.devicehive.dao.UserDao; import com.devicehive.model.Network; import com.devicehive.model.User; import com.devicehive.vo.NetworkVO; import com.devicehive.vo.UserVO; import com.devicehive.vo.UserWithNetworkVO; import org.springframework.stereotype.Repository; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.validation.constraints.NotNull; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import static java.util.Optional.empty; import static java.util.Optional.of; import static java.util.Optional.ofNullable; @Repository public class UserDaoRdbmsImpl extends RdbmsGenericDao implements UserDao { @Override public Optional<UserVO> findByName(String name) { Optional<User> login = createNamedQuery(User.class, "User.findByName", of(CacheConfig.get())) .setParameter("login", name) .getResultList() .stream().findFirst(); return optionalUserConvertToVo(login); } @Override public UserVO findByGoogleName(String name) { User user = createNamedQuery(User.class, "User.findByGoogleName", empty()) .setParameter("login", name) .getResultList() .stream().findFirst().orElse(null); return User.convertToVo(user); } @Override public UserVO findByFacebookName(String name) { User user = createNamedQuery(User.class, "User.findByFacebookName", empty()) .setParameter("login", name) .getResultList() .stream().findFirst().orElse(null); return User.convertToVo(user); } @Override public UserVO findByGithubName(String name) { User user = createNamedQuery(User.class, "User.findByGithubName", empty()) .setParameter("login", name) .getResultList() .stream().findFirst().orElse(null); return User.convertToVo(user); } @Override public Optional<UserVO> findByIdentityName(String login, String googleLogin, String facebookLogin, String githubLogin) { Optional<User> user = createNamedQuery(User.class, "User.findByIdentityName", of(CacheConfig.bypass())) .setParameter("login", login) .setParameter("googleLogin", googleLogin) .setParameter("facebookLogin", facebookLogin) .setParameter("githubLogin", githubLogin) .getResultList() .stream().findFirst(); return optionalUserConvertToVo(user); } @Override public long hasAccessToNetwork(UserVO user, NetworkVO network) { Network nw = reference(Network.class, network.getId()); return createNamedQuery(Long.class, "User.hasAccessToNetwork", empty()) .setParameter("user", user.getId()) .setParameter("network", nw) .getSingleResult(); } @Override public long hasAccessToDevice(UserVO user, String deviceGuid) { return createNamedQuery(Long.class, "User.hasAccessToDevice", empty()) .setParameter("user", user.getId()) .setParameter("guid", deviceGuid) .getSingleResult(); } @Override public UserWithNetworkVO getWithNetworksById(long id) { User user = createNamedQuery(User.class, "User.getWithNetworksById", of(CacheConfig.refresh())) .setParameter("id", id) .getResultList() .stream().findFirst().orElse(null); if (user == null) { return null; } UserVO vo = User.convertToVo(user); UserWithNetworkVO userWithNetworkVO = UserWithNetworkVO.fromUserVO(vo); //TODO [rafa] change here to bulk fetch data if (user.getNetworks() != null) { for (Network network : user.getNetworks()) { NetworkVO networkVo = Network.convertNetwork(network); userWithNetworkVO.getNetworks().add(networkVo); } } return userWithNetworkVO; } @Override public int deleteById(long id) { return createNamedQuery("User.deleteById", of(CacheConfig.bypass())) .setParameter("id", id) .executeUpdate(); } @Override public UserVO find(Long id) { User user = find(User.class, id); return User.convertToVo(user); } @Override public void persist(UserVO user) { User entity = User.convertToEntity(user); super.persist(entity); user.setId(entity.getId()); } @Override public UserVO merge(UserVO existing) { User entity = User.convertToEntity(existing); User merge = super.merge(entity); return User.convertToVo(merge); } @Override public void unassignNetwork(@NotNull UserVO existingUser, @NotNull long networkId) { createNamedQuery(Network.class, "Network.findWithUsers", of(CacheConfig.refresh())) .setParameter("id", networkId) .getResultList() .stream().findFirst() .ifPresent(existingNetwork -> { User usr = new User(); usr.setId(existingUser.getId()); existingNetwork.getUsers().remove(usr); merge(existingNetwork); }); } @Override public List<UserVO> list(String login, String loginPattern, Integer role, Integer status, String sortField, Boolean sortOrderAsc, Integer take, Integer skip) { CriteriaBuilder cb = criteriaBuilder(); CriteriaQuery<User> cq = cb.createQuery(User.class); Root<User> from = cq.from(User.class); Predicate[] predicates = CriteriaHelper.userListPredicates(cb, from, ofNullable(login), ofNullable(loginPattern), ofNullable(role), ofNullable(status)); cq.where(predicates); CriteriaHelper.order(cb, cq, from, ofNullable(sortField), Boolean.TRUE.equals(sortOrderAsc)); TypedQuery<User> query = createQuery(cq); cacheQuery(query, of(CacheConfig.refresh())); ofNullable(take).ifPresent(query::setMaxResults); ofNullable(skip).ifPresent(query::setFirstResult); return query.getResultList().stream().map(User::convertToVo).collect(Collectors.toList()); } private Optional<UserVO> optionalUserConvertToVo(Optional<User> login) { if (login.isPresent()) { return Optional.ofNullable(User.convertToVo(login.get())); } return Optional.empty(); } }