1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.exoplatform.social.core.jpa.storage.dao.jpa.query;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import javax.persistence.EntityManager;
27 import javax.persistence.TypedQuery;
28 import javax.persistence.criteria.*;
29
30 import org.exoplatform.social.core.jpa.search.ExtendProfileFilter;
31 import org.exoplatform.social.core.jpa.storage.entity.IdentityEntity;
32 import org.exoplatform.social.core.jpa.storage.entity.IdentityEntity_;
33 import org.exoplatform.social.core.jpa.storage.entity.ProfileExperienceEntity;
34 import org.exoplatform.social.core.jpa.storage.entity.ProfileExperienceEntity_;
35 import org.exoplatform.social.core.identity.model.Identity;
36 import org.exoplatform.social.core.identity.model.Profile;
37
38
39
40
41 public class ProfileQueryBuilder {
42
43 ExtendProfileFilter filter;
44
45 private ProfileQueryBuilder() {
46
47 }
48
49 public static ProfileQueryBuilder builder() {
50 return new ProfileQueryBuilder();
51 }
52
53 public ProfileQueryBuilder withFilter(ExtendProfileFilter filter) {
54 this.filter = filter;
55 return this;
56 }
57
58
59
60
61
62
63 public TypedQuery[] build(EntityManager em) {
64 CriteriaBuilder cb = em.getCriteriaBuilder();
65 CriteriaQuery query = cb.createQuery(IdentityEntity.class);
66
67 Root<IdentityEntity> identity = query.from(IdentityEntity.class);
68
69 List<Predicate> predicates = new ArrayList<>();
70
71 if (filter != null) {
72 if (filter.isForceLoadProfile()) {
73
74
75 }
76
77 if (filter.isExcludeDeleted()) {
78 predicates.add(cb.isFalse(identity.get(IdentityEntity_.deleted)));
79 }
80
81 if (filter.isExcludeDisabled()) {
82 predicates.add(cb.isTrue(identity.get(IdentityEntity_.enabled)));
83 }
84
85 if (filter.getIdentityIds() != null && filter.getIdentityIds().size() > 0) {
86 predicates.add(identity.get(IdentityEntity_.id).in(filter.getIdentityIds()));
87 }
88
89 if (filter.getRemoteIds() != null && filter.getRemoteIds().size() > 0) {
90 predicates.add(identity.get(IdentityEntity_.remoteId).in(filter.getRemoteIds()));
91 }
92
93 if (filter.getProviderId() != null && !filter.getProviderId().isEmpty()) {
94 predicates.add(cb.equal(identity.get(IdentityEntity_.providerId), filter.getProviderId()));
95 }
96
97 SetJoin<IdentityEntity, ProfileExperienceEntity> experience = null;
98
99 List<Identity> excludes = filter.getExcludedIdentityList();
100 if (excludes != null && excludes.size() > 0) {
101 List<Long> ids = new ArrayList<>(excludes.size());
102 for (Identity id : excludes) {
103 ids.add(Long.parseLong(id.getId()));
104 }
105 predicates.add(cb.not(identity.get(IdentityEntity_.id).in(ids)));
106 }
107
108 String all = filter.getAll();
109 if (all == null || all.trim().isEmpty()) {
110 String name = filter.getName();
111 if (name != null && !name.isEmpty()) {
112 name = processLikeString(name);
113 MapJoin<IdentityEntity, String, String> properties = identity.join(IdentityEntity_.properties, JoinType.LEFT);
114 predicates.add(cb.and(cb.like(cb.lower(properties.value()), name), properties.key().in(Arrays.asList(Profile.FIRST_NAME, Profile.LAST_NAME, Profile.FULL_NAME))));
115 }
116
117 String val = filter.getPosition();
118 if (val != null && !val.isEmpty()) {
119 val = processLikeString(val);
120 Predicate[] p = new Predicate[2];
121 MapJoin<IdentityEntity, String, String> properties = identity.join(IdentityEntity_.properties, JoinType.LEFT);
122 p[1] = cb.and(cb.like(cb.lower(properties.value()), val), cb.equal(properties.key(), Profile.POSITION));
123 if(experience == null) {
124 experience = identity.join(IdentityEntity_.experiences, JoinType.LEFT);
125 }
126 p[0] = cb.like(cb.lower(experience.get(ProfileExperienceEntity_.position)), val);
127
128 predicates.add(cb.or(p));
129 }
130
131 val = filter.getSkills();
132 if (val != null && !val.isEmpty()) {
133 val = processLikeString(val);
134 if(experience == null) {
135 experience = identity.join(IdentityEntity_.experiences, JoinType.LEFT);
136 }
137 predicates.add(cb.like(cb.lower(experience.get(ProfileExperienceEntity_.skills)), val));
138 }
139
140 val = filter.getCompany();
141 if (val != null && !val.isEmpty()) {
142 val = processLikeString(val);
143 if(experience == null) {
144 experience = identity.join(IdentityEntity_.experiences, JoinType.LEFT);
145 }
146 predicates.add(cb.like(cb.lower(experience.get(ProfileExperienceEntity_.company)), val));
147 }
148 } else {
149
150 String name = filter.getName();
151 all = processLikeString(all).toLowerCase();
152 Predicate[] p = new Predicate[5];
153 MapJoin<IdentityEntity, String, String> properties = identity.join(IdentityEntity_.properties, JoinType.LEFT);
154 p[0] = cb.and(cb.like(cb.lower(properties.value()), name), properties.key().in(Arrays.asList(Profile.FIRST_NAME, Profile.LAST_NAME, Profile.FULL_NAME)));
155
156 if(experience == null) {
157 experience = identity.join(IdentityEntity_.experiences, JoinType.LEFT);
158 }
159 p[1] = cb.like(cb.lower(experience.get(ProfileExperienceEntity_.position)), all);
160 p[2] = cb.like(cb.lower(experience.get(ProfileExperienceEntity_.skills)), all);
161 p[3] = cb.like(cb.lower(experience.get(ProfileExperienceEntity_.company)), all);
162 p[4] = cb.like(cb.lower(experience.get(ProfileExperienceEntity_.description)), all);
163
164 predicates.add(cb.or(p));
165 }
166
167 char c = filter.getFirstCharacterOfName();
168 if (c != '\u0000') {
169 String val = Character.toLowerCase(c) + "%";
170 MapJoin<IdentityEntity, String, String> properties = identity.join(IdentityEntity_.properties, JoinType.LEFT);
171 predicates.add(cb.and(cb.equal(properties.key(), Profile.LAST_NAME), cb.like(cb.lower(properties.value()), val)));
172 }
173 }
174
175 Predicate[] pds = predicates.toArray(new Predicate[predicates.size()]);
176
177 query.select(cb.countDistinct(identity)).where(pds);
178 TypedQuery<Long> count = em.createQuery(query);
179
180 query.select(identity).distinct(true).where(pds);
181 TypedQuery<IdentityEntity> select = em.createQuery(query);
182
183
184 return new TypedQuery[]{select, count};
185 }
186
187 private String processLikeString(String s) {
188 return "%" + s.toLowerCase() + "%";
189 }
190 }