1 /**
2 * Copyright 2005-2015 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;
17
18 import org.kuali.rice.core.api.criteria.QueryByCriteria;
19 import org.kuali.rice.core.api.criteria.QueryResults;
20 import org.kuali.rice.krad.data.metadata.MetadataRepository;
21 import org.springframework.dao.DataAccessException;
22 import org.springframework.dao.IncorrectResultSizeDataAccessException;
23
24 /**
25 * The primary API for interacting with the data layer.
26 *
27 * <p>Contains basic data access and query operations for supported data objects. Also provides access to the
28 * {@link MetadataRepository} which contains information about the structure and relationships between data objects.</p>
29 *
30 * <p>This service supports the ability to create a {@link DataObjectWrapper} for a given data object. This
31 * wrapper allows for accessing and manipulating properties within the data object as well as performing various
32 * metadata-aware operations on the data object.</p>
33 *
34 * <p>This service is meant to act as a facade to specific persistence and query-capable solutions and data stores.
35 * Implementations of this service may provide transactional capabilities where it makes sense to do so (and depending
36 * on the transactional support of the backend persistence technology). The documentation for the specific
37 * implementation of DataObjectService that is being used should be consulted for specifics on transaction
38 * semantics.</p>
39 *
40 * @author Kuali Rice Team (rice.collab@kuali.org)
41 */
42 public interface DataObjectService {
43
44 /**
45 * Invoked to retrieve a data object instance by a single primary key field or id object. In the
46 * case of a compound primary key consisting of multiple attributes on the data object, a
47 * {@link CompoundKey} can be passed in order to encapsulate these into a single argument.
48 *
49 * @param type the type of the data object to find
50 * @param id the id representing the primary key of the data object to find
51 * @param <T> the data object class type
52 *
53 * @return the entity with the given primary key or null if none found
54 *
55 * @throws IllegalArgumentException if {@code type} does not denote a data object type or {@code id} is not a valid
56 * type for the data object's primary key or is null
57 * @throws DataAccessException if data access fails
58 *
59 * @see CompoundKey
60 */
61 <T> T find(Class<T> type, Object id);
62
63 /**
64 * Executes a query for the given data object. If the given QueryByCriteria is empty or null, then
65 * all data objects for the given type will be returned. Depending on the given criteria and the
66 * implementation for the query execution, not all matching results may be returned. The QueryResults
67 * will contain information on whether or not there are additional results which can be used for paging
68 * and similar functionality.
69 *
70 * @param type the type of the data objects to query
71 * @param queryByCriteria query object, can contain sorting and page request configuration
72 * @param <T> the data object class type
73 *
74 * @return the results of the query, will never return null but may return empty results
75 *
76 * @throws IllegalArgumentException if {@code type} does not denote a data object type, also if the
77 * {@code queryByCriteria} is null or empty.
78 * @throws DataAccessException if data access fails
79 */
80 <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria);
81
82 /**
83 * Executes a query for the given data object returning all data objects for the given type.
84 *
85 * @param type tye type of data objects to query
86 * @param <T> the data object class type
87 *
88 * @return the results of the query, will never return null but may return empty results.
89 *
90 * @throws IllegalArgumentException if {@code type} is null.
91 * @throws DataAccessException if data access fails.
92 */
93 <T> QueryResults<T> findAll(Class<T> type);
94
95 /**
96 * Executes a query for the data object matching the given queryByCriteria and expecting a single unique result to
97 * be returned. If no results match the given criteria, then null will be returned. If the given criteria matches
98 * more than one result, then an {@link IncorrectResultSizeDataAccessException} will be
99 * thrown.
100 *
101 * @param type the type of the data object to query
102 * @param queryByCriteria query object defining the criteria for the query
103 * @param <T> the data object class type
104 *
105 * @return the single result of the query, or null if no objects were matched
106 *
107 * @throws IllegalArgumentException if {@code type} does not denote a data object type
108 * @throws IncorrectResultSizeDataAccessException if more than one object matched the given criteria
109 */
110 <T> T findUnique(Class<T> type, QueryByCriteria queryByCriteria);
111
112 /**
113 * Deletes a given data object.
114 *
115 * @param dataObject the data object to delete
116 *
117 * @throws IllegalArgumentException if {@code dataObject} is not a valid data object
118 * @throws DataAccessException if data access fails
119 */
120 void delete(Object dataObject);
121
122 /**
123 * Deletes records for the given type and matching the given criteria. If the given type is null then an
124 * IllegalArgumentException will be thrown. If the given criteria is null or empty an IllegalArgumentException
125 * is also thrown to help prevent table truncations.
126 *
127 * @param type the type of data objects to delete
128 * @param queryByCriteria query object
129 *
130 * @throws IllegalArgumentException if {@code type} is null or if the {@code QueryByCriteria} is null or empty
131 * @throws DataAccessException if data access fails
132 */
133 <T> void deleteMatching(Class<T> type, QueryByCriteria queryByCriteria);
134
135 /**
136 * Removes all records for the given data object type
137 *
138 * @param type the type of data objects
139 * @param <T> the data object class type.
140 *
141 * @throws IllegalArgumentException if {@code type} is null
142 * @throws DataAccessException if data access fails
143 */
144 <T> void deleteAll(Class<T> type);
145
146 /**
147 * Saves the given data object, determining whether or not this is a new data object which is being created, or an
148 * existing one which should be updated.
149 *
150 * <p>Optional persistence options can be passed to indicate whether or not linking should be performed prior to
151 * persistence. By default, linking is performed.</p>
152 *
153 * @param dataObject the data object to save
154 * @param options the options to use when saving the data object
155 * @param <T> the data object class type
156 *
157 * @return the saved data object, calling code should always use the reference the object returned from this method
158 * for future operations after calling the save since it could have been updated
159 *
160 * @throws IllegalArgumentException if {@code dataObject} is not a valid data object
161 * @throws DataAccessException if data access fails
162 */
163 <T> T save(T dataObject, PersistenceOption... options);
164
165 /**
166 * Flushes any outstanding work to the backend data store.
167 *
168 * <p>Depending on the backend persistence implementation for the given type, this method may or may not do
169 * anything.</p>
170 *
171 * @param type the type of the data object for which to perform the flush. This is primarily used to identify the
172 * context in which to perform the flush.
173 */
174 void flush(Class<?> type);
175
176
177 /**
178 * Returns the MetadataRepository which provides access to all data object metadata known to the system.
179 *
180 * @return the MetadataRepository
181 */
182 MetadataRepository getMetadataRepository();
183
184 /**
185 * Wraps the given data object in an accessor which provides numerous utility and helper methods related to
186 * accessing data and attributes on the data object.
187 *
188 * @param dataObject the data object to wrap, must be non-null
189 * @param <T> the type of the data object
190 *
191 * @return an accessor which wraps the given data object and it's associated metadata and provides utility and
192 * methods useful when accessing data and attributes on the data object
193 *
194 * @throws IllegalArgumentException if the given data object is null or an invalid data object type
195 */
196 <T> DataObjectWrapper<T> wrap(T dataObject);
197
198 /**
199 * Returns a copy of the given data object instance.
200 *
201 * <p>The method of copying is provider dependent, and will handle instances (including nested) using whatever
202 * measures might be required to deal with the quirks of said provider (e.g. fetching lazy loaded relations).
203 * </p>
204 *
205 * @param dataObject the data object to copy
206 * @param <T> the type of the data object
207 *
208 * @return a copy of the given data object
209 */
210 <T> T copyInstance(T dataObject, CopyOption... options);
211
212 /**
213 * Returns whether the DataObjectService supports the given type, where
214 * "supports" means that there is at least one PersistenceProvider that handles the given type.
215 *
216 * @param type the data object type
217 *
218 * @return whether the DataObjectService supports the given type
219 */
220 <T> boolean supports(Class<T> type);
221
222 }