• Views
  • Iteration Report
  • My Iteration Report
  •  
OMERO.server
  • Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • Last Change
  • Annotate
  • Revision Log

root/trunk/components/common/src/ome/api/IPojos.java

Revision 2575, 21.2 kB (checked in by jmoore, 6 months ago)

ticket:1002 - Further additions for pagination in getImages()

  • Added javadoc
  • Reworked PojosGetImagesQueryDefinition to use QueryBuilder
  • Property svn:keywords set to
    Date
    Revision
    Id
    URL
Line 
1/*
2 * ome.api.IPojos
3 *
4 *   Copyright 2006 University of Dundee. All rights reserved.
5 *   Use is subject to license terms supplied in LICENSE.txt
6 */
7
8package ome.api;
9
10// Java imports
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.HashSet;
14import java.util.Map;
15import java.util.Set;
16
17// Third-party libraries
18
19// Application-internal dependencies
20import ome.annotations.NotNull;
21import ome.annotations.Validate;
22import ome.model.ILink;
23import ome.model.IObject;
24import ome.model.core.Image;
25
26/**
27 * Provides methods for dealing with the core "Pojos" of OME. Included are:
28 * Projects, Datasets, Images, CategoryGroups, Categories, Classifications,
29 * ImageAnnotations, and DatasetAnnotations.
30 *
31 * <h3>Read API</h3>
32 * <p>
33 * The names of the methods correlate to how the function operates:
34 * <ul>
35 * <li><b>load</b>: start at container objects and work down toward the
36 * leaves, returning hierarchy (Proejct-&gt;Dataset-&gt;Image</li>
37 * <li><b>find</b>: start at leave objects and work up to containers,
38 * returning hierarchy</li>
39 * <li><b>get</b>: retrieves only leaves in the hierarchy (currently only
40 * Images)</li>
41 * </ul>
42 * </p>
43 * <h4>Options Mechanism</h4>
44 * <p>
45 * The options are used to add some constraints to the generic method e.g. load
46 * hierarchy trees images <i>for a given user</i>. This mechanism should give
47 * us enough flexibility to extend the API if necessary, e.g. in some cases we
48 * might want to retrieve the images with or without annotations
49 * </p>
50 * <p>
51 * Most methods take such an <code>options</code> map which is built on the
52 * client-side using {@link omero.client.OptionBuilder an option builder.} The
53 * currently supported options are:
54 * <ul>
55 * <li><b>annotator</b>(Integer): If key exists but value null, annotations
56 * are retrieved for all objects in the hierarchy where they exist; if a valid
57 * experimenterID, annotations are only retrieved for that user. May not be used
58 * be all methods. <b>Default: all annotations</b></li>
59 * <li><b>leaves</b>(Boolean): if FALSE omits images from the returned
60 * hierarchy. May not be used by all methods. <b>Default: true</b></li>
61 * <li><b>experimenter</b>(Integer): inables filtering on a per-experimenter
62 * basis. This option has a method-specific (and possibly context-specific)
63 * meaning. Please see the individual methods.</li>
64 * <li><b>group</b>(Integer): enables filtering on a per-group basis. The
65 * <b>experimenter</b> value is ignored if present and instead a similar
66 * filtering is done using all <b>experimenter</b>s in the given group.
67 *
68 * </p>
69 * <h3>Write API</h3>
70 * <p>
71 * As outlined in TODO, the semantics of the Omero write API are based on three
72 * rules:
73 * <ol>
74 * <li>IObject-valued fields for which <code>isLoaded()</code> returns false
75 * are assumed filterd</li>
76 * <li>Collection-valued fields that are null are assumed filtered</li>
77 * <li>Collection-valued fields for which
78 * <code>getDetails().isFiltered(String collectionName)</code> returns true
79 * are assumed filtered. TODO: should we accept isFiltered for all fields?
80 * </ol>
81 * In each of these cases, the server will reload that given field <b>before</b>
82 * attempting to save the graph.
83 * </p>
84 * <p>
85 * For all write calls, the options map (see below) must contain the userId and
86 * the userGroupId for the newly created objects. TODO umask.
87 * </p>
88 *
89 * @author Jean-Marie Burel &nbsp;&nbsp;&nbsp;&nbsp; <a
90 *         href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
91 * @author <br>
92 *         Josh Moore &nbsp;&nbsp;&nbsp;&nbsp; <a
93 *         href="mailto:josh.moore@gmx.de"> josh.moore@gmx.de</a>
94 * @version 1.0 <small> (<b>Internal version:</b> $Revision$ $Date$) </small>
95 * @since OME1.0
96 * @DEV.TODO possibly move optionBuilder to the common code. ome.common.utils
97 * @DEV.TODO possibly move map description to marker interface with a see also
98 *           link
99 * @DEV.TODO add throws statements where necessary (IllegalArgument, ...)
100 *
101 */
102public interface IPojos extends ServiceInterface {
103
104    // ~ READ API
105    // =========================================================================
106
107    /**
108     * Retrieves hierarchy trees rooted by a given node.
109     * <p>
110     * This method also retrieves the Experimenters linked to the objects in the
111     * tree. Similarly, all Images will be linked to their Pixel objects if
112     * included.
113     * </p>
114     * <p>
115     * Note that objects are never duplicated. For example, if an Experimenter
116     * owns all the objects in the retrieved tree, then those objects will be
117     * linked to the <i>same</i> instance of {@link Experimenter}. Or if an
118     * Image is contained in more than one Dataset in the retrieved tree, then
119     * all enclosing {@link Dataset} objects will point to the <i>same</i>
120     * {@link Image} object. And so on.
121     * </p>
122     *
123     * @param rootNodeType
124     *            The type of the root node. Can be {@link Project},
125     *            {@link Dataset}, {@link CategoryGroup}, or {@link Category}.
126     *            Cannot be null.
127     * @param rootNodeIds
128     *            The ids of the root nodes. Can be null if an Experimenter is
129     *            specified in <code>options</code>, otherwise an Exception
130     *            is thrown to prevent all images in the entire database from
131     *            being downloaded.
132     * @param options
133     *            Map as above. <code>annotator</code> and <code>leaves</code>
134     *            used. If <code>rootNodeIds==null</code>,
135     *            <code>experimenter|group</code> must be set and filtering
136     *            will be applied at the <i>Class</i>-level; e.g. to retrieve a
137     *            user's Projects, or user's Datasets. If
138     *            <code>rootNodeIds!=null</code>, the result will be filtered
139     *            by the <code>experimenter|group</code> at the
140     *            <code>Image</code> and intermediate levels <i>if available</i>.
141     * @DEV.TODO should it be applied at all levels?
142     * @return a set of hierarchy trees. The requested node as root and all of
143     *         its descendants. The type of the returned value will be
144     *         <code>rootNodeType</code>.
145     */
146    public <T extends IObject> Set<T> loadContainerHierarchy(@NotNull
147    Class<T> rootNodeType, @Validate(Long.class)
148    Set<Long> rootNodeIds, Map options);
149
150    /**
151     * Retrieves hierarchy trees in various hierarchies that contain the
152     * specified Images.
153     * <p>
154     * This method will look for all the containers containing the specified
155     * Images and then for all containers containing those containers and on up
156     * the container hierarchy.
157     * </p>
158     * <p>
159     * This method returns a <code>Set</code> with all root nodes that were
160     * found. Every root node is linked to the found objects and so on until the
161     * leaf nodes, which are {@link Image} objects. Note that the type of any
162     * root node in the returned set can be the given rootNodeType, any of its
163     * containees or an {@link Image image}.
164     * </p>
165     * <p>
166     * For example, say that you pass in the ids of six Images: <code>i1, i2,
167     * i3, i4, i5, i6</code>.
168     * If the P/D/I hierarchy in the DB looks like this:
169     * </p>
170     *
171     * <pre>
172     *                   __p1__
173     *                  /      \   
174     *                _d1_    _d2_      d3
175     *               /    \  /    \     |
176     *              i1     i2     i3    i4    i5  i6
177     * </pre>
178     *
179     * <p>
180     * Then the returned set will contain <code>p1, d3, i5, i6</code>. All
181     * objects will be properly linked up.
182     * </p>
183     * <p>
184     * Finally, this method will <i>only</i> retrieve the nodes that are
185     * connected in a tree to the specified leaf image nodes. Back to the
186     * previous example, if <code>d1</code> contained image
187     * <code>img500</code>, then the returned object would <i>not</i>
188     * contain <code>img500</code>. In a similar way, if <code>p1</code>
189     * contained <code>ds300</code> and this dataset weren't linked to any of
190     * the <code>i1, i2, i3, i4, i5, i6
191     * </code> images, then <code>ds300</code>
192     * would <i>not</i> be part of the returned tree rooted by <code>p1</code>.
193     * </p>
194     *
195     * @param rootNodeType
196     *            top-most type which will be searched for Can be
197     *            {@link Project} or {@link CategoryGroup}. Not null.
198     * @param imagesIds
199     *            Contains the ids of the Images that sit at the bottom of the
200     *            trees. Not null.
201     * @param options
202     *            Map as above. <code>annotator</code> used.
203     *            <code>experimenter|group</code> may be applied at the
204     *            top-level only or at each level in the hierarchy, but will not
205     *            apply to the leaf (Image) level.
206     * @return A <code>Set</code> with all root nodes that were found.
207     * @DEV.TODO decide on use of experimenter option
208     */
209    public <T extends IObject> Set<IObject> findContainerHierarchies(@NotNull
210    Class<T> rootNodeType, @NotNull
211    @Validate(Long.class)
212    Set<Long> imagesIds, Map options);
213
214    /**
215     * Finds all the annotations that have been attached to the specified
216     * <code>rootNodes</code> for the specified <code>annotatorIds</code>.
217     * This method looks for all annotations that have been attached to each of
218     * the specified objects. It then maps each <code>rootNodeId</code> onto
219     * the set of all annotations that were found for that node. If no
220     * annotations were found for that node, then the entry will be
221     * <code>null</code>. Otherwise it will be a <code>Set</code>
222     * containing {@link Annotation} objects.
223     *
224     * @param rootNodeType
225     *            The type of the rootNodes Can be {@link Dataset} or
226     *            {@link Image}. Not null.
227     * @param rootNodeIds
228     *            Ids of the objects of type <code>rootNodeType</code>. Not
229     *            null.
230     * @param annotatorIds
231     *            Ids of the users for whom annotations should be retrieved. If
232     *            null, all annotations returned.
233     * @param options
234     *            Map as unused. No notion of <code>experimenter|group</code>
235     *            or <code>leaves</code> or <code>counts</code>
236     * @return A map whose key is rootNodeId and value the <code>Set</code> of
237     *         all annotations for that node or <code>null</code>.
238     */
239    public <T extends IObject, A extends IObject> Map<Long, Set<A>> findAnnotations(
240            @NotNull
241            Class<T> rootNodeType, @NotNull
242            @Validate(Long.class)
243            Set<Long> rootNodeIds, @Validate(Long.class)
244            Set<Long> annotatorIds, Map options);
245
246    /**
247     * Retrieves paths in the Category Group/Category/Image (CG/C/I) hierarchy.
248     * <p>
249     * Because of the mutually exclusive rule of CG/C hierarchy, this method is
250     * quite tricky We want to retrieve all Category Group/Category paths that
251     * end with the specified leaves.
252     * </p>
253     * <p>
254     * We also want to retrieve the all Category Group/Category paths that
255     * don’t end with the specified leaves, note that in that case because of
256     * the mutually exclusive constraint the categories which don’t contain a
257     * specified leaf but which is itself contained in a group which already has
258     * a category ending with the specified leaf is excluded.
259     * </p>
260     * <p>
261     * This is <u>more</u> restrictive than may be imagined. The goal is to
262     * find CGC paths to which an Image <B>MAY</b> be attached.
263     * </p>
264     *
265     * @param imgIDs
266     *            the ids of the Images that sit at the bottom of the CGC trees.
267     *            Not null.
268     * @param algorithm,
269     *            specify the search algorithm for finding paths.
270     * @param options
271     *            Map as above. No notion of <code>annotator</code> or
272     *            <code>leaves</code>. <code>experimenter & group</code>
273     *            are as {@link #findContainerHierarchies(Class, Set, Map)}
274     * @return A <code>Set</code> of hierarchy trees with all root nodes that
275     *         were found.
276     */
277    public <T extends IObject> Set<T> findCGCPaths(@NotNull
278    @Validate(Long.class)
279    Set<Long> imgIds, @NotNull
280    String algorithm, Map options);
281
282    /**
283     * algorithm which given a set of images ids retrieve the CG-C hierarchy
284     * where we can classify the images constraint: if a category contains an
285     * image => the hierarchy CG-C is not retrieved.
286     */
287    public final static String CLASSIFICATION_ME = "CLASSIFICATION_ME";
288
289    /**
290     * algorithm which given a set of images ids retrieves the CG-C where
291     * category doesn't contain the image.
292     */
293    public final static String CLASSIFICATION_NME = "CLASSIFICATION_NME";
294
295    /**
296     * algorithm which given a set of image ids retrieves the CG-C containing
297     * the images.
298     */
299    public final static String DECLASSIFICATION = "DECLASSIFICATION";
300
301    public final static Set<String> ALGORITHMS = new HashSet<String>(Arrays
302            .asList(new String[] { CLASSIFICATION_ME, CLASSIFICATION_NME,
303                    DECLASSIFICATION }));
304
305    /**
306     * Retrieve a user's (or all users') images within any given container. For
307     * example, all images in project, applying temporal filtering or
308     * pagination.
309     *
310     * @param rootNodeType
311     *            A Class which will have its hierarchy searched for Images. Not
312     *            null. TODO types?
313     * @param rootNodeIds
314     *            A set of ids of type <code>rootNodeType</code> Not null.
315     * @param options
316     *            Map as above. No notion of <code>leaves</code>.
317     *            <code>experimenter|group</code> apply at the Image level.
318     *            OPTIONS: - startTime and/or endTime should be
319     *            Timestamp.valueOf("YYYY-MM-DD hh:mm:ss.ms");
320     *            <p>
321     *            "limit" and "offset" are applied at the Image-level. That is,
322     *            calling with Dataset.class, limit == 10 and offset == 0 will
323     *            first perform one query to get an effective set of
324     *            rootNodeIds, then getImages will be called with an effective
325     *            rootNodeType of Image.class and the new ids.
326     *            </p>
327     * @return A set of images.
328     * @see ome.util.builders.PojoOptions#paginate(int, int)
329     * @see ome.util.builders.PojoOptions#startTime(java.sql.Timestamp)
330     * @see ome.util.builders.PojoOptions#endTime(java.sql.Timestamp)
331     */
332    public <T extends IObject> Set<Image> getImages(@NotNull
333    Class<T> rootNodeType, @NotNull
334    @Validate(Long.class)
335    Set<Long> rootNodeIds, Map options);
336
337    /**
338     * Retrieve images by options.
339     *
340     * @param options
341     *            Map as above. No notion of <code>leaves</code>.
342     *            <code>experimenter|group</code> apply at the Image level and
343     *            <b>must be present</b>. OPTIONS: - startTime and/or endTime
344     *            should be Timestamp.valueOf("YYYY-MM-DD hh:mm:ss.ms");
345     * @return A set of images.
346     */
347    public Set<Image> getImagesByOptions(Map options);
348
349    /**
350     * Retrieve a user's images.
351     *
352     * @param options
353     *            Map as above. No notion of <code>leaves</code>.
354     *            <code>experimenter|group</code> apply at the Image level and
355     *            <b>must be present</b>.
356     * @return A set of images.
357     */
358    public Set<Image> getUserImages(Map options);
359
360    /**
361     * Retrieves <code>Experimenter</code> instances based on unique user name
362     *
363     * @param names
364     *            Set of user names for <code>Experimenter</code>
365     * @param options
366     *            Map. Unused.
367     * @return A map from username to <code>Experimenter</code>
368     */
369    public Map getUserDetails(@NotNull
370    @Validate(String.class)
371    Set<String> names, Map options);
372
373    /**
374     * Counts the number of members in a collection for a given object. For
375     * example, if you wanted to retrieve the number of Images contained in a
376     * Dataset you would pass TODO.
377     *
378     * @param class
379     *            The fully-qualified classname of the object to be tested
380     * @param property
381     *            Name of the property on that class, omitting getters and
382     *            setters.
383     * @param ids
384     *            Set of Longs, the ids of the objects to test
385     * @param options
386     *            Map. Unused.
387     * @return A map from id integer to count integer
388     */
389    public Map getCollectionCount(@NotNull
390    String type, @NotNull
391    String property, @NotNull
392    @Validate(Long.class)
393    Set<Long> ids, Map options);
394
395    /**
396     * retrieves a collection with all members initialized ("loaded"). This is
397     * useful when a collection has been nulled in a previous query.
398     *
399     * @param dataObject
400     *            Can be "unloaded".
401     * @param collectionName
402     *            <code>public final static String</code> from the
403     *            IObject.class
404     * @param options
405     *            Map. Unused.
406     * @return An initialized collection.
407     */
408    public Collection retrieveCollection(@NotNull
409    IObject dataObject, @NotNull
410    String collectionName, Map options);
411
412    // ~ WRITE API
413    // =========================================================================
414
415    /**
416     * Creates the specified data object.
417     * <p>
418     * A “placeholder” parent object is created if the data object is to be
419     * put in a collection.
420     * </p>
421     * <p>
422     * For example, if the object is a <code>Dataset</code>, we first create
423     * a <code>Project</code> as parent then we set the Dataset parent as
424     * follows: <code>
425     *      //pseudo-code TODO
426     *      Project p = new Project(id,false);
427     *      dataset.addProject(p);
428     * </code>
429     * then for each parent relationship a DataObject {@see ILink link} is
430     * created.
431     *
432     * @param Pojo-based
433     *            IObject. Supported: Project, Dataset, CategoryGroup, Category,
434     *            Annotation, Group, Experimenter. Not null.
435     * @options Map as above.
436     * @return the created object
437     */
438    public <T extends IObject> T createDataObject(@NotNull
439    T object, Map options);
440
441    /**
442     * convenience method to save network calls. Loops over the array of
443     * IObjects calling createDataObject.
444     *
445     * @param dataObjects
446     *            Array of Omero <code>IObjects</code>
447     * @param options
448     *            Map as above.
449     *
450     * @see createDataObject
451     */
452    public IObject[] createDataObjects(@NotNull
453    IObject[] dataObjects, Map options);
454
455    /**
456     * Removes links between OmeroDataObjects e.g Project-Dataset, Dataset-Image
457     * Note that the objects themselves aren't deleted, only the Link objects.
458     * TODO We will need to add a delete method.
459     *
460     * @param dataObjectLinks
461     *            Not null.
462     * @param options
463     *            Map as above.
464     */
465    public void unlink(@NotNull
466    ILink[] dataOjectLinks, Map options);
467
468    /**
469     * typed convenience method for creating links. Functionality also availeble
470     * from {@see createDataObject}
471     *
472     * @param dataObjectLinks
473     *            Array of links to be created.
474     * @param options
475     *            Map as above.
476     * @return the created links
477     */
478    public ILink[] link(@NotNull
479    ILink[] dataObjectLinks, Map options);
480
481    /**
482     * Updates a data object.
483     * <p>
484     * To link or unlink objects to the specified object, we should call the
485     * methods link or unlink. TODO Or do we use for example
486     * dataset.setProjects(set of projects) to add. Tink has to be set as
487     * follows dataset->project and project->dataset.
488     *
489     * Alternatively, you can make sure that the collection is <b>exactly</b>
490     * how it should be in the database. If you can't guarantee this, it's best
491     * to send all your collections back as <code>null</code>
492     *
493     * @param dataObject
494     *            Pojos-based IObject. Supported: supported: Project, Dataset,
495     *            CategoryGroup, Category, Annotation, Group, Experimenter.
496     * @param options
497     *            Map as above.
498     * @return created data object
499     */
500    public <T extends IObject> T updateDataObject(@NotNull
501    T dataObject, Map options);
502
503    /**
504     * convenience method to save network calls. Loops over the array of
505     * IObjects calling updateDataObject.
506     *
507     * @param dataObjects
508     * @param options
509     *            Map as above.
510     * @return created data objects.
511     * @see #updateDataObject(IObject, Map)
512     */
513    public IObject[] updateDataObjects(@NotNull
514    IObject[] dataObjects, Map options);
515
516    /**
517     * Deletes a data object. Currently this method takes a very conservative
518     * approach and only tries to delete a single object (no cascading). The
519     * user will have to delete objects in the appropriate order to prevent
520     * database not null exceptions.
521     *
522     * @param dataObject
523     * @param options
524     */
525    public void deleteDataObject(@NotNull
526    IObject dataObject, Map options);
527
528    /**
529     * convenience method to save network calls. Loops over the array of
530     * IObjects calling deleteDataObjects
531     *
532     * @param dataObjects
533     * @param options
534     *            Map as above.
535     */
536    public void deleteDataObjects(@NotNull
537    IObject[] dataObjects, Map options);
538
539}
Note: See TracBrowser for help on using the browser.

Download in other formats:

  • Plain Text
  • Original Format

Trac Powered

Powered by Trac 0.11
By Edgewall Software.

Visit the Trac open source project at
http://trac.edgewall.org/