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 *     Bogdan Stefanescu
011 *     Florent Guillaume
012 */
013
014package org.nuxeo.ecm.core.api;
015
016import java.io.Serializable;
017import java.security.Principal;
018import java.util.Collection;
019import java.util.List;
020import java.util.Map;
021
022import org.nuxeo.ecm.core.api.DocumentModel.DocumentModelRefresh;
023import org.nuxeo.ecm.core.api.event.DocumentEventTypes;
024import org.nuxeo.ecm.core.api.security.ACE;
025import org.nuxeo.ecm.core.api.security.ACP;
026import org.nuxeo.ecm.core.schema.DocumentType;
027import org.nuxeo.ecm.core.schema.types.Schema;
028
029/**
030 * A session to the Nuxeo Core.
031 *
032 * @see DocumentModel
033 * @see DocumentRef
034 * @author Bogdan Stefanescu
035 * @author Florent Guillaume
036 */
037public interface CoreSession extends AutoCloseable {
038
039    // used to pass properties to importDocument
040    String IMPORT_VERSION_VERSIONABLE_ID = "ecm:versionableId";
041
042    String IMPORT_VERSION_CREATED = "ecm:versionCreated";
043
044    String IMPORT_VERSION_LABEL = "ecm:versionLabel";
045
046    String IMPORT_VERSION_DESCRIPTION = "ecm:versionDescription";
047
048    String IMPORT_VERSION_IS_LATEST = "ecm:isLatestVersion";
049
050    String IMPORT_VERSION_IS_LATEST_MAJOR = "ecm:isLatestMajorVersion";
051
052    String IMPORT_IS_VERSION = "ecm:isVersion";
053
054    String IMPORT_VERSION_MAJOR = "ecm:majorVersion";
055
056    String IMPORT_VERSION_MINOR = "ecm:minorVersion";
057
058    String IMPORT_PROXY_TARGET_ID = "ecm:proxyTargetId";
059
060    String IMPORT_PROXY_VERSIONABLE_ID = "ecm:proxyVersionableId";
061
062    String IMPORT_LIFECYCLE_POLICY = "ecm:lifeCyclePolicy";
063
064    String IMPORT_LIFECYCLE_STATE = "ecm:lifeCycleState";
065
066    /**
067     * @deprecated since 5.4.2, use {@link #IMPORT_LOCK_OWNER} and {@link #IMPORT_LOCK_CREATED} instead
068     */
069    @Deprecated
070    String IMPORT_LOCK = "ecm:lock";
071
072    /** @since 5.4.2 */
073    String IMPORT_LOCK_OWNER = "ecm:lockOwner";
074
075    /**
076     * Lock creation time as a Calendar object.
077     *
078     * @since 5.4.2
079     */
080    String IMPORT_LOCK_CREATED = "ecm:lockCreated";
081
082    String IMPORT_CHECKED_IN = "ecm:isCheckedIn";
083
084    String IMPORT_BASE_VERSION_ID = "ecm:baseVersionId";
085
086    /** The document type to use to create a proxy by import. */
087    String IMPORT_PROXY_TYPE = "ecm:proxy";
088
089    /**
090     * Allow version write, Boolean parameter passed in context data at saveDocument time.
091     *
092     * @since 5.9.2
093     */
094    String ALLOW_VERSION_WRITE = "allowVersionWrite";
095
096    /**
097     * Closes this session.
098     *
099     * @since 5.9.3
100     */
101    @Override
102    void close();
103
104    /**
105     * Destroys any system resources held by this instance.
106     * <p>
107     * Called when the instance is no more needed.
108     */
109    void destroy();
110
111    /**
112     * Gets the document type object given its type name.
113     *
114     * @param type the document type name
115     * @return the type the doc type object
116     */
117    DocumentType getDocumentType(String type);
118
119    /**
120     * NOT PUBLIC, DO NOT CALL.
121     * <p>
122     * Connects the CoreSession to a low-level Session.
123     *
124     * @param repositoryName the repository name
125     * @param principal the principal
126     */
127    void connect(String repositoryName, NuxeoPrincipal principal);
128
129    /**
130     * Returns true if the session is currently connected to the repository.
131     */
132    boolean isLive(boolean onThread);
133
134    /**
135     * Cancels any pending change made through this session.
136     *
137     */
138    void cancel();
139
140    /**
141     * Saves any pending changes done until now through this session.
142     *
143     */
144    void save();
145
146    /**
147     * Gets the current session id.
148     * <p>
149     * If the client is not connected returns null.
150     *
151     * @return the session id or null if not connected
152     */
153    String getSessionId();
154
155    /**
156     * Returns {@code true} if all sessions in the current thread share the same state.
157     */
158    boolean isStateSharedByAllThreadSessions();
159
160    /**
161     * Gets the principal that created the client session.
162     *
163     * @return the principal
164     */
165    Principal getPrincipal();
166
167    /**
168     * Checks if the principal that created the client session has the given privilege on the referred document.
169     *
170     * @param docRef
171     * @param permission
172     * @return
173     */
174    boolean hasPermission(DocumentRef docRef, String permission);
175
176    /**
177     * Checks if a given principal has the given privilege on the referred document.
178     *
179     * @param principal
180     * @param docRef
181     * @param permission
182     * @return
183     */
184    boolean hasPermission(Principal principal, DocumentRef docRef, String permission);
185
186    /**
187     * Gets the root document of this repository.
188     *
189     * @return the root document. cannot be null
190     */
191    DocumentModel getRootDocument();
192
193    /**
194     * Gets a document model given its reference.
195     * <p>
196     * The default schemas are used to populate the returned document model. Default schemas are configured via the
197     * document type manager.
198     * <p>
199     * Any other data model not part of the default schemas will be lazily loaded as needed.
200     *
201     * @param docRef the document reference
202     * @return the document
203     * @throws DocumentNotFoundException if the document cannot be found
204     */
205    DocumentModel getDocument(DocumentRef docRef) throws DocumentNotFoundException;
206
207    /**
208     * Gets a list of documents given their references.
209     * <p>
210     * Documents that are not accessible are skipped.
211     *
212     * @throws DocumentNotFoundException if a document cannot be found
213     */
214    DocumentModelList getDocuments(DocumentRef[] docRefs) throws DocumentNotFoundException;
215
216    /**
217     * Gets a child document given its name and the parent reference.
218     * <p>
219     * Throws an exception if the document could not be found.
220     * <p>
221     * If the supplied id is null, returns the default child of the document if any, otherwise raises an exception.
222     * <p>
223     * If the parent is null or its path is null, then root is considered.
224     *
225     * @param parent the reference to the parent document
226     * @param name the name of the child document to retrieve
227     * @return the named child if exists
228     * @throws DocumentNotFoundException if there is no child with the given name
229     */
230    DocumentModel getChild(DocumentRef parent, String name);
231
232    /**
233     * Tests if the document has a child with the given name.
234     * <p>
235     * This operation silently ignores non-folder documents: If the document is not a folder then returns false.
236     *
237     * @param parent the document
238     * @param name the child name
239     * @return {@code true} if the document has a child with the given name
240     *
241     * @since 7.3
242     */
243    boolean hasChild(DocumentRef parent, String name);
244
245    /**
246     * Gets the children of the given parent.
247     *
248     * @param parent the parent reference
249     * @return the children if any, an empty list if no children or null if the specified parent document is not a
250     *         folder
251     */
252    DocumentModelList getChildren(DocumentRef parent);
253
254    /**
255     * Gets an iterator to the children of the given parent.
256     *
257     * @param parent the parent reference
258     * @return iterator over the children collection or null if the specified parent document is not a folder
259     */
260    DocumentModelIterator getChildrenIterator(DocumentRef parent);
261
262    /**
263     * Gets the children of the given parent filtered according to the given document type.
264     *
265     * @param parent the parent reference
266     * @param type the wanted document type
267     * @return the documents if any, an empty list if none were found or null if the parent document is not a folder
268     */
269    DocumentModelList getChildren(DocumentRef parent, String type);
270
271    /**
272     * Gets an iterator to the children of the given parent filtered according to the given document type.
273     */
274    DocumentModelIterator getChildrenIterator(DocumentRef parent, String type);
275
276    /**
277     * Gets the children of the given parent filtered according to the given document type and permission.
278     *
279     * @param parent the parent reference
280     * @param type the wanted document type
281     * @param type the permission the user must have
282     * @return the documents if any, an empty list if none were found or null if the parent document is not a folder
283     */
284    DocumentModelList getChildren(DocumentRef parent, String type, String perm);
285
286    /**
287     * Same as {@link #getChildren(DocumentRef, String, String)} but the result is filtered and then sorted using the
288     * specified filter and sorter.
289     *
290     * @param parent the parent reference
291     * @param type the wanted type
292     * @param perm permission to check for. If null, defaults to READ
293     * @param filter the filter to use if any, null otherwise
294     * @param sorter the sorter to use if any, null otherwise
295     * @return the list of the children or an empty list if no children were found or null if the given parent is not a
296     *         folder
297     */
298    DocumentModelList getChildren(DocumentRef parent, String type, String perm, Filter filter, Sorter sorter);
299
300    /**
301     * Gets the references of the children. No permission is checked if perm is null.
302     *
303     * @param parentRef the parent reference
304     * @param perm the permission to check on the children (usually READ); if null, <b>no permission is checked</b>
305     * @return a list of children references
306     * @since 1.4.1
307     */
308    List<DocumentRef> getChildrenRefs(DocumentRef parentRef, String perm);
309
310    /**
311     * Gets the children of the given parent filtered according to the given document type and permission. Long result
312     * sets are loaded frame by frame transparently by the DocumentModelIterator.
313     *
314     * @param parent
315     * @param type
316     * @param perm
317     * @param filter
318     * @return
319     */
320    DocumentModelIterator getChildrenIterator(DocumentRef parent, String type, String perm, Filter filter);
321
322    /**
323     * Same as {@link #getChildren(DocumentRef, String, String, Filter, Sorter)} without specific permission filtering.
324     *
325     * @param parent the parent reference
326     * @param type the wanted type
327     * @param filter the filter to use if any, null otherwise
328     * @param sorter the sorter to use if any, null otherwise
329     * @return the list of the children or an empty list if no children were found or null if the given parent is not a
330     *         folder
331     */
332    DocumentModelList getChildren(DocumentRef parent, String type, Filter filter, Sorter sorter);
333
334    /**
335     * Same as {@link CoreSession#getChildren(DocumentRef)} but returns only folder documents.
336     *
337     * @param parent the parent ref
338     * @return a list of children if any, an empty one if none or null if the given parent is not a folder
339     */
340    DocumentModelList getFolders(DocumentRef parent);
341
342    /**
343     * Same as {@link CoreSession#getFolders(DocumentRef)} but uses an optional filter and sorter on the result.
344     *
345     * @param parent the parent reference
346     * @param filter the filter to use or null if none
347     * @param sorter the sorter to use or null if none
348     * @return a list of children if any, an empty one if none or null if the given parent is not a folder
349     */
350    DocumentModelList getFolders(DocumentRef parent, Filter filter, Sorter sorter);
351
352    /**
353     * Same as {@link CoreSession#getChildren(DocumentRef)} but returns only non-folder documents.
354     *
355     * @param parent the parent reference
356     * @return a list of children if any, an empty one if none or null if the given parent is not a folder
357     */
358    DocumentModelList getFiles(DocumentRef parent);
359
360    /**
361     * Same as {@link #getFiles} but uses an optional filter and sorter on the result.
362     *
363     * @param parent the parent reference
364     * @param filter the filter to use or null if none
365     * @param sorter the sorter to use or null if none
366     * @return a list of children if any, an empty one if none or null if the given parent is not a folder
367     */
368    DocumentModelList getFiles(DocumentRef parent, Filter filter, Sorter sorter);
369
370    /**
371     * Returns the parent ref of the document referenced by {@code docRef} or {@code null} if this is the root document.
372     * <p>
373     * This method does not check the permissions on the parent document of this {@code CoreSession}'s {@code Principal}.
374     *
375     * @since 5.4.2
376     */
377    public DocumentRef getParentDocumentRef(DocumentRef docRef);
378
379    /**
380     * Gets the parent document or null if this is the root document.
381     *
382     * @return the parent document or null if this is the root document
383     */
384    DocumentModel getParentDocument(DocumentRef docRef);
385
386    /**
387     * Gets the parent documents in path from the root to the given document or empty list if this is the root document.
388     * <p>
389     * Documents the principal is is not allowed to browse are filtered out the parents list.
390     *
391     * @return the list with parent documents or empty list if this is the root document
392     */
393    List<DocumentModel> getParentDocuments(DocumentRef docRef);
394
395    /**
396     * Tests if the document pointed by the given reference exists and is accessible.
397     * <p>
398     * This operation makes no difference between non-existence and permission problems.
399     * <p>
400     * If the parent is null or its path is null, then root is considered.
401     *
402     * @param docRef the reference to the document to test for existence
403     * @return true if the referenced document exists, false otherwise
404     */
405    boolean exists(DocumentRef docRef);
406
407    /**
408     * Tests if the document has any children.
409     * <p>
410     * This operation silently ignores non-folder documents: If the document is not a folder then returns false.
411     * <p>
412     * If the parent is null or its path is null, then root is considered.
413     *
414     * @param docRef the reference to the document to test
415     * @return true if document has children, false otherwise
416     */
417    boolean hasChildren(DocumentRef docRef);
418
419    /**
420     * Creates a document model using type name.
421     * <p>
422     * Used to fetch initial datamodels from the type definition.
423     * <p>
424     * DocumentModel creation notifies a {@link DocumentEventTypes.EMPTY_DOCUMENTMODEL_CREATED} so that core event
425     * listener can initialize its content with computed properties.
426     *
427     * @param typeName
428     * @return the initial document model
429     */
430    DocumentModel createDocumentModel(String typeName);
431
432    /**
433     * Creates a document model using required information.
434     * <p>
435     * Used to fetch initial datamodels from the type definition.
436     * <p>
437     * DocumentModel creation notifies a {@link DocumentEventTypes.EMPTY_DOCUMENTMODEL_CREATED} so that core event
438     * listener can initialize its content with computed properties.
439     *
440     * @param parentPath
441     * @param name The destination name
442     * @param typeName
443     * @return the initial document model
444     */
445    DocumentModel createDocumentModel(String parentPath, String name, String typeName);
446
447    /**
448     * Creates a document model using required information.
449     * <p>
450     * Used to fetch initial datamodels from the type definition.
451     * <p>
452     * DocumentModel creation notifies a {@link DocumentEventTypes.EMPTY_DOCUMENTMODEL_CREATED} so that core event
453     * listener can initialize its content with computed properties.
454     *
455     * @param typeName
456     * @param options additional contextual data provided to core event listeners
457     * @return the initial document model
458     */
459    DocumentModel createDocumentModel(String typeName, Map<String, Object> options);
460
461    /**
462     * Creates a document using given document model for initialization.
463     * <p>
464     * The model contains path of the new document, its type and optionally the initial data models of the document.
465     * <p>
466     *
467     * @param model the document model to use for initialization
468     * @return the created document
469     */
470    DocumentModel createDocument(DocumentModel model);
471
472    /**
473     * Bulk creation of documents.
474     *
475     * @param docModels the document models to use for intialization
476     * @return the created documents
477     */
478    DocumentModel[] createDocument(DocumentModel[] docModels);
479
480    /**
481     * Low-level import of documents, reserved for the administrator.
482     * <p>
483     * This method is used to import documents with given ids, or directly import versions and proxies.
484     * <p>
485     * The id, parent, name and typeName must be present in each docModel.
486     * <p>
487     * The context data needs to be filled with values depending on the type of the document:
488     * <p>
489     * For a proxy (type = {@code "ecm:proxyType"}): {@link #IMPORT_PROXY_TARGET_ID} and
490     * {@link #IMPORT_PROXY_VERSIONABLE_ID}.
491     * <p>
492     * For a version (no parent): {@link #IMPORT_VERSION_VERSIONABLE_ID}, {@link #IMPORT_VERSION_CREATED},
493     * {@link #IMPORT_VERSION_LABEL} and {@link #IMPORT_VERSION_DESCRIPTION}.
494     * <p>
495     * For a live document: {@link #IMPORT_BASE_VERSION_ID} and {@link #IMPORT_CHECKED_IN} (Boolean).
496     * <p>
497     * For a live document or a version: {@link #IMPORT_LIFECYCLE_POLICY} , {@link #IMPORT_LIFECYCLE_STATE},
498     * {@link #IMPORT_VERSION_MAJOR} (Long) and {@link #IMPORT_VERSION_MINOR} (Long).
499     *
500     * @param docModels the documents to create
501     */
502    void importDocuments(List<DocumentModel> docModels);
503
504    /**
505     * Saves changes done on the given document model.
506     *
507     * @param docModel the document model that needs modified
508     */
509    DocumentModel saveDocument(DocumentModel docModel);
510
511    /**
512     * Bulk document saving.
513     *
514     * @param docModels the document models that needs to be saved
515     */
516    void saveDocuments(DocumentModel[] docModels);
517
518    /**
519     * Check if a document can be removed. This needs the REMOVE permission on the document and the REMOVE_CHILDREN
520     * permission on the parent.
521     * <p>
522     * For an archived version to be removeable, it must not be referenced from any proxy or be the base of a working
523     * document, and the REMOVE permission must be available on the working document (or the user must be an
524     * administrator if no working document exists).
525     *
526     * @param docRef the document
527     * @return true if the document can be removed
528     */
529    boolean canRemoveDocument(DocumentRef docRef);
530
531    /**
532     * Removes this document and all its children, if any.
533     *
534     * @param docRef the reference to the document to remove
535     */
536    void removeDocument(DocumentRef docRef);
537
538    /**
539     * Bulk method to remove documents.
540     * <p>
541     * This method is safe with respect to orderings: it doesn't fail if an ancestor of a document occurs before the
542     * document.
543     * </p>
544     *
545     * @param docRefs the refs to the document to remove
546     */
547    void removeDocuments(DocumentRef[] docRefs);
548
549    /**
550     * Removes all children from the given document.
551     *
552     * @param docRef the reference to the document to remove
553     */
554    void removeChildren(DocumentRef docRef);
555
556    /**
557     * Copies the source document to the destination folder under the given name. If the name is null the original name
558     * is preserved.
559     * <p>
560     * If the destination document is not a folder or it doesn't exists then throws an exception.
561     * <p>
562     * If the source is a proxy the destination will be a copy of the proxy.
563     *
564     * @param src the source document reference
565     * @param dst the destination folder reference
566     * @param name the new name of the file or null if the original name must be preserved
567     */
568    DocumentModel copy(DocumentRef src, DocumentRef dst, String name);
569
570    /**
571     * Copies the source document to the destination folder under the given name. If the name is null the original name
572     * is preserved.
573     * <p>
574     * If the destination document is not a folder or it doesn't exists then throws an exception.
575     * <p>
576     * If the source is a proxy the destination will be a copy of the proxy.
577     *
578     * @param src the source document reference
579     * @param dst the destination folder reference
580     * @param name the new name of the file or null if the original name must be preserved
581     * @param resetLifeCycle the property that flagged whether reset destination document lifecycle or not
582     * @return
583     * @since 5.7
584     */
585    DocumentModel copy(DocumentRef src, DocumentRef dst, String name, boolean resetLifeCycle);
586
587    /**
588     * Bulk copy. Destination must be a folder document.
589     *
590     * @param src the documents to copy
591     * @param dst the destination folder
592     */
593    List<DocumentModel> copy(List<DocumentRef> src, DocumentRef dst);
594
595    /**
596     * Bulk copy. Destination must be a folder document.
597     *
598     * @param src the documents to copy
599     * @param dst the destination folder
600     * @param resetLifeCycle the property that flagged whether reset destination document lifecycle or not
601     * @return
602     * @since 5.7
603     */
604    List<DocumentModel> copy(List<DocumentRef> src, DocumentRef dst, boolean resetLifeCycle);
605
606    /**
607     * Work like copy but in the case of a source proxy the destination will be a new document instead of a proxy.
608     *
609     * @see CoreSession#copy(DocumentRef, DocumentRef, String)
610     * @param src the source document reference
611     * @param dst the destination folder reference
612     * @param name the new name of the file or null if the original name must be preserved
613     */
614    DocumentModel copyProxyAsDocument(DocumentRef src, DocumentRef dst, String name);
615
616    /**
617     * Work like copy but in the case of a source proxy the destination will be a new document instead of a proxy.
618     *
619     * @param src the source document reference
620     * @param dst the destination folder reference
621     * @param name the new name of the file or null if the original name must be preserved
622     * @param resetLifeCycle the property that flagged whether reset destination document lifecycle or not
623     * @return
624     * @since 5.7
625     */
626    DocumentModel copyProxyAsDocument(DocumentRef src, DocumentRef dst, String name, boolean resetLifeCycle);
627
628    /**
629     * Bulk copyProxyAsDocument. Destination must be a folder document.
630     *
631     * @param src the documents to copy
632     * @param dst the destination folder
633     */
634    List<DocumentModel> copyProxyAsDocument(List<DocumentRef> src, DocumentRef dst);
635
636    /**
637     * Bulk copyProxyAsDocument. Destination must be a folder document.
638     *
639     * @param src the documents to copy
640     * @param dst the destination folder
641     * @param resetLifeCycle the property that flagged whether reset destination document lifecycle or not
642     * @return
643     * @since 5.7
644     */
645    List<DocumentModel> copyProxyAsDocument(List<DocumentRef> src, DocumentRef dst, boolean resetLifeCycle);
646
647    /**
648     * Moves the source document to the destination folder under the given name. If the name is {@code null} or if there
649     * is a collision, a suitable new name is found.
650     * <p>
651     * If the destination document is not a folder or it doesn't exists then throws an exception.
652     *
653     * @param src the source document reference
654     * @param dst the destination folder reference
655     * @param name the new name of the file, or {@code null}
656     */
657    DocumentModel move(DocumentRef src, DocumentRef dst, String name);
658
659    /**
660     * Bulk move. Destination must be a folder document.
661     *
662     * @param src the documents to move
663     * @param dst the destination folder
664     */
665    void move(List<DocumentRef> src, DocumentRef dst);
666
667    /**
668     * Gets the document access control policy.
669     * <p>
670     * The returned ACP is the ACP defined on that document if any + the inherited ACL if any. If neither a local ACP
671     * nor inherited ACL exists null is returned.
672     * <p>
673     * Note that modifying the returned ACP will not affect in any way the stored document ACP. To modify the ACP you
674     * must explicitely set it by calling {@link CoreSession#setACP(DocumentRef, ACP, boolean)}
675     * <p>
676     * This method will always fetch a fresh ACP from the storage. The recommended way to get the ACP is to use
677     * {@link DocumentModel#getACP()} this way the ACP will be cached at the document model level and so you can use it
678     * for multiple permission checks without fetching it each time.
679     *
680     * @param docRef the doc ref to retrieve ACP or null if none
681     * @return the ACP
682     */
683    ACP getACP(DocumentRef docRef);
684
685    /**
686     * Sets the ACP for this document.
687     * <p>
688     * If the ACP contains an <code>INHERITED</code> ACL it will be discarded. Only ACLs relative to the current
689     * document may be changed.
690     * <p>
691     * If the <code>overwrite</code> argument is false, the ACP is merged with the existing one if any. The merge is
692     * done as follow:
693     * <ul>
694     * <li>If any ACL is that already exists on the document ACp is redefined by the new ACO then it will be replaced by
695     * the new one. So if you want to remove an ACl in this mode you need to specify an empty ACL.
696     * <li>If the new ACP contains an ACl that is not defined by the old one the it will be added to the merged ACP.
697     * <li>If the <code>owners</code> are specified then they will replace the existing ones if any. Otherwise the old
698     * owners are preserved if any. As for the ACL if you want to remove existing owners you need to specify an empty
699     * owner array (and not a null one)
700     * </ul>
701     * If the <code>overwrite</code> argument is true, the old ACP will be replaced by the new one.
702     * <p>
703     * This way if you can remove the existing ACP by specifying a null ACP and <code>overwrite</code> argument set to
704     * true.
705     * <p>
706     * Setting a null ACP when <code>overwrite</code> is false will do nothing.
707     *
708     * @param docRef
709     * @param acp
710     * @param overwrite
711     */
712    void setACP(DocumentRef docRef, ACP acp, boolean overwrite);
713
714    /**
715     * Replace the {@code oldACE} with the {@code newACE} on the given {@code aclName}.
716     * <p>
717     *
718     * @since 7.4
719     */
720    void replaceACE(DocumentRef docRef, String aclName, ACE oldACE, ACE newACE);
721
722    /**
723     * Returns {@code true} if negative ACLs are allowed.
724     * <p>
725     * Negative ACLs are ACLs that include an ACE with a deny (isGranted=false). This does not include the full-blocking
726     * ACE for Everyone/Everything, which is always allowed.
727     *
728     * @return {@code true} if negative ACLs are allowed
729     * @since 6.0
730     */
731    boolean isNegativeAclAllowed();
732
733    /*
734     * Support for lazy loading
735     */
736
737    /**
738     * Retrieves a data model given a document reference and a schema.
739     * <p>
740     * For INTERNAL use by the core.
741     *
742     * @since 5.4.2
743     */
744    DataModel getDataModel(DocumentRef docRef, Schema schema);
745
746    // -------- Versioning API ---------------
747
748    /**
749     * Gets the last version of a document.
750     *
751     * @param docRef the reference to the document
752     * @return the version
753     * @deprecated use {@link #getLastDocumentVersion} instead
754     */
755    @Deprecated
756    VersionModel getLastVersion(DocumentRef docRef);
757
758    /**
759     * Gets the document corresponding to the last version for the given document.
760     *
761     * @param docRef the reference to the document
762     * @return the document model corresponding to the version
763     */
764    DocumentModel getLastDocumentVersion(DocumentRef docRef);
765
766    /**
767     * Gets the document reference corresponding to the last version for the given document.
768     *
769     * @param docRef the reference to the document
770     * @return the document reference corresponding to the last version
771     */
772    DocumentRef getLastDocumentVersionRef(DocumentRef docRef);
773
774    /**
775     * Gets the head (live) document for this document.
776     *
777     * @param docRef the reference to the document
778     * @return the version
779     */
780    DocumentModel getSourceDocument(DocumentRef docRef);
781
782    /**
783     * Gets the references of the versions of the document.
784     *
785     * @param docRef the reference to the document
786     * @return a list of version references
787     * @since 1.4.1
788     */
789    List<DocumentRef> getVersionsRefs(DocumentRef docRef);
790
791    /**
792     * Retrieves all the versions for a specified document.
793     *
794     * @param docRef the reference to the document
795     * @return the list of {@link DocumentModel} representing versions, empty list if none is found.
796     */
797    List<DocumentModel> getVersions(DocumentRef docRef);
798
799    /**
800     * Retrieves all the versions for a specified document.
801     *
802     * @param docRef the reference to the document
803     * @return the list of {@link VersionModel} representing versions, empty list if none is found.
804     */
805    List<VersionModel> getVersionsForDocument(DocumentRef docRef);
806
807    /**
808     * Gets a document version, given the versionable id and label.
809     * <p>
810     * The version model contains the label of the version to look for. On return, it is filled with the version's
811     * description and creation date.
812     * <p>
813     * Restricted to administrators.
814     *
815     * @param versionableId the versionable id
816     * @param versionModel the version model holding the label
817     * @return the version, or {@code null} if not found
818     * @deprecated use version ids directly
819     */
820    @Deprecated
821    DocumentModel getVersion(String versionableId, VersionModel versionModel);
822
823    /**
824     * Gets the version label for a document, according to the versioning service.
825     *
826     * @param docModel the document
827     * @return the version label
828     */
829    String getVersionLabel(DocumentModel docModel);
830
831    /**
832     * Returns a document that represents the specified version of the document.
833     *
834     * @param docRef the reference to the document
835     * @param version the version for which we want the corresponding document
836     * @return
837     */
838    DocumentModel getDocumentWithVersion(DocumentRef docRef, VersionModel version);
839
840    /**
841     * Restores the given document to the specified version.
842     *
843     * @param docRef the reference to the document
844     * @param versionRef the reference to the version
845     * @param skipSnapshotCreation {@code true} if the document should not be snapshotted before being restored
846     * @param skipCheckout {@code true} if the restored document should be kept in a checked-in state
847     * @since 5.4
848     */
849    DocumentModel restoreToVersion(DocumentRef docRef, DocumentRef versionRef, boolean skipSnapshotCreation,
850            boolean skipCheckout);
851
852    /**
853     * Restores the given document to the specified version permitting to skip the creation of the snapshot for current
854     * document.
855     *
856     * @param docRef the reference to the document
857     * @param version the version to which the document should be restored to - only the label is used for the moment
858     * @param skipSnapshotCreation indicates if skipping snapshot creation
859     * @deprecated use {@link #restoreToVersion(DocumentRef, DocumentRef, boolean, boolean)} instead
860     */
861    @Deprecated
862    DocumentModel restoreToVersion(DocumentRef docRef, VersionModel version, boolean skipSnapshotCreation);
863
864    /**
865     * Restores the given document to the specified version.
866     *
867     * @param docRef the reference to the document
868     * @param versionRef the reference to the version
869     * @since 5.4
870     */
871    DocumentModel restoreToVersion(DocumentRef docRef, DocumentRef versionRef);
872
873    /**
874     * Restores the given document to the specified version.
875     *
876     * @param docRef the reference to the document
877     * @param version the version to which the document should be restored to - only the label is used for the moment
878     * @deprecated use {@link #restoreToVersion(DocumentRef, DocumentRef)} instead
879     */
880    @Deprecated
881    DocumentModel restoreToVersion(DocumentRef docRef, VersionModel version);
882
883    /**
884     * Gets the version to which a checked in document is linked.
885     * <p>
886     * Returns {@code null} for a checked out document or a version or a proxy.
887     *
888     * @return the version, or {@code null}
889     */
890    DocumentRef getBaseVersion(DocumentRef docRef);
891
892    /**
893     * Checks out a versioned document.
894     *
895     * @param docRef the reference to the document
896     */
897    void checkOut(DocumentRef docRef);
898
899    /**
900     * Checks in a modified document, creating a new version.
901     *
902     * @param docRef the reference to the document
903     * @param version the version descriptor
904     * @return the version document just created
905     * @deprecated use {@link #checkIn(DocumentRef, VersioningOption, String)} instead
906     */
907    @Deprecated
908    DocumentModel checkIn(DocumentRef docRef, VersionModel version);
909
910    /**
911     * Checks in a modified document, creating a new version.
912     *
913     * @param docRef the reference to the document
914     * @param option whether to do create a new {@link VersioningOption#MINOR} or {@link VersioningOption#MAJOR} version
915     *            during check in
916     * @param checkinComment the checkin comment
917     * @return the version just created
918     * @since 5.4
919     */
920    DocumentRef checkIn(DocumentRef docRef, VersioningOption option, String checkinComment);
921
922    /**
923     * Returns whether the current document is checked-out or not.
924     *
925     * @param docRef the reference to the document
926     * @return
927     */
928    boolean isCheckedOut(DocumentRef docRef);
929
930    /**
931     * Gets the version series id for a document.
932     * <p>
933     * All documents and versions derived by a check in or checkout from the same original document share the same
934     * version series id.
935     *
936     * @param docRef the document reference
937     * @return the version series id
938     * @since 5.4
939     */
940    String getVersionSeriesId(DocumentRef docRef);
941
942    /**
943     * Gets the working copy (live document) for a proxy or a version.
944     *
945     * @param docRef the document reference
946     * @return the working copy, or {@code null} if not found
947     * @since 5.4
948     */
949    DocumentModel getWorkingCopy(DocumentRef docRef);
950
951    /**
952     * Creates a generic proxy to the given document inside the given folder.
953     * <p>
954     * The document may be a version, or a working copy (live document) in which case the proxy will be a "shortcut".
955     *
956     * @since 1.6.1 (5.3.1)
957     */
958    DocumentModel createProxy(DocumentRef docRef, DocumentRef folderRef);
959
960    /** -------------------------- Query API --------------------------- * */
961
962    /**
963     * Executes the given NXQL query an returns the result.
964     *
965     * @param query the query to execute
966     * @return the query result
967     */
968    DocumentModelList query(String query);
969
970    /**
971     * Executes the given NXQL query an returns the result.
972     *
973     * @param query the query to execute
974     * @param max number of document to retrieve
975     * @return the query result
976     */
977    DocumentModelList query(String query, int max);
978
979    /**
980     * Executes the given NXQL query and returns the result that matches the filter.
981     *
982     * @param query the query to execute
983     * @param filter the filter to apply to result
984     * @return the query result
985     */
986    DocumentModelList query(String query, Filter filter);
987
988    /**
989     * Executes the given NXQL query and returns the result that matches the filter.
990     *
991     * @param query the query to execute
992     * @param filter the filter to apply to result
993     * @param max number of document to retrieve
994     * @return the query result
995     */
996    DocumentModelList query(String query, Filter filter, int max);
997
998    /**
999     * Executes the given NXQL query and returns the result that matches the filter.
1000     *
1001     * @param query the query to execute
1002     * @param filter the filter to apply to result
1003     * @param limit the maximum number of documents to retrieve, or 0 for all of them
1004     * @param offset the offset (starting at 0) into the list of documents
1005     * @param countTotal if {@code true}, return a {@link DocumentModelList} that includes a total size of the
1006     *            underlying list (size if there was no limit or offset)
1007     * @return the query result
1008     */
1009    DocumentModelList query(String query, Filter filter, long limit, long offset, boolean countTotal);
1010
1011    /**
1012     * Executes the given NXQL query and returns the result that matches the filter.
1013     *
1014     * @param query the query to execute
1015     * @param filter the filter to apply to result
1016     * @param limit the maximum number of documents to retrieve, or 0 for all of them
1017     * @param offset the offset (starting at 0) into the list of documents
1018     * @param countUpTo if {@code -1}, count the total size without offset/limit.<br>
1019     *            If {@code 0}, don't count the total size.<br>
1020     *            If {@code n}, count the total number if there are less than n documents otherwise set the size to
1021     *            {@code -1}.
1022     * @return the query result
1023     * @Since 5.6
1024     */
1025    DocumentModelList query(String query, Filter filter, long limit, long offset, long countUpTo);
1026
1027    /**
1028     * Executes the given query and returns the result that matches the filter.
1029     *
1030     * @param query the query to execute
1031     * @param queryType the query type, like "NXQL"
1032     * @param filter the filter to apply to result
1033     * @param limit the maximum number of documents to retrieve, or 0 for all of them
1034     * @param offset the offset (starting at 0) into the list of documents
1035     * @param countTotal if {@code true}, return a {@link DocumentModelList} that includes a total size of the
1036     *            underlying list (size if there was no limit or offset)
1037     * @return the query result
1038     * @since 5.5
1039     */
1040    DocumentModelList query(String query, String queryType, Filter filter, long limit, long offset, boolean countTotal);
1041
1042    /**
1043     * Executes the given query and returns the result that matches the filter.
1044     *
1045     * @param query the query to execute
1046     * @param queryType the query type, like "NXQL"
1047     * @param filter the filter to apply to result
1048     * @param limit the maximum number of documents to retrieve, or 0 for all of them
1049     * @param offset the offset (starting at 0) into the list of documents
1050     * @param countUpTo if {@code -1}, return a {@link DocumentModelList} that includes a total size of the underlying
1051     *            list (size if there was no limit or offset). <br>
1052     *            If {@code 0}, don't return the total size of the underlying list. <br>
1053     *            If {@code n}, return the total size of the underlying list when the size is smaller than {@code n}
1054     *            else return a total size of {@code -1}.
1055     * @return the query result
1056     * @since 5.6
1057     */
1058    DocumentModelList query(String query, String queryType, Filter filter, long limit, long offset, long countUpTo);
1059
1060    /**
1061     */
1062    IterableQueryResult queryAndFetch(String query, String queryType, Object... params);
1063
1064    /** -------------------------- Security API --------------------------- * */
1065
1066    /**
1067     * Retrieves the available security permissions existing in the system.
1068     * <p>
1069     *
1070     * @return a raw list of permission names, either basic or group names
1071     */
1072    // TODO: (Hardcoded at the moment. In the future wil get data from
1073    // LDAP/database.)
1074    List<String> getAvailableSecurityPermissions();
1075
1076    /**
1077     * Returns the life cycle of the document.
1078     *
1079     * @see org.nuxeo.ecm.core.lifecycle
1080     * @param docRef the document reference
1081     * @return the life cycle as a string
1082     */
1083    String getCurrentLifeCycleState(DocumentRef docRef);
1084
1085    /**
1086     * Returns the life cycle policy of the document.
1087     *
1088     * @see org.nuxeo.ecm.core.lifecycle
1089     * @param docRef the document reference
1090     * @return the life cycle policy
1091     */
1092    String getLifeCyclePolicy(DocumentRef docRef);
1093
1094    /**
1095     * Follows a given life cycle transition.
1096     * <p>
1097     * This will update the current life cycle of the document.
1098     *
1099     * @param docRef the document reference
1100     * @param transition the name of the transition to follow
1101     * @return a boolean representing the status if the operation
1102     * @throws LifeCycleException if the transition cannot be followed
1103     */
1104    boolean followTransition(DocumentRef docRef, String transition) throws LifeCycleException;
1105
1106    /**
1107     * Follows a given life cycle transition.
1108     * <p>
1109     * This will update the current life cycle of the document.
1110     *
1111     * @param doc the document model
1112     * @param transition the name of the transition to follow
1113     * @return a boolean representing the status if the operation
1114     * @throws LifeCycleException if the transition cannot be followed
1115     */
1116    boolean followTransition(DocumentModel doc, String transition) throws LifeCycleException;
1117
1118    /**
1119     * Gets the allowed state transitions for this document.
1120     *
1121     * @param docRef the document reference
1122     * @return a collection of state transitions as string
1123     */
1124    Collection<String> getAllowedStateTransitions(DocumentRef docRef);
1125
1126    /**
1127     * Reinitializes the life cycle state of the document to its default state.
1128     *
1129     * @param docRef the document
1130     * @since 5.4.2
1131     */
1132    void reinitLifeCycleState(DocumentRef docRef);
1133
1134    /**
1135     * Retrieves the given field value from the given schema for all the given documents.
1136     *
1137     * @param docRefs the document references
1138     * @param schema the schema
1139     * @param field the field name
1140     * @return the field values in the same order as the given docRefs
1141     */
1142    Object[] getDataModelsField(DocumentRef[] docRefs, String schema, String field);
1143
1144    /**
1145     * Creates an array with all parent refs starting from the given document up to the root. So the return value will
1146     * have [0] = parent ref; [1] = parent parent ref... etc.
1147     *
1148     * @param docRef
1149     * @return an array with ancestor documents ref
1150     */
1151    DocumentRef[] getParentDocumentRefs(DocumentRef docRef);
1152
1153    /**
1154     * Retrieves the given field value from the given schema for the given document along with all its parent documents.
1155     *
1156     * @param docRef the document reference
1157     * @param schema the schema
1158     * @param field the field name
1159     * @return an array with field values of all documents on the path from the given document to the root
1160     */
1161    Object[] getDataModelsFieldUp(DocumentRef docRef, String schema, String field);
1162
1163    /**
1164     * Gets the lock key on the given document if a lock exists or null otherwise.
1165     * <p>
1166     * A lock key has the form {@code someuser:Nov 29, 2010}.
1167     *
1168     * @param doc the document reference
1169     * @return the lock key if the document is locked, null otherwise
1170     * @deprecated since 5.4.2, use {@link #getLockInfo} instead
1171     */
1172    @Deprecated
1173    String getLock(DocumentRef doc);
1174
1175    /**
1176     * Sets a lock on the given document using the given key.
1177     * <p>
1178     * A lock key must have the form {@code someuser:Nov 29, 2010}.
1179     *
1180     * @param doc the document reference
1181     * @param key the lock key
1182     * @throws LockException if the document is already locked
1183     * @deprecated since 5.4.2, use {@link #setLock(DocumentRef)} instead
1184     */
1185    @Deprecated
1186    void setLock(DocumentRef doc, String key) throws LockException;
1187
1188    /**
1189     * Removes the lock if one exists.
1190     * <p>
1191     * The caller principal should be the same as the one who set the lock or to belongs to the administrator group,
1192     * otherwise an exception will be throw.
1193     * <p>
1194     * If the document was not locked, does nothing.
1195     *
1196     * @param docRef the document to unlock
1197     * @return the lock key that was removed
1198     * @deprecated since 5.4.2, use {@link #removeLock} instead
1199     */
1200    @Deprecated
1201    String unlock(DocumentRef docRef);
1202
1203    /**
1204     * Sets a lock on the given document.
1205     *
1206     * @param doc the document reference
1207     * @return the lock info that was set
1208     * @throws LockException if the document is already locked
1209     * @since 5.4.2
1210     */
1211    Lock setLock(DocumentRef docRef) throws LockException;
1212
1213    /**
1214     * Gets the lock info on the given document.
1215     * <p>
1216     * Lock info is never cached, and needs to use a separate transaction in a separate thread, so care should be taken
1217     * to not call this method needlessly.
1218     *
1219     * @param doc the document reference
1220     * @return the lock info if the document is locked, or {@code null} otherwise
1221     * @since 5.4.2
1222     */
1223    Lock getLockInfo(DocumentRef docRef);
1224
1225    /**
1226     * Removes the lock on the given document.
1227     * <p>
1228     * The caller principal should be the same as the one who set the lock or to belongs to the administrator group,
1229     * otherwise an exception will be throw.
1230     * <p>
1231     * If the document was not locked, does nothing.
1232     * <p>
1233     * Returns the previous lock info.
1234     *
1235     * @param docRef the document to unlock
1236     * @return the removed lock info, or {@code null} if there was no lock
1237     * @since 5.4.2
1238     * @throws LockException if the document is locked by someone else
1239     */
1240    Lock removeLock(DocumentRef docRef) throws LockException;
1241
1242    /**
1243     * Applies default Read permissions on root JCR Document for the given user or group name. It can only be called by
1244     * Administrators.
1245     * <p>
1246     * Usage: As an administrator, you may want to add new users or groups. This method needs to be called to grand
1247     * default reading permissions on the root document of the repository for the newly created users/groups.
1248     *
1249     * @param userOrGroupName
1250     */
1251    void applyDefaultPermissions(String userOrGroupName);
1252
1253    /**
1254     * Checks if the given document is dirty.
1255     *
1256     * @param doc the doc reference
1257     * @return true if dirty false otherwise
1258     * @deprecated since 5.4, use {@link #isCheckedOut} instead
1259     */
1260    @Deprecated
1261    boolean isDirty(DocumentRef doc);
1262
1263    /**
1264     * Publishes the document in a section overwriting any existing proxy to the same document. This is simmilar to
1265     * publishDocument(docToPublish, section, true);
1266     *
1267     * @param docToPublish
1268     * @param section
1269     * @return The proxy document that was created
1270     * @since 1.4.1 for the case where docToPublish is a proxy
1271     */
1272    DocumentModel publishDocument(DocumentModel docToPublish, DocumentModel section);
1273
1274    /**
1275     * Publishes the document in a section.
1276     *
1277     * @param docToPublish
1278     * @param section
1279     * @param overwriteExistingProxy
1280     * @return The proxy document that was created
1281     */
1282    DocumentModel publishDocument(DocumentModel docToPublish, DocumentModel section, boolean overwriteExistingProxy);
1283
1284    /**
1285     * Finds the proxies for a document. If the parent is not null, the search will be limited to its direct children.
1286     * <p>
1287     * If the document is a version, then only proxies to that version will be looked up.
1288     * <p>
1289     * If the document is a proxy, then all similar proxies (pointing to any version of the same versionable) are
1290     * retrieved.
1291     *
1292     * @param docRef the target document for the proxies
1293     * @param folderRef the folder where proxies are located or {@code null}
1294     * @return the list of the proxies. An empty list is returned if no proxy are found
1295     * @since 1.4.1 for the case where docRef is a proxy
1296     */
1297    DocumentModelList getProxies(DocumentRef docRef, DocumentRef folderRef);
1298
1299    /**
1300     * Gets all proxy versions to document docRef inside folder folderRef.
1301     * <p>
1302     * Intended to be used by UI clients to display information about proxies in sections.
1303     *
1304     * @param docRef the target document for the proxies
1305     * @param folderRef the folder where proxies are located
1306     * @return an array of the proxy versions, with an empty string being used for a live proxy. {@code null} is
1307     *         returned if no proxies are found the specified folder
1308     * @deprecated since 5.4, use {@link #getProxies} instead
1309     */
1310    @Deprecated
1311    String[] getProxyVersions(DocumentRef docRef, DocumentRef folderRef);
1312
1313    /**
1314     * Returns the type of his parent SuperSpace (workspace, section, etc.). SuperSpace is qualified by the SuperSpace
1315     * facet.
1316     *
1317     * @param doc
1318     * @return
1319     */
1320    String getSuperParentType(DocumentModel doc);
1321
1322    /**
1323     * Returns the parent SuperSpace (workspace, section, etc.). SuperSpace is qualified by the SuperSpace facet.
1324     *
1325     * @param doc
1326     * @return DocumentModel of SuperSpace
1327     */
1328    DocumentModel getSuperSpace(DocumentModel doc);
1329
1330    /**
1331     * Returns the repository name against which this core session is bound.
1332     *
1333     * @return the repository name used currently used as an identifier
1334     */
1335    String getRepositoryName();
1336
1337    /**
1338     * Gets system property of the specified type for the document ref.
1339     *
1340     * @param <T>
1341     * @param ref
1342     * @param systemProperty
1343     * @param type
1344     * @return
1345     */
1346    <T extends Serializable> T getDocumentSystemProp(DocumentRef ref, String systemProperty, Class<T> type);
1347
1348    /**
1349     * Sets given value as a system property.
1350     *
1351     * @param <T>
1352     * @param ref
1353     * @param systemProperty
1354     * @param value
1355     */
1356    <T extends Serializable> void setDocumentSystemProp(DocumentRef ref, String systemProperty, T value);
1357
1358    /**
1359     * Given a parent document, order the source child before the destination child. The source and destination must be
1360     * name of child documents of the given parent document. (a document name can be retrieved using
1361     * <code>docModel.getName()</code>) To place the source document at the end of the children list use a null
1362     * destination node.
1363     *
1364     * @param parent the parent document
1365     * @param src the document to be moved (ordered)
1366     * @param dest the document before which the reordered document will be placed If null the source document will be
1367     *            placed at the end of the children list
1368     */
1369    void orderBefore(DocumentRef parent, String src, String dest);
1370
1371    /**
1372     * Internal method - it is used internally by {@link DocumentModel#refresh()}
1373     * <p>
1374     * Get fresh data from a document given a description of what kind of data should be refetched.
1375     * <p>
1376     * The refresh information is specified using a bit mask. See {@link DocumentModel} for all accepted flags.
1377     * <p>
1378     * When the flag {@link DocumentModel#REFRESH_CONTENT_IF_LOADED} is specified a third argument must be passed
1379     * representing the schema names for document parts to refresh. This argument is ignored if the flag is not
1380     * specified or no schema names are provided
1381     *
1382     * @param ref the document reference
1383     * @param refreshFlags refresh flags as defined in {@link DocumentModel}
1384     * @param schemas the schema names if a partial content refresh is required
1385     * @return a DocumentModelRefresh object
1386     */
1387    DocumentModelRefresh refreshDocument(DocumentRef ref, int refreshFlags, String[] schemas);
1388
1389    /**
1390     * Provides the full list of all permissions or groups of permissions that contain the given one (inclusive). It
1391     * makes the method {@link org.nuxeo.ecm.core.security.SecurityService#getPermissionsToCheck} available remote.
1392     *
1393     * @param permission
1394     * @return the list, as an array of strings.
1395     */
1396    String[] getPermissionsToCheck(String permission);
1397
1398    /**
1399     * Find the first parent with the given {@code facet} and adapt it on the {@code adapterClass}.
1400     * <p>
1401     * This method does not check the permissions on the document to be adapted of this {@code CoreSession}'s
1402     * {@code Principal}, and so the adapter must not need other schemas from the {@code DocumentModel} except the
1403     * schemas related to the given facet.
1404     *
1405     * @return the first parent with the given {@code facet} adapted, or {@code null} if no parent found or the document
1406     *         does not support the given {@code adapterClass}.
1407     * @since 5.4.2
1408     */
1409    <T extends DetachedAdapter> T adaptFirstMatchingDocumentWithFacet(DocumentRef docRef, String facet,
1410            Class<T> adapterClass);
1411
1412    /**
1413     * Gets the fulltext extracted from the binary fields.
1414     *
1415     * @param doc the document reference
1416     * @return the fulltext map or {@code null} if not supported.
1417     * @since 5.9.3
1418     */
1419    Map<String, String> getBinaryFulltext(DocumentRef ref);
1420
1421}