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