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