View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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.kuali.rice.krad.data.provider.impl;
17  
18  import org.kuali.rice.core.api.criteria.LookupCustomizer;
19  import org.kuali.rice.core.api.criteria.QueryByCriteria;
20  import org.kuali.rice.core.api.criteria.QueryResults;
21  import org.kuali.rice.krad.data.CompoundKey;
22  import org.kuali.rice.krad.data.DataObjectService;
23  import org.kuali.rice.krad.data.DataObjectWrapper;
24  import org.kuali.rice.krad.data.PersistenceOption;
25  import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
26  import org.kuali.rice.krad.data.metadata.MetadataRepository;
27  import org.kuali.rice.krad.data.provider.PersistenceProvider;
28  import org.kuali.rice.krad.data.provider.ProviderRegistry;
29  import org.springframework.beans.factory.annotation.Required;
30  
31  /**
32   * DataObjectService implementation backed by the {@link ProviderRegistry}.
33   *
34   * @author Kuali Rice Team (rice.collab@kuali.org)
35   */
36  public class ProviderBasedDataObjectService implements DataObjectService {
37  
38  	protected ProviderRegistry providerRegistry;
39  	protected MetadataRepository metadataRepository;
40  
41      @Override
42      public <T> T find(Class<T> type, Object id) {
43          return persistenceProviderForType(type).find(type, reduceCompoundKey(id));
44      }
45  
46      /**
47       * If the given id object is an instance of CompoundKey but there is only one entry in the key map, then just grab
48       * that single value and treat it as a single id.
49       *
50       * @param id the potentially CompoundKey to reduce
51       * @return the single value from the CompoundKey map if the given id is a CompoundKey with a single entry, otherwise
52       *         the original id that was passed in is returned
53       */
54      protected Object reduceCompoundKey(Object id) {
55          if (id instanceof CompoundKey) {
56              CompoundKey compoundKey = (CompoundKey)id;
57              if (compoundKey.getKeys().size() == 1) {
58                  id = compoundKey.getKeys().values().iterator().next();
59              }
60          }
61          return id;
62      }
63  
64      @Override
65      public <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria) {
66          return persistenceProviderForType(type).findMatching(type, queryByCriteria);
67      }
68  
69      @Override
70      public <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria, LookupCustomizer<T> lookupCustomizer) {
71          return persistenceProviderForType(type).findMatching(type, queryByCriteria, lookupCustomizer);
72      }
73  
74      @Override
75      public void delete(Object dataObject) {
76          persistenceProviderForObject(dataObject).delete(dataObject);
77      }
78  
79      @Override
80      public <T> void deleteMatching(Class<T> type, QueryByCriteria queryByCriteria) {
81          QueryResults<T> results = findMatching(type, queryByCriteria);
82          for (T result: results.getResults()) {
83              delete(result);
84          }
85      }
86  
87      @Override
88  	public <T> T save(T dataObject, PersistenceOption... options) {
89          return persistenceProviderForObject(dataObject).save(dataObject, options);
90      }
91  
92      @Override
93      public MetadataRepository getMetadataRepository() {
94          return metadataRepository;
95      }
96  
97      @Override
98      public <T> DataObjectWrapper<T> wrap(T dataObject) {
99          if (dataObject == null) {
100             throw new IllegalArgumentException("data object was null");
101         }
102 		DataObjectMetadata metadata = getMetadataRepository().getMetadata(dataObject.getClass());
103         return new DataObjectWrapperImpl<T>(dataObject, metadata, this);
104     }
105 
106     @Override
107     public <T> boolean supports(Class<T> type) {
108         return providerRegistry.getPersistenceProvider(type) != null;
109     }
110 
111     /**
112      * @return PersistenceProvider returned by the ProviderRegistry for the given type
113      * @throws RuntimeException if not PersistenceProvider handles given type
114      */
115     protected PersistenceProvider persistenceProviderForType(Class<?> type) {
116         PersistenceProvider provider = providerRegistry.getPersistenceProvider(type);
117         if (provider == null) {
118             throw new RuntimeException("No PersistenceProvider handles type: " + type);
119         }
120         return provider;
121     }
122 
123     /**
124 	 * @return PersistenceProvider returned by the ProviderRegistry for the given object
125 	 * @throws RuntimeException
126 	 *             if not PersistenceProvider handles given type
127 	 * @throws IllegalArgumentException
128 	 *             if null object passed in
129 	 */
130     protected PersistenceProvider persistenceProviderForObject(Object object) {
131 		if (object == null) {
132 			throw new IllegalArgumentException("data object was null");
133 		}
134 		return persistenceProviderForType(object.getClass());
135     }
136 
137     @Override
138     public void flush(Class<?> type){
139         PersistenceProvider persistenceProvider = persistenceProviderForType(type);
140         if (persistenceProvider == null) {
141             throw new RuntimeException("No PersistenceProvider handles type: " + type);
142         }
143         persistenceProvider.flush(type);
144     }
145 
146     @Required
147     public void setProviderRegistry(ProviderRegistry providerRegistry) {
148         this.providerRegistry = providerRegistry;
149     }
150 
151     @Required
152     public void setMetadataRepository(MetadataRepository metadataRepository) {
153         this.metadataRepository = metadataRepository;
154     }
155 
156     private static final class DataObjectWrapperImpl<T> extends DataObjectWrapperBase<T> {
157         private DataObjectWrapperImpl(T dataObject, DataObjectMetadata metadata, DataObjectService dataObjectService) {
158             super(dataObject, metadata, dataObjectService);
159         }
160     }
161 
162 }