Skip to content

Package: UnitOfWork

UnitOfWork

Coverage

1: /**
2: * Copyright (C) 2023 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.jopa.sessions;
16:
17: import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
18: import cz.cvut.kbss.jopa.model.LoadState;
19: import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
20: import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification;
21:
22: import java.lang.reflect.Field;
23: import java.net.URI;
24: import java.util.List;
25: import java.util.function.Consumer;
26:
27: /**
28: * Represents a persistence context.
29: * <p>
30: * All interactions with objects managed in a persistence context are tracked by its corresponding UoW and on commit,
31: * the UoW propagates them into the changes into the storage.
32: */
33: public interface UnitOfWork extends Session {
34:
35: /**
36: * Clears this Unit of Work.
37: */
38: void clear();
39:
40: /**
41: * Commit changes to the ontology.
42: */
43: void commit();
44:
45: /**
46: * Rolls back changes done since last commit.
47: *
48: * @see #commit()
49: */
50: void rollback();
51:
52: /**
53: * Returns true if the specified entity is managed in the current persistence context. This method is used by the
54: * EntityManager's contains method.
55: *
56: * @param entity Object
57: * @return {@literal true} if entity is managed, {@literal false} otherwise
58: */
59: boolean contains(Object entity);
60:
61: /**
62: * Is this Unit of Work active?
63: *
64: * @return boolean
65: */
66: boolean isActive();
67:
68: /**
69: * Returns true if this {@code UnitOfWork} represents persistence context of a currently running transaction.
70: *
71: * @return True if in an active transaction
72: */
73: boolean isInTransaction();
74:
75: /**
76: * Return true if the given entity is managed. This means it is either in the shared session cache or it is a new
77: * object ready for persist.
78: *
79: * @param entity Object
80: * @return boolean
81: */
82: boolean isObjectManaged(Object entity);
83:
84: /**
85: * Checks whether context specified by {@code context} is consistent.
86: * <p>
87: * Can be {@code null}, indicating that consistency of the whole repository should be checked.
88: *
89: * @param context Context URI
90: * @return {@code true} if the context is consistent, {@code false} otherwise
91: * @throws OWLPersistenceException If an ontology access error occurs
92: */
93: boolean isConsistent(URI context);
94:
95: /**
96: * Loads value of the specified field for the specified entity.
97: * <p>
98: * The value is set on the entity.
99: *
100: * @param entity The entity to load field for
101: * @param field The field to load
102: * @throws NullPointerException If {@code entity} or {@code field} is {@code null}
103: * @throws OWLPersistenceException If an error occurs, this may be e. g. that the field is not present on the
104: * entity, an ontology access error occurred etc.
105: */
106: <T> void loadEntityField(T entity, Field field);
107:
108: /**
109: * Merges the state of the given entity into the current persistence context.
110: * <p>
111: * The {@code descriptor} argument specified the ontology contexts into which the detached entity and its fields
112: * belong and should be merged.
113: *
114: * @param entity entity instance
115: * @param descriptor Entity descriptor, specifies repository context
116: * @return the managed instance that the state was merged to
117: * @throws NullPointerException If {@code entity} or {@code repository} is {@code null}
118: */
119: <T> T mergeDetached(T entity, Descriptor descriptor);
120:
121: /**
122: * Retrieves object with the specified identifier.
123: * <p>
124: * The object as well as its fields are looked for in contexts specified by the descriptor. The result is then cast
125: * to the specified type.
126: *
127: * @param cls The type of the returned object
128: * @param identifier Instance identifier
129: * @param descriptor Entity descriptor
130: * @return The retrieved object or {@code null} if there is no object with the specified identifier in the specified
131: * repository
132: * @throws NullPointerException If {@code cls}, {@code identifier} or {@code repository} is {@code null}
133: * @throws OWLPersistenceException If an error occurs during object loading
134: */
135: <T> T readObject(Class<T> cls, Object identifier, Descriptor descriptor);
136:
137: /**
138: * Retrieves a reference to an object with the specified identifier.
139: * <p>
140: * A reference is permitted to have its state fetched lazily.
141: *
142: * @param cls The type of the returned object
143: * @param identifier Instance identifier
144: * @param descriptor Entity descriptor
145: * @param <T> Entity type
146: * @return The retrieved object or {@code null} if none can be found
147: * @throws OWLPersistenceException If an error occurs during object loading
148: */
149: <T> T getReference(Class<T> cls, Object identifier, Descriptor descriptor);
150:
151: /**
152: * Register an existing object in this Unit of Work.
153: * <p>
154: * This method creates a working clone of this object and puts the given object into this Unit of Work cache.
155: *
156: * @param object Object
157: * @param descriptor Entity descriptor identifying repository contexts
158: * @return Object Returns clone of the registered object
159: */
160: Object registerExistingObject(Object object, Descriptor descriptor);
161:
162: /**
163: * Registers an existing object in this Unit of Work.
164: * <p>
165: * Invokes the specified postClone procedures after the cloning takes place, passing the newly created clone as
166: * argument.
167: *
168: * @param object The object to register
169: * @param descriptor Descriptor identifying repository contexts
170: * @param postClone Handlers to be called after the original object is cloned on the clone
171: * @return Clone of the registered object
172: * @see #registerExistingObject(Object, Descriptor)
173: */
174: Object registerExistingObject(Object object, Descriptor descriptor, List<Consumer<Object>> postClone);
175:
176: /**
177: * Registers the specified new object in this Unit of Work.
178: * <p>
179: * The object will be persisted into the context specified by {@code descriptor}.
180: *
181: * @param object The object to register
182: * @param descriptor Entity descriptor
183: * @throws NullPointerException If {@code entity} or {@code context} is {@code null}
184: * @throws OWLPersistenceException If {@code context} is not a valid context URI or if an error during registration
185: * occurs
186: */
187: void registerNewObject(Object object, Descriptor descriptor);
188:
189: /**
190: * Remove the given object. Calling this method causes the entity to be removed from the shared cache and a delete
191: * query is initiated on the ontology.
192: *
193: * @param object Object
194: */
195: void removeObject(Object object);
196:
197: /**
198: * Restores the specified removed object.
199: * <p>
200: * This means it is reinstated as a managed entity and reinserted into the repository.
201: *
202: * @param entity The object to restore
203: */
204: void restoreRemovedObject(Object entity);
205:
206: /**
207: * Release the current unit of work. Calling this method disregards any changes made to clones.
208: */
209: @Override
210: void release();
211:
212: /**
213: * Refreshes state of the object from the storage, overwriting any changes made to it.
214: *
215: * @param object The object to revert
216: * @param <T> Object type
217: * @throws IllegalArgumentException If the object is not managed
218: */
219: <T> void refreshObject(T object);
220:
221: /**
222: * This method returns true, if the UnitOfWork should be released after the commit call. This is done for inferred
223: * attributes, which cause the whole session cache to be invalidated.
224: *
225: * @return True if the UnitOfWork should be released after commit.
226: */
227: boolean shouldReleaseAfterCommit();
228:
229: /**
230: * Writes any uncommitted changes into the ontology. This method may be useful when flushing entity manager or
231: * closing sessions, because we don't want to let the changes to get lost.
232: */
233: void writeUncommittedChanges();
234:
235: /**
236: * Gets repository contexts available to this session.
237: *
238: * @return Unmodifiable list of context URIs
239: */
240: List<URI> getContexts();
241:
242: /**
243: * Gets the load status of the specified attribute on the specified entity.
244: *
245: * @param entity Entity instance
246: * @param attributeName Attribute whose load status is to be determined
247: * @return Attribute load status
248: * @see cz.cvut.kbss.jopa.model.ProviderUtil#isLoadedWithoutReference(Object, String)
249: */
250: LoadState isLoaded(Object entity, String attributeName);
251:
252: /**
253: * Gets the load status of the specified entity.
254: *
255: * @param entity Entity whose load status is to be determined.
256: * @return Entity load status
257: * @see cz.cvut.kbss.jopa.model.ProviderUtil#isLoaded(Object)
258: */
259: LoadState isLoaded(Object entity);
260:
261: /**
262: * Checks whether the specified attribute value of the specified entity is inferred in the underlying repository.
263: * <p>
264: * Note that given the nature of the repository implementation, this method may return true if the corresponding
265: * statement is both inferred and asserted. Also note that this method will use the descriptor associated with the
266: * specified entity in this persistence context to resolve the repository context, but some underlying repositories
267: * do not store inferences in data contexts, so the attribute context may be ignored.
268: *
269: * @param entity Entity whose attribute to examine. Must be managed by this persistence context
270: * @param attribute Attribute whose value to examine
271: * @param value The value whose inference to examine
272: * @return {@code true} if the entity attribute value is inferred, {@code false} otherwise
273: */
274: <T> boolean isInferred(T entity, FieldSpecification<? super T, ?> attribute, Object value);
275: }