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