001 package org.nakedobjects.applib;
002
003 import java.util.List;
004
005 import org.nakedobjects.applib.query.Query;
006 import org.nakedobjects.applib.security.UserMemento;
007
008
009
010 /**
011 * Represents a container that the domain objects work within. It provides access to the persistence mechanism
012 * and user interface.
013 */
014 public interface DomainObjectContainer {
015
016 //////////////////////////////////////////////////////////////////
017 // resolve, objectChanged
018 //////////////////////////////////////////////////////////////////
019
020 /**
021 * Ensure that the specified object is completely loaded into memory.
022 *
023 * <p>
024 * This forces the lazy loading mechanism to load the object if it is not already loaded.
025 */
026 void resolve(Object domainObject);
027
028 /**
029 * Ensure that the specified object is completely loaded into memory, though only if the supplied field
030 * reference is <tt>null</tt>.
031 *
032 * <p>
033 * This forces the lazy loading mechanism to load the object if it is not already loaded.
034 */
035 void resolve(Object domainObject, Object field);
036
037 /**
038 * Flags that the specified object's state has changed and its changes need to be saved.
039 */
040 void objectChanged(Object domainObject);
041
042
043 //////////////////////////////////////////////////////////////////
044 // flush, commit
045 //////////////////////////////////////////////////////////////////
046
047 /**
048 * Flush all changes to the object store.
049 *
050 * <p>
051 * Typically only for use by tests.
052 *
053 * @return <tt>true</tt>
054 */
055 boolean flush();
056
057 /**
058 * Commit all changes to the object store.
059 *
060 * <p>
061 * Typically only for use by tests.
062 */
063 void commit();
064
065 //////////////////////////////////////////////////////////////////
066 // new{Transient/Persistent}Instance
067 //////////////////////////////////////////////////////////////////
068
069 /**
070 * Create a new instance of the specified class, but do not persist it.
071 *
072 * @see #newPersistentInstance(Class)
073 */
074 <T> T newTransientInstance(Class<T> ofType);
075
076 /**
077 * Returns a new instance of the specified class that will have been persisted.
078 */
079 <T> T newPersistentInstance(final Class<T> ofType) ;
080
081 /**
082 * Returns a new instance of the specified class that has the sane persisted state as the specified object.
083 */
084 <T> T newInstance(final Class<T> ofType, final Object object);
085
086
087 //////////////////////////////////////////////////////////////////
088 // isValid, validate
089 //////////////////////////////////////////////////////////////////
090
091 /**
092 * Whether the object is in a valid state, that is that none of the validation of
093 * properties, collections and object-level is vetoing.
094 *
095 * @see #validate(Object)
096 */
097 boolean isValid(Object domainObject);
098
099 /**
100 * The reason, if any why the object is in a invalid state
101 *
102 * <p>
103 * Checks the validation of all of the properties, collections and object-level.
104 *
105 * @see #isValid(Object)
106 */
107 String validate(Object domainObject);
108
109 //////////////////////////////////////////////////////////////////
110 // isPersistent, persist, remove
111 //////////////////////////////////////////////////////////////////
112
113 /**
114 * Determines if the specified object is persistent (that it is stored permanently outside of the virtual
115 * machine).
116 */
117 boolean isPersistent(Object domainObject);
118
119 /**
120 * Make the specified transient object persistent.
121 *
122 * <p>
123 * Throws an exception if object is already persistent.
124 *
125 * @see #isPersistent(Object)
126 * @see #persistIfNotAlready(Object)
127 */
128 void persist(Object transientDomainObject);
129
130 /**
131 * Make the specified object persistent if not already.
132 *
133 * <p>
134 * Does nothing otherwise.
135 *
136 * @see #isPersistent(Object)
137 * @see #persist(Object)
138 */
139 void persistIfNotAlready(Object domainObject);
140
141 /**
142 * Removes (deletes) the persisted object.
143 *
144 * @param persistentDomainObject
145 */
146 void remove(Object persistentDomainObject);
147
148
149 //////////////////////////////////////////////////////////////////
150 // info, warn, error
151 //////////////////////////////////////////////////////////////////
152
153 /**
154 * Make the specified message available to the user. Note this will probably be displayed in transitory
155 * fashion, so is only suitable for useful but optional information.
156 *
157 * @see #warnUser(String)
158 * @see #raiseError(String)
159 */
160 void informUser(String message);
161
162 /**
163 * Warn the user about a situation with the specified message. The container should guarantee to display
164 * this warning to the user.
165 *
166 * @see #raiseError(String)
167 * @see #informUser(String)
168 */
169 void warnUser(String message);
170
171 /**
172 * Notify the user of an application error with the specified message. Note this will probably be
173 * displayed in an alarming fashion, so is only suitable for errors
174 *
175 * @see #warnUser(String)
176 * @see #informUser(String)
177 */
178 void raiseError(String message);
179
180 //////////////////////////////////////////////////////////////////
181 // security
182 //////////////////////////////////////////////////////////////////
183
184 /**
185 * Get the details about the current user.
186 */
187 UserMemento getUser();
188
189
190
191 //////////////////////////////////////////////////////////////////
192 // allInstances, allMatches, firstMatch, uniqueMatch
193 //////////////////////////////////////////////////////////////////
194
195 /**
196 * Returns all the instances of the specified type (including subtypes).
197 *
198 * <p>
199 * If there are no instances the list will be empty. This method creates a
200 * new {@link List} object each time it is called so the caller is free to
201 * use or modify the returned {@link List}, but the changes will not be
202 * reflected back to the repository.
203 *
204 * <p>
205 * This method should only be called where the number of instances is known to
206 * be relatively low.
207 */
208 public <T> List<T> allInstances(Class<T> ofType);
209
210
211
212 /**
213 * Returns all the instances of the specified type (including subtypes) that
214 * the filter object accepts.
215 *
216 * <p>
217 * If there are no instances the list will be empty. This method creates a
218 * new {@link List} object each time it is called so the caller is free to
219 * use or modify the returned {@link List}, but the changes will not be
220 * reflected back to the repository.
221 *
222 * <p>
223 * This method is useful during exploration/prototyping, but you may want to use
224 * {@link #allMatches(Query)} for production code.
225 */
226 public <T> List<T> allMatches(final Class<T> ofType, final Filter<T> filter);
227
228 /**
229 * Returns all the instances of the specified type (including subtypes) that
230 * have the given title.
231 *
232 * <p>
233 * If there are no instances the list will be empty. This method creates a
234 * new {@link List} object each time it is called so the caller is free to
235 * use or modify the returned {@link List}, but the changes will not be
236 * reflected back to the repository.
237 *
238 * <p>
239 * This method is useful during exploration/prototyping, but you may want to use
240 * {@link #allMatches(Query)} for production code.
241 */
242 public <T> List<T> allMatches(Class<T> ofType, String title);
243
244 /**
245 * Returns all the instances of the specified type (including subtypes) that
246 * match the given object: where any property that is set will be tested and
247 * properties that are not set will be ignored.
248 *
249 * <p>
250 * If there are no instances the list will be empty. This method creates a
251 * new {@link List} object each time it is called so the caller is free to
252 * use or modify the returned {@link List}, but the changes will not be
253 * reflected back to the repository.
254 *
255 * <p>
256 * This method is useful during exploration/prototyping, but you may want to use
257 * {@link #allMatches(Query)} for production code.
258 */
259 <T> List<T> allMatches(Class<T> ofType, T pattern);
260
261 /**
262 * Returns all the instances that match the given {@link Query}.
263 *
264 * <p>
265 * If there are no instances the list will be empty. This method creates a
266 * new {@link List} object each time it is called so the caller is free to
267 * use or modify the returned {@link List}, but the changes will not be
268 * reflected back to the repository.
269 */
270 <T> List<T> allMatches(Query<T> query);
271
272
273 /**
274 * Returns the first instance of the specified type (including subtypes)
275 * that matches the supplied {@link Filter}, or <tt>null</tt> if none.
276 *
277 * <p>
278 * This method is useful during exploration/prototyping, but you may want to use
279 * {@link #firstMatch(Query)} for production code.
280 */
281 public <T> T firstMatch(final Class<T> ofType, final Filter<T> filter);
282
283 /**
284 * Returns the first instance of the specified type (including subtypes)
285 * that matches the supplied title, or <tt>null</tt> if none.
286 *
287 * <p>
288 * This method is useful during exploration/prototyping, but you may want to use
289 * {@link #firstMatch(Query)} for production code.
290 */
291 <T> T firstMatch(Class<T> ofType, String title);
292
293 /**
294 * Returns the first instance of the specified type (including subtypes)
295 * that matches the supplied object as a pattern, or <tt>null</tt> if none.
296 *
297 * <p>
298 * This method is useful during exploration/prototyping, but you may want to use
299 * {@link #firstMatch(Query)} for production code.
300 */
301 <T> T firstMatch(Class<T> ofType, T pattern);
302
303 /**
304 * Returns the first instance that matches the supplied query,
305 * or <tt>null</tt> if none.
306 */
307 <T> T firstMatch(Query<T> query);
308
309
310 /**
311 * Find the only instance of the specified type (including subtypes) that
312 * has the specified title.
313 *
314 * <p>
315 * If no instance is found then <tt>null</tt> will be return, while if there
316 * is more that one instances a run-time exception will be thrown.
317 *
318 * <p>
319 * This method is useful during exploration/prototyping, but you may want to use
320 * {@link #uniqueMatch(Query)} for production code.
321 */
322 public <T> T uniqueMatch(final Class<T> ofType, final Filter<T> filter);
323
324 /**
325 * Find the only instance of the specified type (including subtypes) that
326 * has the specified title.
327 *
328 * <p>
329 * If no instance is found then <tt>null</tt> will be returned, while if
330 * there is more that one instances a run-time exception will be thrown.
331 *
332 * <p>
333 * This method is useful during exploration/prototyping, but you may want to use
334 * {@link #uniqueMatch(Query)} for production code.
335 */
336 <T> T uniqueMatch(Class<T> ofType, String title);
337
338 /**
339 * Find the only instance of the patterned object type (including subtypes)
340 * that matches the set fields in the pattern object: where any property
341 * that is set will be tested and properties that are not set will be
342 * ignored.
343 *
344 * <p>
345 * If no instance is found then null will be return, while if there is more
346 * that one instances a run-time exception will be thrown.
347 *
348 * <p>
349 * This method is useful during exploration/prototyping, but you may want to use
350 * {@link #uniqueMatch(Query)} for production code.
351 */
352 <T> T uniqueMatch(Class<T> ofType, T pattern);
353
354 /**
355 * Find the only instance that matches the provided query.
356 *
357 * <p>
358 * If no instance is found then null will be return, while if there is more
359 * that one instances a run-time exception will be thrown.
360 */
361 <T> T uniqueMatch(Query<T> query);
362
363
364 }
365 // Copyright (c) Naked Objects Group Ltd.