1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.data.provider.impl;
17
18 import com.google.common.collect.Sets;
19 import org.kuali.rice.core.api.criteria.LookupCustomizer;
20 import org.kuali.rice.core.api.criteria.QueryByCriteria;
21 import org.kuali.rice.core.api.criteria.QueryResults;
22 import org.kuali.rice.krad.data.CompoundKey;
23 import org.kuali.rice.krad.data.DataObjectService;
24 import org.kuali.rice.krad.data.DataObjectWrapper;
25 import org.kuali.rice.krad.data.PersistenceOption;
26 import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
27 import org.kuali.rice.krad.data.metadata.MetadataRepository;
28 import org.kuali.rice.krad.data.provider.PersistenceProvider;
29 import org.kuali.rice.krad.data.provider.ProviderRegistry;
30 import org.kuali.rice.krad.data.provider.util.ReferenceLinker;
31 import org.springframework.beans.factory.annotation.Required;
32 import org.springframework.dao.IncorrectResultSizeDataAccessException;
33
34 import java.util.Set;
35
36
37
38
39
40
41 public class ProviderBasedDataObjectService implements DataObjectService {
42 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
43 .getLogger(ProviderBasedDataObjectService.class);
44
45 protected ProviderRegistry providerRegistry;
46 protected MetadataRepository metadataRepository;
47 protected ReferenceLinker referenceLinker;
48
49 @Override
50 public <T> T find(Class<T> type, Object id) {
51 return persistenceProviderForType(type).find(type, reduceCompoundKey(id));
52 }
53
54
55
56
57
58
59
60
61
62 protected Object reduceCompoundKey(Object id) {
63 if (id instanceof CompoundKey) {
64 CompoundKey compoundKey = (CompoundKey)id;
65 if (compoundKey.getKeys().size() == 1) {
66 id = compoundKey.getKeys().values().iterator().next();
67 }
68 }
69 return id;
70 }
71
72 @Override
73 public <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria) {
74 return persistenceProviderForType(type).findMatching(type, queryByCriteria);
75 }
76
77 @Override
78 public <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria, LookupCustomizer<T> lookupCustomizer) {
79 return persistenceProviderForType(type).findMatching(type, queryByCriteria, lookupCustomizer);
80 }
81
82 @Override
83 public <T> T findUnique(Class<T> type, QueryByCriteria queryByCriteria) {
84 QueryResults<T> results = findMatching(type, queryByCriteria);
85 if (results.getResults().isEmpty()) {
86 return null;
87 } else if (results.getResults().size() > 1) {
88 throw new IncorrectResultSizeDataAccessException("Attempted to find single result but found more than "
89 + "one for class " + type + " and criteria " + queryByCriteria, 1, results.getResults().size());
90 } else {
91 return results.getResults().get(0);
92 }
93 }
94
95 @Override
96 public void delete(Object dataObject) {
97 persistenceProviderForObject(dataObject).delete(dataObject);
98 }
99
100 @Override
101 public <T> void deleteMatching(Class<T> type, QueryByCriteria queryByCriteria) {
102 QueryResults<T> results = findMatching(type, queryByCriteria);
103 for (T result: results.getResults()) {
104 delete(result);
105 }
106 }
107
108 @Override
109 public <T> T save(T dataObject, PersistenceOption... options) {
110 Set<PersistenceOption> optionSet = Sets.newHashSet(options);
111 T saved = persistenceProviderForObject(dataObject).save(dataObject, options);
112 if (optionSet.contains(PersistenceOption.LINK_KEYS)) {
113 DataObjectWrapper<T> wrapper = wrap(saved);
114 wrapper.linkForeignKeys(true);
115 }
116 return saved;
117 }
118
119 @Override
120 public MetadataRepository getMetadataRepository() {
121 return metadataRepository;
122 }
123
124 @Override
125 public <T> T copyInstance(T dataObject) {
126 return persistenceProviderForObject(dataObject).copyInstance(dataObject);
127 }
128
129 @Override
130 public <T> DataObjectWrapper<T> wrap(T dataObject) {
131 if (dataObject == null) {
132 throw new IllegalArgumentException("data object was null");
133 }
134 DataObjectMetadata metadata = getMetadataRepository().getMetadata(dataObject.getClass());
135
136
137 if (metadata == null) {
138 LOG.warn("Non KRAD Data object passed - no metadata found for: " + dataObject.getClass());
139
140
141 }
142 return new DataObjectWrapperImpl<T>(dataObject, metadata, this, referenceLinker);
143 }
144
145 @Override
146 public <T> boolean supports(Class<T> type) {
147 return providerRegistry.getPersistenceProvider(type) != null;
148 }
149
150
151
152
153
154 protected PersistenceProvider persistenceProviderForType(Class<?> type) {
155 PersistenceProvider provider = providerRegistry.getPersistenceProvider(type);
156 if (provider == null) {
157 throw new RuntimeException("No PersistenceProvider handles type: " + type);
158 }
159 return provider;
160 }
161
162
163
164
165
166
167
168
169 protected PersistenceProvider persistenceProviderForObject(Object object) {
170 if (object == null) {
171 throw new IllegalArgumentException("data object was null");
172 }
173 return persistenceProviderForType(object.getClass());
174 }
175
176 @Override
177 public void flush(Class<?> type){
178 PersistenceProvider persistenceProvider = persistenceProviderForType(type);
179 if (persistenceProvider == null) {
180 throw new RuntimeException("No PersistenceProvider handles type: " + type);
181 }
182 persistenceProvider.flush(type);
183 }
184
185 @Required
186 public void setProviderRegistry(ProviderRegistry providerRegistry) {
187 this.providerRegistry = providerRegistry;
188 }
189
190 @Required
191 public void setMetadataRepository(MetadataRepository metadataRepository) {
192 this.metadataRepository = metadataRepository;
193 }
194
195 public ReferenceLinker getReferenceLinker() {
196 return referenceLinker;
197 }
198
199 @Required
200 public void setReferenceLinker(ReferenceLinker referenceLinker) {
201 this.referenceLinker = referenceLinker;
202 }
203
204 private static final class DataObjectWrapperImpl<T> extends DataObjectWrapperBase<T> {
205 private DataObjectWrapperImpl(T dataObject, DataObjectMetadata metadata, DataObjectService dataObjectService,
206 ReferenceLinker referenceLinker) {
207 super(dataObject, metadata, dataObjectService, referenceLinker);
208 }
209 }
210
211 }