Advertisement
Guest User

Untitled

a guest
Dec 6th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.75 KB | None | 0 0
  1. package ejbs;
  2.  
  3. import dtos.DTO;
  4. import providers.Mapper;
  5. import java.io.Serializable;
  6. import java.lang.annotation.Annotation;
  7. import java.lang.reflect.Field;
  8. import java.lang.reflect.InvocationTargetException;
  9. import java.lang.reflect.Method;
  10. import java.lang.reflect.ParameterizedType;
  11. import java.util.Arrays;
  12. import java.util.LinkedList;
  13. import java.util.List;
  14. import java.util.function.Predicate;
  15. import java.util.stream.Stream;
  16. import javax.annotation.PostConstruct;
  17. import javax.ejb.EJBException;
  18. import javax.inject.Inject;
  19. import javax.persistence.EntityExistsException;
  20. import javax.persistence.EntityManager;
  21. import javax.persistence.EntityNotFoundException;
  22. import javax.persistence.Id;
  23. import javax.persistence.NamedQueries;
  24. import javax.persistence.NamedQuery;
  25. import javax.persistence.PersistenceContext;
  26. import javax.persistence.Query;
  27. import javax.ws.rs.Consumes;
  28. import javax.ws.rs.DELETE;
  29. import javax.ws.rs.GET;
  30. import javax.ws.rs.POST;
  31. import javax.ws.rs.PUT;
  32. import javax.ws.rs.Path;
  33. import javax.ws.rs.PathParam;
  34. import javax.ws.rs.Produces;
  35. import javax.ws.rs.core.MediaType;
  36.  
  37. @Consumes({ MediaType.APPLICATION_JSON })
  38. @Produces({ MediaType.APPLICATION_JSON })
  39. public abstract class BaseBean<E extends Serializable, D extends DTO, PK> {
  40.  
  41. @PersistenceContext
  42. protected EntityManager em;
  43.  
  44. protected Class<E> entityClass;
  45. protected Class<D> dtoClass;
  46.  
  47. @Inject
  48. protected Mapper mapper;
  49.  
  50. private static final String SQL_ALL = "SELECT entity FROM %s entity";
  51. private static final String SQL_EXISTS = "SELECT COUNT(e) FROM %1$s e WHERE e.%2$s = :%2$s";
  52.  
  53. @PostConstruct
  54. private void init() {
  55. entityClass = getGenericClass(0);
  56. dtoClass = getGenericClass(1);
  57. }
  58.  
  59. private <T> Class<T> getGenericClass(int index) {
  60. ParameterizedType genericType = (ParameterizedType) this.getClass().getGenericSuperclass();
  61. return (Class<T>) genericType.getActualTypeArguments()[index];
  62. }
  63.  
  64. @GET
  65. public List<D> all() {
  66. String className = entityClass.getSimpleName();
  67. String namedQuery = className + ".all";
  68.  
  69. if (containsNamedQuery(namedQuery)) {
  70. return toDTOs(createNamedQuery(namedQuery).getResultList());
  71. }
  72.  
  73. String all = String.format(SQL_ALL, className);
  74. return toDTOs(query(all).getResultList());
  75. }
  76.  
  77. @POST
  78. public D create(D dto) {
  79. E entity = toEntity(dto);
  80. entity = create(entity);
  81. return toDTO(entity);
  82. }
  83.  
  84. @GET
  85. @Path("{primaryKey}")
  86. public D retrieve(@PathParam("primaryKey") PK primaryKey) {
  87. return toDTO(find(primaryKey));
  88. }
  89.  
  90. @PUT
  91. @Path("{primaryKey}")
  92. public D update(@PathParam("primaryKey") PK primaryKey, D dto) {
  93. E entity = toEntity(dto);
  94. entity = update(entity);
  95. return toDTO(entity);
  96. }
  97.  
  98. @DELETE
  99. @Path("{primaryKey}")
  100. public boolean delete(@PathParam("primaryKey") PK primaryKey) {
  101. try {
  102. E entity = find(primaryKey);
  103.  
  104. if (entity == null) {
  105. return false;
  106. }
  107.  
  108. em.refresh(entity);
  109. em.remove(entity);
  110.  
  111. return true;
  112. } catch (Exception e) {
  113. throw new EJBException(e.getMessage(), e);
  114. }
  115. }
  116.  
  117. public boolean exists(E entity) {
  118. Field primaryKey = getPrimaryKeyField();
  119. String pkName = primaryKey.getName();
  120.  
  121. Query query = em.createQuery(buildQueryExists(), Long.class);
  122. query = query.setParameter(pkName, getValue(entity, primaryKey));
  123.  
  124. return (Long) query.getSingleResult() > 0;
  125. }
  126.  
  127. private String camelToPascalCase(String value) {
  128. return String.valueOf(value.charAt(0)).toUpperCase() + value.substring(1);
  129. }
  130.  
  131. private Method getMethod(String methodName, Class<?> ...args) throws NoSuchMethodException {
  132. try {
  133. return entityClass.getDeclaredMethod(methodName, args);
  134. } catch (NoSuchMethodException | SecurityException e) {
  135. return entityClass.getMethod(methodName, args);
  136. }
  137. }
  138.  
  139. private <T> T getValue(E entity, Field field) {
  140. try {
  141. if (field.isAccessible()) {
  142. return (T) field.get(entity);
  143. }
  144.  
  145. String fieldName = field.getName();
  146. String methodName = "get" + camelToPascalCase(fieldName);
  147.  
  148. Method getter = getMethod(methodName);
  149.  
  150. return (T) getter.invoke(entity);
  151. } catch (NullPointerException | IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException e) {
  152. return null;
  153. }
  154. }
  155.  
  156. public boolean exists(Object primaryKey) {
  157. String pkName = getPrimaryKeyField().getName();
  158.  
  159. Query query = em.createQuery(buildQueryExists(), Long.class);
  160. query = query.setParameter(pkName, primaryKey);
  161.  
  162. return (Long) query.getSingleResult() > 0;
  163. }
  164.  
  165. protected E create(E entity) {
  166. if (exists(entity)) {
  167. throw new EntityExistsException();
  168. }
  169.  
  170. em.persist(entity);
  171.  
  172. return entity;
  173. }
  174.  
  175. protected E update(E entity) {
  176. if (! exists(entity)) {
  177. throw new EntityNotFoundException();
  178. }
  179.  
  180. em.merge(entity);
  181.  
  182. return entity;
  183. }
  184.  
  185. public D createOrUpdate(D dto) {
  186. return toDTO(createOrUpdate(toEntity(dto)));
  187. }
  188.  
  189. protected E createOrUpdate(E entity) {
  190. return exists(entity) ? update(entity) : create(entity);
  191. }
  192.  
  193. private <A extends Annotation> Stream<A> getAnnotations(Class<A> annotationClass) {
  194. return Arrays.stream(entityClass.getAnnotationsByType(annotationClass));
  195. }
  196.  
  197. private Stream<NamedQuery> getNamedQueries() {
  198. // 3. Get the @NamedQuery annotations of E
  199. Stream<NamedQuery> nq = getAnnotations(NamedQuery.class);
  200.  
  201. // 4. check also for @NamedQueries annotations.
  202. Stream<NamedQuery> nq2 = getAnnotations(NamedQueries.class).map(NamedQueries::value).flatMap(Arrays::stream);
  203.  
  204. return Stream.concat(nq, nq2);
  205. }
  206.  
  207. private boolean containsNamedQuery(String namedQuery) {
  208. Stream<NamedQuery> namedQueries = getNamedQueries();
  209. return namedQueries.map(NamedQuery::name).anyMatch(namedQuery::equals);
  210. }
  211.  
  212. public E find(Object primaryKey) {
  213. return em.find(entityClass, primaryKey);
  214. }
  215.  
  216. public E findOrFail(Object primaryKey) {
  217. E entity = find(primaryKey);
  218.  
  219. if (entity == null) {
  220. String entityName = entityClass.getSimpleName();
  221. String pkName = getPrimaryKeyField().getName();
  222. throw new EntityNotFoundException("Record not found in " + entityName + " for " + pkName + " = " + primaryKey);
  223. }
  224.  
  225. return entity;
  226. }
  227.  
  228. private String buildQueryExists() {
  229. String entityName = entityClass.getSimpleName();
  230. String pkName = getPrimaryKeyField().getName();
  231.  
  232. return String.format(SQL_EXISTS, entityName, pkName);
  233. }
  234.  
  235. public E toEntity(D dto) {
  236. return mapper.map(dto, entityClass);
  237. }
  238.  
  239. public List<E> toEntities(List<D> dtos) {
  240. return mapper.map(dtos, entityClass);
  241. }
  242.  
  243. public D toDTO(E entity) {
  244. return mapper.map(entity, dtoClass);
  245. }
  246.  
  247. public List<D> toDTOs(List<E> entities) {
  248. return mapper.map(entities, dtoClass);
  249. }
  250.  
  251. private <T> List<Field> getAllDeclaredFields(Class<T> tClass) {
  252. List<Field> fields = new LinkedList<>();
  253.  
  254. Class<? super T> parentClass = tClass.getSuperclass();
  255.  
  256. if (parentClass != null) {
  257. fields.addAll(getAllDeclaredFields(parentClass));
  258. }
  259.  
  260. fields.addAll(Arrays.asList(tClass.getDeclaredFields()));
  261.  
  262. return fields;
  263. }
  264.  
  265. private Field getPrimaryKeyField() {
  266. List<Field> fields = getAllDeclaredFields(entityClass);
  267. Predicate<Field> isPrimaryKey = field -> field.getAnnotationsByType(Id.class).length > 0;
  268.  
  269. return fields.stream().filter(isPrimaryKey).findFirst().get();
  270. }
  271.  
  272. public Query createNamedQuery(String name) {
  273. return em.createNamedQuery(name, entityClass);
  274. }
  275.  
  276. public Query query(String qlString) {
  277. return em.createQuery(qlString, entityClass);
  278. }
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement