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