/*
* (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Bogdan Stefanescu
* Julien Anguenot
* Florent Guillaume
*/
package org.nuxeo.ecm.core.model;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.DocumentNotFoundException;
import org.nuxeo.ecm.core.api.LifeCycleException;
import org.nuxeo.ecm.core.api.Lock;
import org.nuxeo.ecm.core.api.PropertyException;
import org.nuxeo.ecm.core.api.model.DocumentPart;
import org.nuxeo.ecm.core.schema.DocumentType;
import org.nuxeo.ecm.core.schema.types.ComplexType;
/**
* A low-level document from a {@link Session}.
*/
public interface Document {
/**
* Gets the session that owns this document.
*
* @return the session
*/
Session getSession();
/**
* Gets the name of this document.
*
* @return the document name
*/
String getName();
/**
* Gets the document's position in its containing folder (if ordered).
*
* @return the position
* @since 6.0
*/
Long getPos();
/**
* Gets this document's UUID.
*
* @return the document UUID
*/
String getUUID();
/**
* Gets the parent document, or {@code null} if this is the root document.
*
* @return the parent document, or {@code null}
*/
Document getParent();
/**
* Gets the type of this document.
*
* @return the document type
*/
DocumentType getType();
/**
* Gets the path of this document.
*
* @return the path
*/
String getPath();
/**
* Sets a simple property value.
* <p>
* For more generic properties described by an xpath, use {@link #setValue} instead.
*
* @param name the name of the property to set
* @param value the value to set
* @see #setValue
*/
void setPropertyValue(String name, Serializable value);
/**
* Sets a property value.
* <p>
* The xpath may point to a partial path, in which case the value may be a complex {@link List} or {@link Map}.
*
* @param xpath the xpath of the property to set
* @param value the value to set
* @throws PropertyException if the property does not exist or the value is of the wrong type
* @since 7.3
*/
void setValue(String xpath, Object value) throws PropertyException;
/**
* Gets a simple property value.
* <p>
* For more generic properties described by an xpath, use {@link #getValue} instead.
*
* @param name the name of the property to get
* @return the property value or {@code null} if the property is not set
* @see #getValue
*/
Serializable getPropertyValue(String name);
/**
* Gets a property value.
* <p>
* The xpath may point to a partial path, in which case the value may be a complex {@link List} or {@link Map}.
*
* @param xpath the xpath of the property to set
* @return the property value or {@code null} if the property is not set
* @throws PropertyException if the property does not exist
*/
Object getValue(String xpath) throws PropertyException;
/**
* An accessor that can read or write a blob and know its xpath.
*
* @since 7.3
*/
interface BlobAccessor {
/** Gets the blob's xpath. */
String getXPath();
/** Gets the blob. */
Blob getBlob();
/** Sets the blob. */
void setBlob(Blob blob);
}
/**
* Visits all the blobs of this document and calls the passed blob visitor on each one.
*
* @since 7.3
*/
void visitBlobs(Consumer<BlobAccessor> blobVisitor) throws PropertyException;
/**
* Checks whether this document is a folder.
*
* @return {@code true} if the document is a folder, {@code false} otherwise
*/
boolean isFolder();
/**
* Sets this document as readonly or not.
*
* @since 5.9.2
*/
void setReadOnly(boolean readonly);
/**
* Checks whether this document is readonly or not.
*
* @since 5.9.2
*/
boolean isReadOnly();
/**
* Removes this document and all its children, if any.
*/
void remove();
/**
* Gets the life cycle state of this document.
*
* @return the life cycle state
*/
String getLifeCycleState();
/**
* Sets the life cycle state of this document.
*
* @param state the life cycle state
*/
void setCurrentLifeCycleState(String state);
/**
* Gets the life cycle policy of this document.
*
* @return the life cycle policy
*/
String getLifeCyclePolicy();
/**
* Sets the life cycle policy of this document.
*
* @param policy the life cycle policy
*/
void setLifeCyclePolicy(String policy);
/**
* Follows a given life cycle transition.
* <p>
* This will update the life cycle state of the document.
*
* @param transition the name of the transition to follow
*/
void followTransition(String transition) throws LifeCycleException;
/**
* Returns the allowed state transitions for this document.
*
* @return a collection of state transitions
*/
Collection<String> getAllowedStateTransitions();
/**
* Checks whether or not this document is a proxy.
*
* @return {@code true} if this document is a proxy, {@code false} otherwise
*/
boolean isProxy();
/**
* Gets the repository in which the document lives.
*
* @return the repository name.
*/
String getRepositoryName();
/**
* Sets a system property.
*/
void setSystemProp(String name, Serializable value);
/**
* Gets a system property.
*/
<T extends Serializable> T getSystemProp(String name, Class<T> type);
/**
* Gets the current change token for this document.
*
* @return the change token
* @since 9.1
*/
String getChangeToken();
/**
* Loads a {@link DocumentPart} from storage.
* <p>
* Reading data is done by {@link DocumentPart} because of per-proxy schemas.
*/
void readDocumentPart(DocumentPart dp) throws PropertyException;
/**
* Reads a set of prefetched fields.
* <p>
* Reading data is done by {@link ComplexType} because of per-proxy schemas.
*
* @since 5.9.4
*/
Map<String, Serializable> readPrefetch(ComplexType complexType, Set<String> xpaths) throws PropertyException;
/**
* Context passed to write operations to optionally record things to do at {@link #flush} time.
*
* @since 7.3
*/
interface WriteContext {
/**
* Gets the recorded changed xpaths.
*/
Set<String> getChanges();
/**
* Flushes recorded write operations.
*
* @param doc the base document being written
*/
void flush(Document doc);
}
/**
* Gets a write context for the current document.
*
* @since 7.3
*/
WriteContext getWriteContext();
/**
* Writes a {@link DocumentPart} to storage.
* <p>
* Writing data is done by {@link DocumentPart} because of per-proxy schemas.
*
* @return {@code true} if something changed
*/
boolean writeDocumentPart(DocumentPart dp, WriteContext writeContext) throws PropertyException;
/**
* Gets the facets available on this document (from the type and the instance facets).
*
* @return the facets
* @since 5.4.2
*/
Set<String> getAllFacets();
/**
* Gets the facets defined on this document instance. The type facets are not returned.
*
* @return the facets
* @since 5.4.2
*/
String[] getFacets();
/**
* Checks whether this document has a given facet, either from its type or added on the instance.
*
* @param facet the facet name
* @return {@code true} if the document has the facet
* @since 5.4.2
*/
boolean hasFacet(String facet);
/**
* Adds a facet to this document.
* <p>
* Does nothing if the facet was already present on the document.
*
* @param facet the facet name
* @return {@code true} if the facet was added, or {@code false} if it is already present
* @throws IllegalArgumentException if the facet does not exist
* @since 5.4.2
*/
boolean addFacet(String facet);
/**
* Removes a facet from this document.
* <p>
* It's not possible to remove a facet coming from the document type.
*
* @param facet the facet name
* @return {@code true} if the facet was removed, or {@code false} if it isn't present or is present on the type or
* does not exit
* @since 5.4.2
*/
boolean removeFacet(String facet);
/**
* Sets a lock on this document.
*
* @param lock the lock to set
* @return {@code null} if locking succeeded, or the existing lock if locking failed
*/
Lock setLock(Lock lock);
/**
* Removes a lock from this document.
*
* @param the owner to check, or {@code null} for no check
* @return {@code null} if there was no lock or if removal succeeded, or a lock if it blocks removal due to owner
* mismatch
*/
Lock removeLock(String owner);
/**
* Gets the lock if one set on this document.
*
* @return the lock, or {@code null} if no lock is set
*/
Lock getLock();
/**
* Gets a child document given its name.
* <p>
* Throws {@link DocumentNotFoundException} if the document could not be found.
*
* @param name the name of the child to retrieve
* @return the child if exists
* @throws DocumentNotFoundException if the child does not exist
*/
Document getChild(String name);
/**
* Gets the children of the document.
* <p>
* Returns an empty list for non-folder documents.
*
* @return the children
*/
List<Document> getChildren();
/**
* Gets a list of the children ids.
* <p>
* Returns an empty list for non-folder documents.
*
* @return a list of children ids.
* @since 1.4.1
*/
List<String> getChildrenIds();
/**
* Checks whether this document has a child of the given name.
* <p>
* Returns {@code false} for non-folder documents.
*
* @param name the name of the child to check
* @return {@code true} if the child exists, {@code false} otherwise
*/
boolean hasChild(String name);
/**
* Tests if the document has any children.
* <p>
* Returns {@code false} for non-folder documents.
*
* @return {@code true} if the document has children, {@code false} otherwise
*/
boolean hasChildren();
/**
* Creates a new child document of the given type.
* <p>
* Throws an error if this document is not a folder.
*
* @param name the name of the new child to create
* @param typeName the type of the child to create
* @return the newly created document
*/
Document addChild(String name, String typeName);
/**
* Orders the given source child before the destination child.
* <p>
* Both source and destination must be names that point to child documents of this document. The source document
* will be placed before the destination one. If destination is {@code null}, the source document will be appended
* at the end of the children list.
*
* @param src the document to move
* @param dest the document before which to place the source document
*/
void orderBefore(String src, String dest);
/**
* Creates a new version.
*
* @param label the version label
* @param checkinComment the checkin comment
* @return the created version
*/
Document checkIn(String label, String checkinComment);
void checkOut();
/**
* Gets the list of version ids for this document.
*
* @return the list of version ids
* @since 1.4.1
*/
List<String> getVersionsIds();
/**
* Gets the versions for this document.
*
* @return the versions of the document, or an empty list if there are no versions
*/
List<Document> getVersions();
/**
* Gets the last version of this document.
* <p>
* Returns {@code null} if there is no version at all.
*
* @return the last version, or {@code null} if there is no version
*/
Document getLastVersion();
/**
* Gets the source for this document.
* <p>
* For a version, it's the working copy.
* <p>
* For a proxy, it's the version the proxy points to.
*
* @return the source document
*/
Document getSourceDocument();
/**
* Replaces this document's content with the version specified.
*
* @param version the version to replace with
*/
void restore(Document version);
/**
* Gets a version of this document, given its label.
*
* @param label the version label
* @return the version
*/
Document getVersion(String label);
/**
* Checks whether this document is a version document.
*
* @return {@code true} if it's a version, {@code false} otherwise
*/
boolean isVersion();
/**
* Gets the version to which a checked in document is linked.
* <p>
* Returns {@code null} for a checked out document or a version or a proxy.
*
* @return the version, or {@code null}
*/
Document getBaseVersion();
/**
* Checks whether this document is checked out.
*
* @return {@code true} if the document is checked out, or {@code false} otherwise
*/
boolean isCheckedOut();
/**
* Gets the version creation date of this document if it's a version or a proxy.
*
* @return the version creation date, or {@code null} if it's not a version or a proxy
*/
Calendar getVersionCreationDate();
/**
* Gets the version check in comment of this document if it's a version or a proxy.
*
* @return the check in comment, or {@code null} if it's not a version or a proxy
*/
String getCheckinComment();
/**
* Gets the version series id.
*
* @return the version series id
*/
String getVersionSeriesId();
/**
* Gets the version label.
*
* @return the version label
*/
String getVersionLabel();
/**
* Checks whether this document is the latest version.
*
* @return {@code true} if this is the latest version, or {@code false} otherwise
*/
boolean isLatestVersion();
/**
* Checks whether this document is a major version.
*
* @return {@code true} if this is a major version, or {@code false} otherwise
*/
boolean isMajorVersion();
/**
* Checks whether this document is the latest major version.
*
* @return {@code true} if this is the latest major version, or {@code false} otherwise
*/
boolean isLatestMajorVersion();
/**
* Checks if there is a checked out working copy for the version series of this document.
*
* @return {@code true} if there is a checked out working copy
*/
boolean isVersionSeriesCheckedOut();
/**
* Gets the working copy for this document.
*
* @return the working copy
*/
Document getWorkingCopy();
/**
* Gets the document (version or live document) to which this proxy points.
*/
Document getTargetDocument();
/**
* Sets the document (version or live document) to which this proxy points.
*/
void setTargetDocument(Document target);
}