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