PageRenderTime 29ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/components/server-core/src/main/java/org/marvelution/jji/data/access/AbstractActiveObjectsDAO.java

https://bitbucket.org/marvelution/jira-jenkins-integration
Java | 232 lines | 132 code | 26 blank | 74 comment | 7 complexity | c79fa1ad82ab03538fbd1991e75dec30 MD5 | raw file
  1. /*
  2. * Copyright (c) 2012-present Marvelution Holding B.V.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.marvelution.jji.data.access;
  17. import java.util.*;
  18. import java.util.function.*;
  19. import java.util.stream.*;
  20. import org.marvelution.jji.data.access.model.Entity;
  21. import com.atlassian.activeobjects.external.*;
  22. import com.atlassian.activeobjects.spi.*;
  23. import net.java.ao.*;
  24. import org.slf4j.*;
  25. import static org.marvelution.jji.model.HasId.*;
  26. import static java.util.Arrays.*;
  27. import static java.util.Optional.*;
  28. /**
  29. * Base implementation for DAO based on {@link ActiveObjects}
  30. *
  31. * @author Mark Rekveld
  32. * @since 2.0.0
  33. */
  34. public abstract class AbstractActiveObjectsDAO<E extends Entity>
  35. {
  36. protected final Logger logger = LoggerFactory.getLogger(getClass());
  37. protected final ActiveObjects activeObjects;
  38. private final Class<E> entityClass;
  39. protected AbstractActiveObjectsDAO(
  40. ActiveObjects activeObjects,
  41. Class<E> entityClass)
  42. {
  43. this.activeObjects = activeObjects;
  44. this.entityClass = entityClass;
  45. }
  46. /**
  47. * @since 4.0.0
  48. */
  49. protected String addQuotesIfNeeded(String string)
  50. {
  51. UnaryOperator<String> quotivy = UnaryOperator.identity();
  52. // Postgres really wants quotes around the column name, but AO doesn't do this correctly when using UPPER() so do is 'manually'.
  53. if (activeObjects.moduleMetaData().getDatabaseType() == DatabaseType.POSTGRESQL)
  54. {
  55. quotivy = s -> "\"" + s + "\"";
  56. }
  57. return quotivy.apply(string);
  58. }
  59. /**
  60. * Returns an {@link Optional} reference to the {@link Entity} with the specified {@code id}
  61. */
  62. protected Optional<E> getOne(String id)
  63. {
  64. return getOne(entityClass, id);
  65. }
  66. /**
  67. * Returns an {@link Optional} reference to the {@link Entity} of the specified {@link Class entityType} with the specified {@code id}
  68. *
  69. * @since 4.1.0
  70. */
  71. protected <OE extends Entity> Optional<OE> getOne(
  72. Class<OE> entityClass,
  73. String id)
  74. {
  75. return ofNullable(activeObjects.get(entityClass, id));
  76. }
  77. /**
  78. * Returns an {@link Optional} reference to the {@link Entity} that is the first result of the specified {@link Query}
  79. */
  80. protected Optional<E> findOne(Query query)
  81. {
  82. return find(query).findFirst();
  83. }
  84. /**
  85. * Returns a {@link Stream} to {@link Entity Entities} that match the specified {@link Query}
  86. */
  87. protected Stream<E> find(Query query)
  88. {
  89. return find(entityClass, query);
  90. }
  91. /**
  92. * Returns a {@link Stream} to {@link Entity Entities} of the specified {@link Class entityType} that match the specified {@link Query}
  93. *
  94. * @since 4.1.0
  95. */
  96. protected <EO extends RawEntity<String>> Stream<EO> find(
  97. Class<EO> entityType,
  98. Query query)
  99. {
  100. return stream(activeObjects.find(entityType, query));
  101. }
  102. /**
  103. * Returns the number of entities related to the specified {@link Query}.
  104. *
  105. * @since 3.9.0
  106. */
  107. protected int count(Query query)
  108. {
  109. return activeObjects.count(entityClass, query);
  110. }
  111. /**
  112. * Inserts a new {@link Entity} using the specified {@link Map} of fields and return it.
  113. */
  114. protected E insert(NullCharacterRemovingHashMap mapping)
  115. {
  116. return insert(entityClass, mapping);
  117. }
  118. /**
  119. * Inserts a new {@link Entity} of the specified {@code entityType} using the specified {@link Map} of fields and return it.
  120. */
  121. protected <OE extends Entity> OE insert(
  122. Class<OE> entityType,
  123. NullCharacterRemovingHashMap mapping)
  124. {
  125. if (!mapping.containsKey(Entity.ID))
  126. {
  127. mapping.put(Entity.ID, newId());
  128. }
  129. return activeObjects.create(entityType, mapping);
  130. }
  131. /**
  132. * Update an {@link Entity} using the specified {@link Consumer updater} and return it in its new state.
  133. */
  134. protected E update(
  135. String id,
  136. Consumer<E> updater)
  137. {
  138. return update(entityClass, id, updater);
  139. }
  140. /**
  141. * Update an {@link Entity} of the specified {@code entityType} using the specified {@link Consumer updater} and return it in its new
  142. * state.
  143. */
  144. protected <OE extends Entity> OE update(
  145. Class<OE> entityType,
  146. String id,
  147. Consumer<OE> updater)
  148. {
  149. OE mapping = activeObjects.get(entityType, id);
  150. updater.accept(mapping);
  151. mapping.save();
  152. return mapping;
  153. }
  154. /**
  155. * Delete a single {@link Entity} of the specified {@code entityType}, with the specified {@code id}
  156. */
  157. protected <OE extends Entity> void delete(
  158. Class<OE> entityType,
  159. String id)
  160. {
  161. OE mapping = activeObjects.get(entityType, id);
  162. if (mapping != null)
  163. {
  164. deleteEntity(mapping);
  165. }
  166. }
  167. /**
  168. * Delete all the {@link Entity} of the specified {@code entityType}, that match the specified {@link Query};
  169. */
  170. protected <OE extends Entity> void delete(
  171. Class<OE> entityType,
  172. Query query)
  173. {
  174. deleteEntity(activeObjects.find(entityType, query));
  175. }
  176. protected void deleteOne(String id)
  177. {
  178. getOne(id).ifPresent(this::delete);
  179. }
  180. /**
  181. * Delete all {@link Entity Entities}, and returns them, that match the specified {@code query}
  182. */
  183. protected void delete(Query query)
  184. {
  185. stream(activeObjects.find(entityClass, query)).forEach(this::delete);
  186. }
  187. protected abstract void delete(E entity);
  188. /**
  189. * Delete {@link Entity Entities} using a where criteria statement
  190. */
  191. protected void deleteWithSQL(
  192. String criteria,
  193. Object... parameters)
  194. {
  195. activeObjects.deleteWithSQL(entityClass, criteria, parameters);
  196. }
  197. protected void deleteEntity(Entity... entity)
  198. {
  199. if (entity != null)
  200. {
  201. stream(entity).filter(Objects::nonNull)
  202. .peek(object -> logger.debug("Deleting entity {} with ID {}", object.getEntityType().getSimpleName(), object.getID()))
  203. .forEach(activeObjects::delete);
  204. }
  205. }
  206. }