1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.dao;
20
21 import java.time.OffsetDateTime;
22 import java.util.List;
23 import javax.persistence.NoResultException;
24 import javax.persistence.Query;
25 import javax.persistence.TypedQuery;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
28 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
29 import org.apache.syncope.core.persistence.api.entity.AccessToken;
30 import org.apache.syncope.core.persistence.jpa.entity.JPAAccessToken;
31 import org.springframework.transaction.annotation.Transactional;
32 import org.springframework.util.ReflectionUtils;
33
34 public class JPAAccessTokenDAO extends AbstractDAO<AccessToken> implements AccessTokenDAO {
35
36 @Transactional(readOnly = true)
37 @Override
38 public AccessToken find(final String key) {
39 return entityManager().find(JPAAccessToken.class, key);
40 }
41
42 @Transactional(readOnly = true)
43 @Override
44 public AccessToken findByOwner(final String username) {
45 TypedQuery<AccessToken> query = entityManager().createQuery(
46 "SELECT e FROM " + JPAAccessToken.class.getSimpleName() + " e "
47 + "WHERE e.owner=:username", AccessToken.class);
48 query.setParameter("username", username);
49
50 AccessToken result = null;
51 try {
52 result = query.getSingleResult();
53 } catch (NoResultException e) {
54 LOG.debug("No token for user {} could be found", username, e);
55 }
56
57 return result;
58 }
59
60 private static StringBuilder buildFindAllQuery() {
61 return new StringBuilder("SELECT e FROM ").
62 append(JPAAccessToken.class.getSimpleName()).
63 append(" e WHERE 1=1");
64 }
65
66 @Transactional(readOnly = true)
67 @Override
68 public int count() {
69 StringBuilder queryString = buildFindAllQuery();
70
71 Query query = entityManager().createQuery(StringUtils.replaceOnce(
72 queryString.toString(), "SELECT e", "SELECT COUNT(e)"));
73 return ((Number) query.getSingleResult()).intValue();
74 }
75
76 private static String toOrderByStatement(final List<OrderByClause> orderByClauses) {
77 StringBuilder statement = new StringBuilder();
78
79 orderByClauses.forEach(clause -> {
80 String field = clause.getField().trim();
81 if (ReflectionUtils.findField(JPAAccessToken.class, field) != null) {
82 statement.append("e.").append(field).append(' ').append(clause.getDirection().name());
83 }
84 });
85
86 if (statement.length() == 0) {
87 statement.append(" ORDER BY e.expirationTime DESC");
88 } else {
89 statement.insert(0, "ORDER BY ");
90 }
91 return statement.toString();
92 }
93
94 @Transactional(readOnly = true)
95 @Override
96 public List<AccessToken> findAll(final int page, final int itemsPerPage, final List<OrderByClause> orderByClauses) {
97 StringBuilder queryString = buildFindAllQuery().append(toOrderByStatement(orderByClauses));
98
99 TypedQuery<AccessToken> query = entityManager().createQuery(queryString.toString(), AccessToken.class);
100
101 query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
102
103 if (itemsPerPage > 0) {
104 query.setMaxResults(itemsPerPage);
105 }
106
107 return query.getResultList();
108 }
109
110 @Transactional(rollbackFor = Throwable.class)
111 @Override
112 public AccessToken save(final AccessToken accessToken) {
113 return entityManager().merge(accessToken);
114 }
115
116 @Transactional(rollbackFor = Throwable.class)
117 @Override
118 public void delete(final String key) {
119 AccessToken accessToken = find(key);
120 if (accessToken == null) {
121 return;
122 }
123
124 delete(accessToken);
125 }
126
127 @Override
128 public void delete(final AccessToken accessToken) {
129 entityManager().remove(accessToken);
130 }
131
132 @Override
133 public int deleteExpired() {
134 Query query = entityManager().createQuery(
135 "DELETE FROM " + JPAAccessToken.class.getSimpleName() + " e "
136 + "WHERE e.expirationTime < :now");
137 query.setParameter("now", OffsetDateTime.now());
138 return query.executeUpdate();
139 }
140 }