001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Florent Guillaume
011 */
012
013package org.nuxeo.ecm.core.storage.sql;
014
015import java.io.Serializable;
016import java.util.List;
017import java.util.Map;
018
019import javax.resource.cci.Connection;
020
021import org.nuxeo.ecm.core.api.IterableQueryResult;
022import org.nuxeo.ecm.core.api.PartialList;
023import org.nuxeo.ecm.core.model.LockManager;
024import org.nuxeo.ecm.core.query.QueryFilter;
025
026/**
027 * The session is the main high level access point to data from the underlying database.
028 *
029 * @author Florent Guillaume
030 */
031public interface Session extends Connection {
032
033    /**
034     * Gets the low-level Mapper for this session.
035     *
036     * @return the mapper
037     */
038    Mapper getMapper();
039
040    /**
041     * Checks if the session is live (not closed).
042     *
043     * @return {@code true} if the session is live
044     */
045    boolean isLive();
046
047    /**
048     * Returns {@code true} if all sessions in the current thread share the same state.
049     */
050    boolean isStateSharedByAllThreadSessions();
051
052    /**
053     * Gets the session repository name.
054     *
055     * @return the repository name
056     */
057    String getRepositoryName();
058
059    /**
060     * Gets the {@link Model} associated to this session.
061     *
062     * @return the model
063     */
064    Model getModel();
065
066    /**
067     * Saves the modifications to persistent storage.
068     * <p>
069     * Modifications will be actually written only upon transaction commit.
070     *
071     */
072    void save();
073
074    /**
075     * Gets the root node of the repository.
076     *
077     * @return the root node
078     */
079    Node getRootNode();
080
081    /**
082     * Gets a node given its id.
083     *
084     * @param id the id
085     * @return the node, or {@code null} if not found
086     */
087    Node getNodeById(Serializable id);
088
089    /**
090     * Gets several nodes given their ids.
091     *
092     * @param ids the ids
093     * @return the nodes, in the same order as the ids, with elements being {@code null} if not found
094     */
095    List<Node> getNodesByIds(List<Serializable> ids);
096
097    /**
098     * Gets a node given its absolute path, or given an existing node and a relative path.
099     *
100     * @param path the path
101     * @param node the node (ignored for absolute paths)
102     * @return the node, or {@code null} if not found
103     */
104    Node getNodeByPath(String path, Node node);
105
106    /**
107     * Adds a mixin to a node.
108     * <p>
109     * Does nothing if the mixin was already present on the node.
110     *
111     * @param node the node
112     * @param mixin the mixin name
113     * @return {@code true} if the mixin was added, or {@code false} if it is already present
114     * @since 5.8
115     */
116    boolean addMixinType(Node node, String mixin);
117
118    /**
119     * Removes a mixin from a node.
120     * <p>
121     * It's not possible to remove a mixin coming from the primary type.
122     *
123     * @param node the node
124     * @param mixin the mixin
125     * @return {@code true} if the mixin was removed, or {@code false} if it isn't present or is present on the type or
126     *         does not exist
127     * @since 5.8
128     */
129    boolean removeMixinType(Node node, String mixin);
130
131    /**
132     * Interface for a class that knows how to resolve a node path into a node id.
133     */
134    interface PathResolver {
135        /**
136         * Returns the node id for a given path.
137         *
138         * @param path the node path
139         * @return the node id, or {@code null}
140         */
141        Serializable getIdForPath(String path);
142    }
143
144    /**
145     * Gets the parent of a node.
146     * <p>
147     * The root has a {@code null} parent.
148     *
149     * @param node the node
150     * @return the parent node, or {@code null} for the root's parent
151     */
152    Node getParentNode(Node node);
153
154    /**
155     * Gets the absolute path of a node.
156     *
157     * @param node the node
158     * @return the path
159     */
160    String getPath(Node node);
161
162    /**
163     * Checks if a child node with the given name exists.
164     * <p>
165     * There are two kinds of children, the regular children documents and the complex properties. The {@code boolean}
166     * {@value #complexProp} allows a choice between those.
167     *
168     * @param parent the parent node
169     * @param name the child name
170     * @param complexProp whether to check complex properties or regular children
171     * @return {@code true} if a child node with that name exists
172     */
173    boolean hasChildNode(Node parent, String name, boolean complexProp);
174
175    /**
176     * Gets a child node given its parent and name.
177     *
178     * @param parent the parent node
179     * @param name the child name
180     * @param complexProp whether to check complex properties or regular children
181     * @return the child node, or {@code null} is not found
182     */
183    Node getChildNode(Node parent, String name, boolean complexProp);
184
185    /**
186     * Checks it a node has children.
187     *
188     * @param parent the parent node
189     * @param complexProp whether to check complex properties or regular children
190     * @return {@code true} if the parent has children
191     */
192    boolean hasChildren(Node parent, boolean complexProp);
193
194    /**
195     * Gets the children of a node.
196     *
197     * @param parent the parent node
198     * @param name the children name to get (for lists of complex properties), or {@code null} for all
199     * @param complexProp whether to check complex properties or regular children
200     * @return the collection of children
201     */
202    List<Node> getChildren(Node parent, String name, boolean complexProp);
203
204    /**
205     * Creates a new child node.
206     *
207     * @param parent the parent to which the child is added
208     * @param name the child name
209     * @param pos the child position, or {@code null}
210     * @param typeName the child type
211     * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false})
212     * @return the new node
213     */
214    Node addChildNode(Node parent, String name, Long pos, String typeName, boolean complexProp);
215
216    /**
217     * Creates a new child node with given id (used for import).
218     *
219     * @param id the id
220     * @param parent the parent to which the child is added
221     * @param name the child name
222     * @param pos the child position, or {@code null}
223     * @param typeName the child type
224     * @param complexProp whether this is a complex property ({@code true}) or a regular child ({@code false})
225     * @return the new node
226     */
227    Node addChildNode(Serializable id, Node parent, String name, Long pos, String typeName, boolean complexProp);
228
229    /**
230     * Creates a proxy for a version node.
231     *
232     * @param targetId the target id
233     * @param versionSeriesId the version series id
234     * @param parent the parent to which the proxy is added
235     * @param name the proxy name
236     * @param pos the proxy position
237     * @return the new proxy node
238     */
239    Node addProxy(Serializable targetId, Serializable versionSeriesId, Node parent, String name, Long pos);
240
241    /**
242     * Sets a proxies' target.
243     *
244     * @param proxy the proxy
245     * @param targetId the new target id
246     * @since 5.5
247     */
248    void setProxyTarget(Node proxy, Serializable targetId);
249
250    /**
251     * Removes a node from the storage.
252     * <p>
253     * This is much more complex that removing a property node ( {@link #removePropertyNode}).
254     *
255     * @param node the node to remove
256     * @see {@link #removePropertyNode}
257     */
258    void removeNode(Node node);
259
260    /**
261     * Removes a property node from the storage.
262     * <p>
263     * This is much less complex that removing a generic document node ( {@link #removeNode}).
264     *
265     * @param node the property node to remove
266     * @see {@link #removeNode}
267     */
268    void removePropertyNode(Node node);
269
270    /**
271     * Order the given source child node before the destination child node. The source node will be placed before the
272     * destination one. If destination is {@code null}, the source node will be appended at the end of the children
273     * list.
274     *
275     * @param parent the parent node
276     * @param source the child node to move
277     * @param dest the child node before which to place the source node, or {@code null} to move at the end
278     */
279    void orderBefore(Node parent, Node source, Node dest);
280
281    /**
282     * Moves a node to a new location with a new name.
283     * <p>
284     * A {@link #save} is automatically done first.
285     *
286     * @param source the node to move
287     * @param parent the new parent to which the node is moved
288     * @param name the new node name
289     * @return the moved node
290     */
291    Node move(Node source, Node parent, String name);
292
293    /**
294     * Copies a node to a new location with a new name.
295     * <p>
296     * A {@link #save} is automatically done first.
297     *
298     * @param source the node to copy
299     * @param parent the new parent to which the node is copied
300     * @param name the new node name
301     * @return the copied node
302     */
303    Node copy(Node source, Node parent, String name);
304
305    /**
306     * Checks in a checked-out node: creates a new version with a copy of its information.
307     * <p>
308     * A {@link #save} is automatically done first.
309     *
310     * @param node the node to check in
311     * @param label the label for the version
312     * @param checkinComment the description for the version
313     * @return the created version
314     */
315    Node checkIn(Node node, String label, String checkinComment);
316
317    /**
318     * Checks out a checked-in node.
319     *
320     * @param node the node to check out
321     */
322    void checkOut(Node node);
323
324    /**
325     * Restores a node to a given version.
326     * <p>
327     * The restored node is checked in.
328     *
329     * @param node the node to restore
330     * @param version the version to restore from
331     */
332    void restore(Node node, Node version);
333
334    /**
335     * Gets a version given its version series id and label.
336     *
337     * @param versionSeriesId the version series id
338     * @param label the label
339     * @return the version node, or {@code null} if not found
340     */
341    Node getVersionByLabel(Serializable versionSeriesId, String label);
342
343    /**
344     * Gets all the versions for a given version series id.
345     * <p>
346     * A {@link #save} is automatically done first.
347     *
348     * @param versionSeriesId the version series id
349     * @return the list of versions
350     */
351    List<Node> getVersions(Serializable versionSeriesId);
352
353    /**
354     * Gets the last version for a given version series id.
355     * <p>
356     * A {@link #save} is automatically done first.
357     *
358     * @param versionSeriesId the version series id
359     * @return the last version, or {@code null} if no versions exist
360     */
361    Node getLastVersion(Serializable versionSeriesId);
362
363    /**
364     * Finds the proxies for a document. If the parent is not null, the search will be limited to its direct children.
365     * <p>
366     * If the document is a version, then only proxies to that version will be looked up.
367     * <p>
368     * Otherwise all proxies to the same version series than the document are retrieved.
369     * <p>
370     * A {@link #save} is automatically done first.
371     *
372     * @param document the document
373     * @param parent the parent, or {@code null}
374     * @return the list of proxies
375     */
376    List<Node> getProxies(Node document, Node parent);
377
378    /**
379     * Makes a NXQL query to the database.
380     *
381     * @param query the query
382     * @param queryFilter the query filter
383     * @param countTotal if {@code true}, also count the total size without offset/limit
384     * @return the resulting list with total size included
385     */
386    PartialList<Serializable> query(String query, QueryFilter queryFilter, boolean countTotal);
387
388    /**
389     * Makes a query to the database.
390     *
391     * @param query the query
392     * @param query the query type
393     * @param queryFilter the query filter
394     * @param countUpTo if {@code -1}, also count the total size without offset/limit.<br>
395     *            If {@code 0}, don't count the total size.<br>
396     *            If {@code n}, count the total number if there are less than n documents otherwise set the size to
397     *            {@code -1}.
398     * @return the resulting list with total size included
399     * @Since 5.6
400     */
401    PartialList<Serializable> query(String query, String queryType, QueryFilter queryFilter, long countUpTo);
402
403    /**
404     * Makes a query to the database and returns an iterable (which must be closed when done).
405     *
406     * @param query the query
407     * @param queryType the query type
408     * @param queryFilter the query filter
409     * @param params optional query-type-dependent parameters
410     * @return an iterable, which <b>must</b> be closed when done
411     */
412    IterableQueryResult queryAndFetch(String query, String queryType, QueryFilter queryFilter, Object... params);
413
414    /**
415     * Gets the lock manager for this session.
416     *
417     * @return the lock manager
418     * @since 7.4
419     */
420    LockManager getLockManager();
421
422    /**
423     * Read ACLs are optimized ACLs for the read permission, they need to be updated after document creation or ACL
424     * change.
425     * <p>
426     * This method flag the current session, the read ACLs update will be done automatically at save time.
427     */
428    void requireReadAclsUpdate();
429
430    /**
431     * Update only the read ACLs that have changed.
432     */
433    void updateReadAcls();
434
435    /**
436     * Rebuild the read ACLs for the whole repository.
437     */
438    void rebuildReadAcls();
439
440    /**
441     * Gets the fulltext extracted from the binary fields.
442     *
443     * @since 5.9.3
444     */
445    Map<String, String> getBinaryFulltext(Serializable id);
446
447}