001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.data.provider;
017
018import org.kuali.rice.core.api.criteria.QueryByCriteria;
019import org.kuali.rice.core.api.criteria.QueryResults;
020import org.kuali.rice.krad.data.CopyOption;
021import org.kuali.rice.krad.data.PersistenceOption;
022
023/**
024 * Defines persistence SPI for data providers.
025 *
026 * <p>
027 * PersistenceProviders are responsible for creating, updating, querying, copying and deleting data objects.
028 * DataObjectTypes the PersistenceProvider supports must be queried through {@link #handles(Class)} before interaction
029 * with the PersistenceProvider.
030 * </p>
031 *
032 * @author Kuali Rice Team (rice.collab@kuali.org)
033 */
034public interface PersistenceProvider extends Provider {
035
036    /**
037     * Saves the given data object, determining whether or not this is a new data object which is being created, or an
038     * existing one which should be updated.
039     *
040     * <p>
041     * Optional persistence options can be passed to indicate whether or not linking should be performed prior to
042     * persistence and whether or not validation should be performed. By default, linking is performed as well as
043     * validation.
044     * </p>
045     *
046     * @param dataObject the data object to save
047     * @param options the options to use when saving the data object
048     * @param <T> the data object class type
049     *
050     * @return the saved data object, calling code should always use the reference the object returned from this method
051     * for future operations after calling the save since it could have been updated
052     *
053     * @throws IllegalArgumentException if {@code dataObject} is not a valid data object
054     * @throws org.springframework.dao.DataAccessException if data access fails
055     */
056    <T> T save(T dataObject, PersistenceOption... options);
057
058    /**
059     * Invoked to retrieve a data object instance by a single primary key field or id object.
060     *
061     * <p>In the case of a compound primary key consisting of multiple attributes on the data object, a CompoundKey can
062     * be passed in order to encapsulate these into a single argument.
063     * </p>
064     *
065     * @param type the type of the data object to find
066     * @param id the id representing the primary key of the data object to find
067     * @param <T> the data object class type
068     *
069     * @return the entity with the given primary key or null if none found
070     *
071     * @throws IllegalArgumentException if {@code type} does not denote a data object type or {@code id} is not a valid
072     * type for the data object's primary key or is null
073     * @throws org.springframework.dao.DataAccessException if data access fails
074     */
075    <T> T find(Class<T> type, Object id);
076
077    /**
078     * Executes a query for the given data object.
079     *
080     * <p>
081     * If the given QueryByCriteria is empty or null, then all data objects for the given type will be returned.
082     * Depending on the given criteria and the implementation for the query execution, not all matching results may be
083     * returned. The QueryResults will contain information on whether or not there are additional results which can be
084     * used for paging and similar functionality.
085     * </p>
086     *
087     * @param type the type of the data objects to query
088     * @param queryByCriteria query object, can contain sorting and page request configuration
089     * @param <T> the data object class type
090     *
091     * @return the results of the query, will never return null but may return empty results
092     *
093     * @throws IllegalArgumentException if {@code type} does not denote a data object type or if {@code queryByCriteria}
094     *  is null
095     * @throws org.springframework.dao.DataAccessException if data access fails
096     */
097    <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria);
098
099    /**
100     * Retrieves all data objects for the given type.
101     *
102     * @param type the type of data objects to find
103     * @param <T> the data object class type
104     *
105     * @return the results of the query, will never return null but may return empty results
106     *
107     * @throws java.lang.IllegalArgumentException if type is null.
108     */
109    <T> QueryResults<T> findAll(Class<T> type);
110
111    /**
112     * Deletes a given data object.
113     *
114     * @param dataObject the data object to delete
115     *
116     * @throws IllegalArgumentException if {@code dataObject} is not a valid data object
117     * @throws org.springframework.dao.DataAccessException if data access fails
118     */
119    void delete(Object dataObject);
120
121    /**
122     * Deletes data objects based on the given criteria
123     *
124     * <p>If the given criteria is empty or null than an {@link java.lang.IllegalArgumentException} will be thrown.
125     *   If the given type is null then an {@link java.lang.IllegalArgumentException} will be thrown.</p>
126     *
127     * @param type the type of data object
128     * @param queryByCriteria criteria to filter by
129     *
130     * @throws IllegalArgumentException if the criteria or criteria predicate is null
131     * @throws org.springframework.dao.DataAccessException if data access fails
132     */
133    <T> void deleteMatching(Class<T> type, QueryByCriteria queryByCriteria);
134
135    /**
136     * Deletes all data objects based on the given type.
137     *
138     * @param type the type of data objects to delete
139     * @param <T> the data object class type
140     *
141     * @throws IllegalArgumentException if the class type is null
142     * @throws org.springframework.dao.DataAccessException if data access fails
143     */
144    <T> void deleteAll(Class<T> type);
145
146    /**
147     * Returns a copy of the given data object instance.
148     *
149     * <p>
150     * The method of copying is provider dependent, and will handle instances (including nested) using whatever measures
151     * might be required to deal with the quirks of said provider (e.g. fetching lazy loaded relations).
152     * </p>
153     *
154     * @param dataObject the data object to copy
155     * @param <T> the type of the data object
156     *
157     * @return a copy of the given data object
158     */
159        <T> T copyInstance(T dataObject, CopyOption... options);
160
161    /**
162     * Indicates whether or not this provider handles persistence for the given data object type.
163     *
164     * <p>
165     * Responsibility on with the caller to call prior to invocation of any other PersistenceProvider methods to ensure
166     * the data objects of the right type are passed.
167     * </p>
168     *
169     * @param type the data object type to check
170     *
171     * @return true if this provider can handle the given type, false otherwise
172     */
173    boolean handles(Class<?> type);
174
175    /**
176         * Flush any outstanding changes within the current context for the provider pertaining to the given data object
177         * Class type.
178         *
179         * <p>
180         * If an implementation of this interface does not support or require the concept of "flushing", this method can be
181         * ignored. However, when used, this must purge *all* cache items for the given types from all caches managed by
182         * this provider.
183         * </p>
184         *
185         * @param type
186         *            the type of the data object for which to perform the flush. This should be used to identify the
187         *            context in which to perform the flush.
188         */
189    void flush(Class<?> type);
190
191}