View Javadoc
1   package com.atlassian.activeobjects.internal;
2   
3   import com.atlassian.activeobjects.external.ActiveObjects;
4   import com.atlassian.activeobjects.external.ActiveObjectsModuleMetaData;
5   import com.atlassian.activeobjects.spi.DatabaseType;
6   import com.atlassian.sal.api.transaction.TransactionCallback;
7   import net.java.ao.DBParam;
8   import net.java.ao.DatabaseProvider;
9   import net.java.ao.DefaultPolymorphicTypeMapper;
10  import net.java.ao.EntityManager;
11  import net.java.ao.EntityStreamCallback;
12  import net.java.ao.Query;
13  import net.java.ao.RawEntity;
14  import net.java.ao.SchemaConfiguration;
15  import net.java.ao.schema.NameConverters;
16  import net.java.ao.schema.helper.DatabaseMetaDataReader;
17  import net.java.ao.schema.helper.DatabaseMetaDataReaderImpl;
18  
19  import java.sql.Connection;
20  import java.sql.SQLException;
21  import java.util.Map;
22  import java.util.concurrent.ExecutionException;
23  import java.util.concurrent.TimeUnit;
24  import java.util.concurrent.TimeoutException;
25  
26  import static com.google.common.base.Preconditions.checkNotNull;
27  
28  /**
29   * <p>Implementation of {@link com.atlassian.activeobjects.external.ActiveObjects} that mainly delegates to the
30   * {@link net.java.ao.EntityManager}.</p>
31   * <p>This is {@code abstract} and concrete implementations should have to provide a correctly configured {@link net.java.ao.EntityManager}</p>
32   *
33   * @see net.java.ao.EntityManager
34   */
35  public class EntityManagedActiveObjects implements ActiveObjects {
36      private final EntityManager entityManager;
37      private final TransactionManager transactionManager;
38      private final DatabaseType dbType;
39  
40      protected EntityManagedActiveObjects(EntityManager entityManager, TransactionManager transactionManager, DatabaseType dbType) {
41          this.entityManager = checkNotNull(entityManager);
42          this.transactionManager = checkNotNull(transactionManager);
43          this.dbType = checkNotNull(dbType);
44      }
45  
46      ///CLOVER:OFF
47  
48      public final void migrate(Class<? extends RawEntity<?>>... entities) {
49          try {
50              entityManager.setPolymorphicTypeMapper(new DefaultPolymorphicTypeMapper(entities));
51              entityManager.migrate(entities);
52          } catch (SQLException e) {
53              throw new ActiveObjectsSqlException(entityManager, e);
54          }
55      }
56  
57      public void migrateDestructively(Class<? extends RawEntity<?>>... entities) {
58          try {
59              entityManager.setPolymorphicTypeMapper(new DefaultPolymorphicTypeMapper(entities));
60              entityManager.migrateDestructively(entities);
61          } catch (SQLException e) {
62              throw new ActiveObjectsSqlException(entityManager, e);
63          }
64      }
65  
66      public final void flushAll() {
67          entityManager.flushAll();
68      }
69  
70      public final void flush(RawEntity<?>... entities) {
71          entityManager.flush(entities);
72      }
73  
74      public final <T extends RawEntity<K>, K> T[] get(Class<T> type, K... keys) {
75          try {
76              return entityManager.get(type, keys);
77          } catch (SQLException e) {
78              throw new ActiveObjectsSqlException(entityManager, e);
79          }
80      }
81  
82      public final <T extends RawEntity<K>, K> T get(Class<T> type, K key) {
83          try {
84              return entityManager.get(type, key);
85          } catch (SQLException e) {
86              throw new ActiveObjectsSqlException(entityManager, e);
87          }
88      }
89  
90      public final <T extends RawEntity<K>, K> T create(Class<T> type, DBParam... params) {
91          try {
92              return entityManager.create(type, params);
93          } catch (SQLException e) {
94              throw new ActiveObjectsSqlException(entityManager, e);
95          }
96      }
97  
98      public final <T extends RawEntity<K>, K> T create(Class<T> type, Map<String, Object> params) {
99          try {
100             return entityManager.create(type, params);
101         } catch (SQLException e) {
102             throw new ActiveObjectsSqlException(entityManager, e);
103         }
104     }
105 
106     public final void delete(RawEntity<?>... entities) {
107         try {
108             entityManager.delete(entities);
109         } catch (SQLException e) {
110             throw new ActiveObjectsSqlException(entityManager, e);
111         }
112     }
113 
114     public <K> int deleteWithSQL(Class<? extends RawEntity<K>> type, String criteria, Object... parameters) {
115         try {
116             return entityManager.deleteWithSQL(type, criteria, parameters);
117         } catch (SQLException e) {
118             throw new ActiveObjectsSqlException(entityManager, e);
119         }
120     }
121 
122     public final <T extends RawEntity<K>, K> T[] find(Class<T> type) {
123         try {
124             return entityManager.find(type);
125         } catch (SQLException e) {
126             throw new ActiveObjectsSqlException(entityManager, e);
127         }
128     }
129 
130     public final <T extends RawEntity<K>, K> T[] find(Class<T> type, String criteria, Object... parameters) {
131         try {
132             return entityManager.find(type, criteria, parameters);
133         } catch (SQLException e) {
134             throw new ActiveObjectsSqlException(entityManager, e);
135         }
136     }
137 
138     public final <T extends RawEntity<K>, K> T[] find(Class<T> type, Query query) {
139         try {
140             return entityManager.find(type, query);
141         } catch (SQLException e) {
142             throw new ActiveObjectsSqlException(entityManager, e);
143         }
144     }
145 
146     public final <T extends RawEntity<K>, K> T[] find(Class<T> type, String field, Query query) {
147         try {
148             return entityManager.find(type, field, query);
149         } catch (SQLException e) {
150             throw new ActiveObjectsSqlException(entityManager, e);
151         }
152     }
153 
154     public final <T extends RawEntity<K>, K> T[] findWithSQL(Class<T> type, String keyField, String sql, Object... parameters) {
155         try {
156             return entityManager.findWithSQL(type, keyField, sql, parameters);
157         } catch (SQLException e) {
158             throw new ActiveObjectsSqlException(entityManager, e);
159         }
160     }
161 
162     public final <T extends RawEntity<K>, K> void stream(Class<T> type, Query query, EntityStreamCallback<T, K> streamCallback) {
163         try {
164             entityManager.stream(type, query, streamCallback);
165         } catch (SQLException e) {
166             throw new ActiveObjectsSqlException(entityManager, e);
167         }
168     }
169 
170     public final <T extends RawEntity<K>, K> void stream(Class<T> type, EntityStreamCallback<T, K> streamCallback) {
171         try {
172             entityManager.stream(type, streamCallback);
173         } catch (SQLException e) {
174             throw new ActiveObjectsSqlException(entityManager, e);
175         }
176     }
177 
178     public final <K> int count(Class<? extends RawEntity<K>> type) {
179         try {
180             return entityManager.count(type);
181         } catch (SQLException e) {
182             throw new ActiveObjectsSqlException(entityManager, e);
183         }
184     }
185 
186     public final <K> int count(Class<? extends RawEntity<K>> type, String criteria, Object... parameters) {
187         try {
188             return entityManager.count(type, criteria, parameters);
189         } catch (SQLException e) {
190             throw new ActiveObjectsSqlException(entityManager, e);
191         }
192     }
193 
194     public final <K> int count(Class<? extends RawEntity<K>> type, Query query) {
195         try {
196             return entityManager.count(type, query);
197         } catch (SQLException e) {
198             throw new ActiveObjectsSqlException(entityManager, e);
199         }
200     }
201 
202     ///CLOVER:ON
203     public final <T> T executeInTransaction(final TransactionCallback<T> callback) {
204         return transactionManager.doInTransaction(callback);
205     }
206 
207     @Override
208     public ActiveObjectsModuleMetaData moduleMetaData() {
209         class EntityAOModuleMetaData extends AbstractActiveObjectsMetaData {
210             EntityAOModuleMetaData() {
211                 super(dbType);
212             }
213 
214             @Override
215             public boolean isInitialized() {
216                 return false;
217             }
218 
219             @Override
220             public boolean isDataSourcePresent() {
221                 return false;
222             }
223 
224             @Override
225             public boolean isTablePresent(Class<? extends RawEntity<?>> type) {
226                 DatabaseProvider databaseProvider = entityManager.getProvider();
227                 NameConverters nameConverters = entityManager.getNameConverters();
228                 SchemaConfiguration schemaConfiguration = entityManager.getSchemaConfiguration();
229 
230                 DatabaseMetaDataReader databaseMetaDataReader = new DatabaseMetaDataReaderImpl(
231                         databaseProvider,
232                         nameConverters,
233                         schemaConfiguration
234                 );
235 
236                 try (Connection connection = databaseProvider.getConnection()) {
237                     return databaseMetaDataReader.isTablePresent(connection.getMetaData(), type);
238                 } catch (SQLException e) {
239                     throw new RuntimeException(e);
240                 }
241             }
242 
243             @Override
244             public void awaitInitialization() throws ExecutionException, InterruptedException {
245                 throw new UnsupportedOperationException(
246                         "Cannot call awaitModelInitialization directly on EntityManagedActiveObjects.\n"
247                                 + "awaitModelInitialization should not be called from within an upgrade task");
248             }
249 
250             @Override
251             public void awaitInitialization(final long timeout, final TimeUnit unit)
252                     throws InterruptedException, ExecutionException, TimeoutException {
253                 throw new UnsupportedOperationException(
254                         "Cannot call awaitModelInitialization directly on EntityManagedActiveObjects.\n"
255                                 + "awaitModelInitialization should not be called from within an upgrade task");
256             }
257         }
258 
259         return new EntityAOModuleMetaData();
260     }
261 }