001/*
002 * (C) Copyright 2006-2018 Nuxeo (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 */
020package org.nuxeo.ecm.core.api;
021
022import java.io.Serializable;
023import java.util.Collection;
024import java.util.Map;
025import java.util.Set;
026
027import org.nuxeo.common.utils.Path;
028import org.nuxeo.ecm.core.api.model.DocumentPart;
029import org.nuxeo.ecm.core.api.model.Property;
030import org.nuxeo.ecm.core.api.model.PropertyVisitor;
031import org.nuxeo.ecm.core.api.model.resolver.PropertyObjectResolver;
032import org.nuxeo.ecm.core.api.security.ACP;
033import org.nuxeo.ecm.core.schema.DocumentType;
034
035/**
036 * The document model is a serializable representation of a core document.
037 * <p>
038 * The document model is made from several data models, each data model is bound to a schema. All the information about
039 * a document (like security) is expressed using schemas (and implicitly data models).
040 * <p>
041 * Data models are lazily loaded as they are needed. At document model creation only data models corresponding to the
042 * default schemas are loaded. The default schemas are configured in the type manager through extension points.
043 *
044 * @see CoreSession
045 */
046public interface DocumentModel extends Serializable {
047
048    int REFRESH_STATE = 1; // "small" state (life cycle, lock, versioning)
049
050    /** @deprecated since 10.1, has no effect. */
051    @Deprecated
052    int REFRESH_PREFETCH = 4;
053
054    int REFRESH_ACP_IF_LOADED = 8; // refresh now only if already loaded
055
056    int REFRESH_ACP_LAZY = 16; // refresh later in lazy mode
057
058    int REFRESH_ACP = 32; // refresh now
059
060    int REFRESH_CONTENT_IF_LOADED = 64; // refresh now only if already loaded
061
062    int REFRESH_CONTENT_LAZY = 128; // refresh later in lazy mode
063
064    int REFRESH_CONTENT = 256; // refresh now
065
066    int REFRESH_IF_LOADED = REFRESH_STATE | REFRESH_ACP_IF_LOADED | REFRESH_CONTENT_IF_LOADED;
067
068    int REFRESH_LAZY = REFRESH_STATE | REFRESH_ACP_LAZY | REFRESH_CONTENT_LAZY;
069
070    int REFRESH_ALL = REFRESH_STATE | REFRESH_ACP | REFRESH_CONTENT;
071
072    int REFRESH_DEFAULT = REFRESH_STATE | REFRESH_ACP_IF_LOADED | REFRESH_CONTENT_LAZY;
073
074    /**
075     * Gets the document type object.
076     *
077     * @return the document type object
078     */
079    DocumentType getDocumentType();
080
081    /**
082     * Retrieves the session id corresponding to this object.
083     * <p>
084     * This method should rarely be used, use {@link #getCoreSession} directly instead.
085     * <p>
086     * Using the session id you can retrieve the core session that created the object.
087     * <p>
088     * Document models created by the user on the client side are not bound to any session. They are simple DTO used to
089     * transport data.
090     *
091     * @return the session id the session ID for server side created doc models or null for client side models (used for
092     *         data transportation)
093     */
094    String getSessionId();
095
096    /**
097     * Gets the core session to which this document is tied.
098     * <p>
099     * This may be null if the document has been detached from a session.
100     *
101     * @return the core session
102     * @since 5.2.GA
103     */
104    CoreSession getCoreSession();
105
106    /**
107     * Detaches the documentImpl from its existing session, so that it can survive beyond the session's closing.
108     *
109     * @param loadAll if {@code true}, load all data and ACP from the session before detaching
110     * @since 5.6
111     */
112    void detach(boolean loadAll);
113
114    /**
115     * Reattaches a document impl to an existing session.
116     *
117     * @param sid the session id
118     * @since 5.6
119     */
120    void attach(String sid);
121
122    /**
123     * Gets a reference to the core document that can be used either remotely or locally (opens the core JVM).
124     *
125     * @return the document reference
126     */
127    DocumentRef getRef();
128
129    /**
130     * Retrieves the parent reference of the current document.
131     *
132     * @return the parent reference or null if no parent
133     */
134    DocumentRef getParentRef();
135
136    /**
137     * Gets the document UUID.
138     *
139     * @return the document UUID
140     */
141    String getId();
142
143    /**
144     * Gets the document name.
145     *
146     * @return the document name
147     */
148    String getName();
149
150    /**
151     * Gets the document's position in its containing folder (if ordered).
152     *
153     * @return the position, or {@code null} if the containing folder is not ordered
154     * @since 6.0
155     */
156    Long getPos();
157
158    /**
159     * Get a text suitable to be shown in a UI for this document.
160     *
161     * @return the title or the internal name if no title could be found
162     */
163    String getTitle();
164
165    /**
166     * Gets the document path as a string.
167     *
168     * @return the document path as string
169     */
170    String getPathAsString();
171
172    /**
173     * Gets the document path.
174     *
175     * @return the document path as string
176     */
177    Path getPath();
178
179    /**
180     * Gets the document type name.
181     *
182     * @return the document type name
183     */
184    String getType();
185
186    /**
187     * Gets the schemas available on this document (from the type and the facets).
188     *
189     * @return the schemas
190     * @since 5.4.2
191     */
192    String[] getSchemas();
193
194    /**
195     * Checks if the document has the given schema, either from its type or added on the instance through a facet.
196     *
197     * @param schema the schema name
198     * @return {@code true} if the document has the schema
199     */
200    boolean hasSchema(String schema);
201
202    /**
203     * Gets the facets available on this document (from the type and the instance facets).
204     *
205     * @return the facets
206     * @since 5.4.2
207     */
208    Set<String> getFacets();
209
210    /**
211     * Checks if the document has a facet, either from its type or added on the instance.
212     *
213     * @param facet the facet name
214     * @return {@code true} if the document has the facet
215     */
216    boolean hasFacet(String facet);
217
218    /**
219     * Adds a facet to the document instance.
220     * <p>
221     * Does nothing if the facet was already present on the document.
222     *
223     * @param facet the facet name
224     * @return {@code true} if the facet was added, or {@code false} if it is already present
225     * @throws IllegalArgumentException if the facet does not exist
226     * @since 5.4.2
227     */
228    boolean addFacet(String facet);
229
230    /**
231     * Removes a facet from the document instance.
232     * <p>
233     * It's not possible to remove a facet coming from the document type.
234     *
235     * @param facet the facet name
236     * @return {@code true} if the facet was removed, or {@code false} if it isn't present or is present on the type or
237     *         does not exit
238     * @since 5.4.2
239     */
240    boolean removeFacet(String facet);
241
242    /**
243     * INTERNAL, not for public use.
244     * <p>
245     * Gets a list with the currently fetched data models.
246     *
247     * @return the data models that are already fetched as a collection
248     * @deprecated since 8.4, internal method
249     * @see #getSchemas
250     * @see #getProperties
251     * @see #getPropertyObject
252     * @see #getPropertyObjects
253     */
254    @Deprecated
255    Collection<DataModel> getDataModelsCollection();
256
257    /**
258     * Gets the data models.
259     *
260     * @return the data models that are already fetched.
261     * @deprecated since 8.4, use direct {@link Property} getters instead
262     * @see #getSchemas
263     * @see #getProperties
264     * @see #getPropertyObject
265     * @see #getPropertyObjects
266     */
267    @Deprecated
268    Map<String, DataModel> getDataModels();
269
270    /**
271     * Gets the data model corresponding to the given schema.
272     * <p>
273     * Null is returned if the document type has no such schema.
274     *
275     * @param schema the schema name
276     * @return the data model or null if no such schema is supported
277     * @deprecated since 8.4, use direct {@link Property} getters instead
278     * @see #getSchemas
279     * @see #getProperties
280     * @see #getPropertyObject
281     * @see #getPropertyObjects
282     */
283    @Deprecated
284    DataModel getDataModel(String schema);
285
286    /**
287     * Sets path info.
288     * <p>
289     * path and ref attributes will be set according to info
290     */
291    void setPathInfo(String parentPath, String name);
292
293    /**
294     * Tests if the document is locked.
295     * <p>
296     * Lock info is cached on the document for performance. Use {@link CoreSession#getLockInfo} to get the non-cached
297     * status.
298     *
299     * @return the lock key if the document is locked or null otherwise
300     */
301    boolean isLocked();
302
303    /**
304     * Sets a lock on the document.
305     *
306     * @return the lock info that was set
307     * @throws LockException if the document is already locked
308     * @since 5.4.2
309     */
310    Lock setLock() throws LockException;
311
312    /**
313     * Gets the lock info on the document.
314     * <p>
315     * Lock info is cached on the document for performance. Use {@link CoreSession#getLockInfo} to get the non-cached
316     * status.
317     *
318     * @return the lock info if the document is locked, or {@code null} otherwise
319     * @since 5.4.2
320     */
321    Lock getLockInfo();
322
323    /**
324     * Removes the lock on the document.
325     * <p>
326     * The caller principal should be the same as the one who set the lock or to belongs to the administrator group,
327     * otherwise an exception will be throw.
328     * <p>
329     * If the document was not locked, does nothing.
330     * <p>
331     * Returns the previous lock info.
332     *
333     * @return the removed lock info, or {@code null} if there was no lock
334     * @throws LockException if the document is locked by someone else
335     * @since 5.4.2
336     */
337    Lock removeLock() throws LockException;
338
339    /**
340     * Tests if the document is checked out.
341     * <p>
342     * A checked out document can be modified normally. A checked in document is identical to the last version that it
343     * created, and not modifiable.
344     * <p>
345     * Only applicable to documents that are live (not versions and not proxies).
346     *
347     * @return {@code true} if the document is checked out, {@code false} if it is checked in
348     * @since 5.4
349     */
350    boolean isCheckedOut();
351
352    /**
353     * Checks out a document.
354     * <p>
355     * A checked out document can be modified normally.
356     * <p>
357     * Only applicable to documents that are live (not versions and not proxies).
358     *
359     * @since 5.4
360     */
361    void checkOut();
362
363    /**
364     * Checks in a document and returns the created version.
365     * <p>
366     * A checked in document is identical to the last version that it created, and not modifiable.
367     * <p>
368     * Only applicable to documents that are live (not versions and not proxies).
369     *
370     * @param option whether to do create a new {@link VersioningOption#MINOR} or {@link VersioningOption#MAJOR} version
371     *            during check in
372     * @param checkinComment the checkin comment
373     * @return the version just created
374     * @since 5.4
375     */
376    DocumentRef checkIn(VersioningOption option, String checkinComment);
377
378    /**
379     * Returns the version label.
380     * <p>
381     * The label returned is computed by the VersioningService.
382     *
383     * @return the version label, or {@code null}
384     */
385    String getVersionLabel();
386
387    /**
388     * Returns the checkin comment if the document model is a version.
389     *
390     * @return the checkin comment, or {@code null}
391     * @since 5.4
392     */
393    String getCheckinComment();
394
395    /**
396     * Gets the version series id for this document.
397     * <p>
398     * All documents and versions derived by a check in or checkout from the same original document share the same
399     * version series id.
400     *
401     * @return the version series id
402     * @since 5.4
403     */
404    String getVersionSeriesId();
405
406    /**
407     * Checks if a document is the latest version in the version series.
408     *
409     * @since 5.4
410     */
411    boolean isLatestVersion();
412
413    /**
414     * Checks if a document is a major version.
415     *
416     * @since 5.4
417     */
418    boolean isMajorVersion();
419
420    /**
421     * Checks if a document is the latest major version in the version series.
422     *
423     * @since 5.4
424     */
425    boolean isLatestMajorVersion();
426
427    /**
428     * Checks if there is a checked out working copy for the version series of this document.
429     *
430     * @since 5.4
431     */
432    boolean isVersionSeriesCheckedOut();
433
434    /**
435     * Gets the access control policy (ACP) for this document.
436     * <p>
437     * Returns null if no security was defined on this document.
438     * <p>
439     * The ACP can be used to introspect or to evaluate user privileges on this document.
440     * <p>
441     * This is a wrapper for {@link CoreSession#getACP(DocumentRef)} but it is recommended since it caches the ACP for
442     * later usage.
443     *
444     * @return the security data model or null if none
445     */
446    ACP getACP();
447
448    /**
449     * Sets the ACP for this document model.
450     * <p>
451     * This is a wrapper for {@link CoreSession#setACP(DocumentRef, ACP, boolean)}
452     *
453     * @see CoreSession#setACP(DocumentRef, ACP, boolean)
454     * @param acp the ACP to set
455     * @param overwrite whether to overwrite the old ACP or not
456     */
457    void setACP(ACP acp, boolean overwrite);
458
459    /**
460     * Gets a property from the given schema.
461     * <p>
462     * The data model owning the property will be fetched from the server if not already fetched.
463     *
464     * @param schemaName the schema name
465     * @param name the property name
466     * @return the property value or null if no such property exists
467     */
468    Object getProperty(String schemaName, String name);
469
470    /**
471     * Gets a property object from the given schema.
472     *
473     * @param schema the schema name
474     * @param name the property name
475     * @return the property, or {@code null} if no such property exists
476     * @since 8.4
477     */
478    Property getPropertyObject(String schema, String name);
479
480    /**
481     * Sets the property value from the given schema.
482     * <p>
483     * This operation will not fetch the data model if not already fetched
484     *
485     * @param schemaName the schema name
486     * @param name the property name
487     * @param value the property value
488     */
489    void setProperty(String schemaName, String name, Object value);
490
491    /**
492     * Gets the values from the given data model as a map.
493     * <p>
494     * The operation will fetch the data model from the server if not already fetched.
495     *
496     * @param schemaName the data model schema name
497     * @return the values map
498     */
499    Map<String, Object> getProperties(String schemaName);
500
501    /**
502     * Sets values for the given data model.
503     * <p>
504     * This will not fetch the data model if not already fetched.
505     *
506     * @param schemaName the schema name
507     * @param data the values to set
508     */
509    void setProperties(String schemaName, Map<String, Object> data);
510
511    /**
512     * Checks if this document is in the trash.
513     *
514     * @return true if the document is in the trash, false otherwise.
515     * @since 10.1
516     */
517    boolean isTrashed();
518
519    /**
520     * Checks if this document is a folder.
521     *
522     * @return true if the document is a folder, false otherwise
523     */
524    boolean isFolder();
525
526    /**
527     * Checks if this document can have versions.
528     *
529     * @return true if the document can have versions, false otherwise
530     */
531    boolean isVersionable();
532
533    /**
534     * Checks if this document can be downloaded.
535     *
536     * @return true if the document has downloadable content, false otherwise
537     */
538    boolean isDownloadable();
539
540    /**
541     * Checks if this document is a version.
542     *
543     * @return true if the document is an older version of another document, false otherwise
544     */
545    boolean isVersion();
546
547    /**
548     * Checks if this document is a proxy.
549     *
550     * @return true if the document is a proxy false otherwise
551     */
552    boolean isProxy();
553
554    /**
555     * Checks if this document is immutable.
556     *
557     * @return {@code true} if the document is a version or a proxy to a version, {@code false} otherwise
558     * @since 1.6.1 (5.3.1)
559     */
560    boolean isImmutable();
561
562    /**
563     * Checks if the document has actual data to write (dirty parts).
564     *
565     * @since 5.5
566     */
567    boolean isDirty();
568
569    /**
570     * Method that implement the visitor pattern.
571     * <p>
572     * The visitor must return null to stop visiting children otherwise a context object that will be passed as the arg
573     * argument to children
574     *
575     * @param visitor the visitor to accept
576     * @param arg an argument passed to the visitor. This should be used by the visitor to carry on the visiting
577     *            context.
578     * @since 5.5
579     */
580    void accept(PropertyVisitor visitor, Object arg);
581
582    /**
583     * Adapts the document to the given interface.
584     * <p>
585     * Attention, the first computation will cache the adaptation result for later calls.
586     * </p>
587     *
588     * @param <T> the interface type to adapt to
589     * @param itf the interface class
590     * @return the adapted document
591     */
592    <T> T getAdapter(Class<T> itf);
593
594    /**
595     * Adapts the document to the given interface.
596     *
597     * @param <T> the interface type to adapt to
598     * @param itf the interface class
599     * @param refreshCache : readapt and stores in cache if already exists.
600     * @return the adapted document
601     */
602    <T> T getAdapter(Class<T> itf, boolean refreshCache);
603
604    /**
605     * Returns the life cycle of the document.
606     *
607     * @see org.nuxeo.ecm.core.lifecycle
608     * @return the life cycle as a string
609     */
610    String getCurrentLifeCycleState();
611
612    /**
613     * Returns the life cycle policy of the document.
614     *
615     * @see org.nuxeo.ecm.core.lifecycle
616     * @return the life cycle policy
617     */
618    String getLifeCyclePolicy();
619
620    /**
621     * Follows a given life cycle transition.
622     * <p>
623     * This will update the current life cycle of the document.
624     *
625     * @param transition the name of the transition to follow
626     * @return a boolean representing the status if the operation
627     */
628    boolean followTransition(String transition);
629
630    /**
631     * Gets the allowed state transitions for this document.
632     *
633     * @return a collection of state transitions as string
634     */
635    Collection<String> getAllowedStateTransitions();
636
637    /**
638     * Gets the context data associated to this document.
639     *
640     * @return a map of context data
641     */
642    Map<String, Serializable> getContextData();
643
644    /**
645     * Gets the context data using the default scope.
646     *
647     * @param key the context data key
648     * @return the value
649     */
650    Serializable getContextData(String key);
651
652    /**
653     * Sets a context data in the default scope.
654     *
655     * @param key the context data key
656     * @param value the value
657     */
658    void putContextData(String key, Serializable value);
659
660    /**
661     * Copies the context data from given document to this document.
662     */
663    void copyContextData(DocumentModel otherDocument);
664
665    /**
666     * Copies all the data from a source document.
667     */
668    void copyContent(DocumentModel sourceDoc);
669
670    /**
671     * Returns the name of the repository in which the document is stored.
672     *
673     * @return the repository name as a string.
674     */
675    String getRepositoryName();
676
677    /**
678     * Returns a cache key.
679     * <p>
680     * Cache key will be computed like this : <code>
681     *     docUUID + "-" + sessionId + "-" + timestamp
682     *   </code>
683     * <p>
684     * We will use the last modification time if present for the timestamp.
685     * <p>
686     * Since 5.6, the timestamp does not hold milliseconds anymore as some databases do not store them, which could
687     * interfere with cache key comparisons.
688     *
689     * @return the cache key as a string
690     */
691    String getCacheKey();
692
693    /**
694     * Returns the source document identifier.
695     * <p>
696     * This is useful when not interested about the repository UUID itself. Technically, this is the current version
697     * UUID.
698     *
699     * @return the source id as a string.
700     */
701    String getSourceId();
702
703    /**
704     * Checks if a property is prefetched.
705     *
706     * @param xpath the property xpath
707     * @return {@code true} if it is prefetched
708     * @since 5.5
709     * @deprecated since 10.1, will always return {@code false}
710     */
711    @Deprecated
712    boolean isPrefetched(String xpath);
713
714    /**
715     * Checks if a property is prefetched.
716     *
717     * @param schemaName the schema name
718     * @param name the property name
719     * @return {@code true} if it is prefetched
720     * @since 5.5
721     * @deprecated since 10.1, will always return {@code false}
722     */
723    @Deprecated
724    boolean isPrefetched(String schemaName, String name);
725
726    /**
727     * Used to set lifecycle state along with prefetching other properties.
728     */
729    void prefetchCurrentLifecycleState(String lifecycle);
730
731    /**
732     * Used to set lifecycle policy along with prefetching other properties.
733     */
734    void prefetchLifeCyclePolicy(String lifeCyclePolicy);
735
736    boolean isLifeCycleLoaded();
737
738    /**
739     * Gets system property of the specified type. This is not a lazy loaded property, thus the request is made directly
740     * to the server. This is needed as some critical system properties might be changed directly in the core.
741     */
742    <T extends Serializable> T getSystemProp(String systemProperty, Class<T> type);
743
744    /**
745     * Get a document part given its schema name
746     *
747     * @param schema the schema
748     * @return the document aprt or null if none exists for that schema
749     * @deprecated since 8.4, use direct {@link Property} getters instead
750     * @see #getPropertyObject
751     * @see #getPropertyObjects
752     */
753    @Deprecated
754    DocumentPart getPart(String schema);
755
756    /**
757     * Gets this document's parts.
758     *
759     * @deprecated since 8.4, use direct {@link Property} getters instead
760     * @see #getSchemas
761     * @see #getPropertyObject
762     * @see #getPropertyObjects
763     */
764    @Deprecated
765    DocumentPart[] getParts();
766
767    /**
768     * Gets the {@link Property} objects for the given schema.
769     * <p>
770     * An empty list is returned if the document doesn't have the schema.
771     *
772     * @param schema the schema
773     * @return the properties
774     * @since 8.4
775     */
776    Collection<Property> getPropertyObjects(String schema);
777
778    /**
779     * Gets a property given a xpath.
780     * <p>
781     * Note that what's called xpath in this context is not an actual XPath as specified by the w3c. Main differences
782     * are that in our xpath:
783     * <ul>
784     * <li>Indexes start at 0 instead of 1</li>
785     * <li>You can express {@code foo/bar[i]/baz} as {@code foo/i/baz}</li>
786     * </ul>
787     * The latter is possible because in Nuxeo lists of complex elements are homogenous, so the name of the second-level
788     * element is implied.
789     */
790    Property getProperty(String xpath) throws PropertyException;
791
792    /**
793     * Gets a property value given a xpath.
794     * <p>
795     * Note that what's called xpath in this context is not an actual XPath as specified by the w3c. Main differences
796     * are that in our xpath:
797     * <ul>
798     * <li>Indexes start at 0 instead of 1</li>
799     * <li>You can express {@code foo/bar[i]/baz} as {@code foo/i/baz}</li>
800     * </ul>
801     * The latter is possible because in Nuxeo lists of complex elements are homogenous, so the name of the second-level
802     * element is implied.
803     */
804    Serializable getPropertyValue(String xpath) throws PropertyException;
805
806    /**
807     * Sets a property value given a xpath.
808     */
809    void setPropertyValue(String xpath, Serializable value) throws PropertyException;
810
811    /**
812     * Clears any prefetched or cached document data.
813     * <p>
814     * This will force the document to lazily update its data when required.
815     */
816    void reset();
817
818    /**
819     * Refresh document data from server.
820     * <p>
821     * The data models will be removed and all prefetch and system data will be refreshed from the server
822     * <p>
823     * The refreshed data contains:
824     * <ul>
825     * <li>document life cycle
826     * <li>document lock state, acp if required
827     * <li>acp if required - otherwise acp info will be cleared so that it will be refetched in lazy way
828     * <li>document parts if required - otherwise parts data will be removed to be refreshed lazy
829     * </ul>
830     * The refresh flags are:
831     * <ul>
832     * <li>{@link DocumentModel#REFRESH_STATE}
833     * <li>{@link DocumentModel#REFRESH_ACP_IF_LOADED}
834     * <li>{@link DocumentModel#REFRESH_ACP_LAZY}
835     * <li>{@link DocumentModel#REFRESH_ACP}
836     * <li>{@link DocumentModel#REFRESH_CONTENT_IF_LOADED}
837     * <li>{@link DocumentModel#REFRESH_CONTENT_LAZY}
838     * <li>{@link DocumentModel#REFRESH_CONTENT}
839     * <li>{@link DocumentModel#REFRESH_DEFAULT} same as REFRESH_STATE | REFRESH_DEFAULT | REFRESH_ACP_IF_LOADED |
840     * REFRESH_CONTENT_IF_LOADED
841     * <li>{@link DocumentModel#REFRESH_ALL} same as REFRESH_STATE | REFRESH_PREFTECH | REFRESH_ACP | REFRESH_CONTENT
842     * </ul>
843     * If XX_IF_LOADED is used then XX will be refreshed only if already loaded in the document - otherwise a lazy
844     * refresh will be done
845     *
846     * @param refreshFlags the refresh flags
847     * @param schemas the document parts (schemas) that should be refreshed now
848     */
849    void refresh(int refreshFlags, String[] schemas);
850
851    /** Info fetched internally during a refresh. */
852    class DocumentModelRefresh {
853
854        public String lifeCycleState;
855
856        public String lifeCyclePolicy;
857
858        public boolean isCheckedOut;
859
860        public boolean isLatestVersion;
861
862        public boolean isMajorVersion;
863
864        public boolean isLatestMajorVersion;
865
866        public boolean isVersionSeriesCheckedOut;
867
868        public String versionSeriesId;
869
870        public String checkinComment;
871
872        public ACP acp;
873
874        public Set<String> instanceFacets;
875
876        public DocumentPart[] documentParts;
877
878        public boolean isTrashed;
879    }
880
881    /**
882     * Same as {@code DocumentModel.refresh(REFRESH_DEFAULT)}.
883     */
884    void refresh();
885
886    /**
887     * Clone operation. Must be made public instead of just protected as in Object.
888     */
889    DocumentModel clone() throws CloneNotSupportedException;
890
891    /**
892     * Gets the current change token for this document.
893     * <p>
894     * The change token is an opaque string which is modified every time the document is changed.
895     * <p>
896     * Before saving a document through {@link CoreSession#saveDocument} it's possible to pass an expected change token
897     * in the document context data through {@code doc.putContextData(CoreSession.CHANGE_TOKEN, expectedChangeToken)}.
898     * If the change token does not match the stored one, it means that a concurrent update happened, and a
899     * {@link org.nuxeo.ecm.core.api.ConcurrentUpdateException ConcurrentUpdateException} will be thrown.
900     *
901     * @return the change token
902     * @since 5.5
903     * @see #putContextData
904     * @see CoreSession#CHANGE_TOKEN
905     * @see CoreSession#getChangeToken
906     */
907    String getChangeToken();
908
909    /**
910     * Gets the fulltext extracted from the binary fields.
911     *
912     * @since 5.9.3
913     */
914    Map<String, String> getBinaryFulltext();
915
916    /**
917     * @param xpath the property xpath
918     * @return A {@link PropertyObjectResolver} to manage the property reference to external entities, null if this
919     *         property's type has no resolver.
920     * @since 7.1
921     */
922    PropertyObjectResolver getObjectResolver(String xpath);
923
924}