001/* 002 * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Bogdan Stefanescu 011 * Julien Anguenot 012 * Florent Guillaume 013 */ 014package org.nuxeo.ecm.core.model; 015 016import java.io.Serializable; 017import java.util.Calendar; 018import java.util.Collection; 019import java.util.List; 020import java.util.Map; 021import java.util.Set; 022import java.util.function.Consumer; 023 024import org.nuxeo.ecm.core.api.Blob; 025import org.nuxeo.ecm.core.api.DocumentNotFoundException; 026import org.nuxeo.ecm.core.api.LifeCycleException; 027import org.nuxeo.ecm.core.api.Lock; 028import org.nuxeo.ecm.core.api.PropertyException; 029import org.nuxeo.ecm.core.api.model.DocumentPart; 030import org.nuxeo.ecm.core.schema.DocumentType; 031import org.nuxeo.ecm.core.schema.types.ComplexType; 032 033/** 034 * A low-level document from a {@link Session}. 035 */ 036public interface Document { 037 038 /** 039 * Gets the session that owns this document. 040 * 041 * @return the session 042 */ 043 Session getSession(); 044 045 /** 046 * Gets the name of this document. 047 * 048 * @return the document name 049 */ 050 String getName(); 051 052 /** 053 * Gets the document's position in its containing folder (if ordered). 054 * 055 * @return the position 056 * @since 6.0 057 */ 058 Long getPos(); 059 060 /** 061 * Gets this document's UUID. 062 * 063 * @return the document UUID 064 */ 065 String getUUID(); 066 067 /** 068 * Gets the parent document, or {@code null} if this is the root document. 069 * 070 * @return the parent document, or {@code null} 071 */ 072 Document getParent(); 073 074 /** 075 * Gets the type of this document. 076 * 077 * @return the document type 078 */ 079 DocumentType getType(); 080 081 /** 082 * Gets the path of this document. 083 * 084 * @return the path 085 */ 086 String getPath(); 087 088 /** 089 * Sets a simple property value. 090 * <p> 091 * For more generic properties described by an xpath, use {@link #setValue} instead. 092 * 093 * @param name the name of the property to set 094 * @param value the value to set 095 * @see #setValue 096 */ 097 void setPropertyValue(String name, Serializable value); 098 099 /** 100 * Sets a property value. 101 * <p> 102 * The xpath may point to a partial path, in which case the value may be a complex {@link List} or {@link Map}. 103 * 104 * @param xpath the xpath of the property to set 105 * @param value the value to set 106 * @throws PropertyException if the property does not exist or the value is of the wrong type 107 * @since 7.3 108 */ 109 void setValue(String xpath, Object value) throws PropertyException; 110 111 /** 112 * Gets a simple property value. 113 * <p> 114 * For more generic properties described by an xpath, use {@link #getValue} instead. 115 * 116 * @param name the name of the property to get 117 * @return the property value or {@code null} if the property is not set 118 * @see #getValue 119 */ 120 Serializable getPropertyValue(String name); 121 122 /** 123 * Gets a property value. 124 * <p> 125 * The xpath may point to a partial path, in which case the value may be a complex {@link List} or {@link Map}. 126 * 127 * @param xpath the xpath of the property to set 128 * @return the property value or {@code null} if the property is not set 129 * @throws PropertyException if the property does not exist 130 */ 131 Object getValue(String xpath) throws PropertyException; 132 133 /** 134 * An accessor that can read or write a blob and know its xpath. 135 * 136 * @since 7.3 137 */ 138 interface BlobAccessor { 139 /** Gets the blob's xpath. */ 140 String getXPath(); 141 142 /** Gets the blob. */ 143 Blob getBlob(); 144 145 /** Sets the blob. */ 146 void setBlob(Blob blob); 147 } 148 149 /** 150 * Visits all the blobs of this document and calls the passed blob visitor on each one. 151 * 152 * @since 7.3 153 */ 154 void visitBlobs(Consumer<BlobAccessor> blobVisitor) throws PropertyException; 155 156 /** 157 * Checks whether this document is a folder. 158 * 159 * @return {@code true} if the document is a folder, {@code false} otherwise 160 */ 161 boolean isFolder(); 162 163 /** 164 * Sets this document as readonly or not. 165 * 166 * @since 5.9.2 167 */ 168 void setReadOnly(boolean readonly); 169 170 /** 171 * Checks whether this document is readonly or not. 172 * 173 * @since 5.9.2 174 */ 175 boolean isReadOnly(); 176 177 /** 178 * Removes this document and all its children, if any. 179 */ 180 void remove(); 181 182 /** 183 * Gets the life cycle state of this document. 184 * 185 * @return the life cycle state 186 */ 187 String getLifeCycleState(); 188 189 /** 190 * Sets the life cycle state of this document. 191 * 192 * @param state the life cycle state 193 */ 194 void setCurrentLifeCycleState(String state); 195 196 /** 197 * Gets the life cycle policy of this document. 198 * 199 * @return the life cycle policy 200 */ 201 String getLifeCyclePolicy(); 202 203 /** 204 * Sets the life cycle policy of this document. 205 * 206 * @param policy the life cycle policy 207 */ 208 void setLifeCyclePolicy(String policy); 209 210 /** 211 * Follows a given life cycle transition. 212 * <p> 213 * This will update the life cycle state of the document. 214 * 215 * @param transition the name of the transition to follow 216 */ 217 void followTransition(String transition) throws LifeCycleException; 218 219 /** 220 * Returns the allowed state transitions for this document. 221 * 222 * @return a collection of state transitions 223 */ 224 Collection<String> getAllowedStateTransitions(); 225 226 /** 227 * Checks whether or not this document is a proxy. 228 * 229 * @return {@code true} if this document is a proxy, {@code false} otherwise 230 */ 231 boolean isProxy(); 232 233 /** 234 * Gets the repository in which the document lives. 235 * 236 * @return the repository name. 237 */ 238 String getRepositoryName(); 239 240 /** 241 * Sets a system property. 242 */ 243 void setSystemProp(String name, Serializable value); 244 245 /** 246 * Gets a system property. 247 */ 248 <T extends Serializable> T getSystemProp(String name, Class<T> type); 249 250 /** 251 * Loads a {@link DocumentPart} from storage. 252 * <p> 253 * Reading data is done by {@link DocumentPart} because of per-proxy schemas. 254 */ 255 void readDocumentPart(DocumentPart dp) throws PropertyException; 256 257 /** 258 * Reads a set of prefetched fields. 259 * <p> 260 * Reading data is done by {@link ComplexType} because of per-proxy schemas. 261 * 262 * @since 5.9.4 263 */ 264 Map<String, Serializable> readPrefetch(ComplexType complexType, Set<String> xpaths) throws PropertyException; 265 266 /** 267 * Context passed to write operations to optionally record things to do at {@link #flush} time. 268 * 269 * @since 7.3 270 */ 271 interface WriteContext { 272 /** 273 * Gets the recorded changed xpaths. 274 */ 275 Set<String> getChanges(); 276 277 /** 278 * Flushes recorded write operations. 279 * 280 * @param doc the base document being written 281 */ 282 void flush(Document doc); 283 } 284 285 /** 286 * Gets a write context for the current document. 287 * 288 * @since 7.3 289 */ 290 WriteContext getWriteContext(); 291 292 /** 293 * Writes a {@link DocumentPart} to storage. 294 * <p> 295 * Writing data is done by {@link DocumentPart} because of per-proxy schemas. 296 * 297 * @return {@code true} if something changed 298 */ 299 boolean writeDocumentPart(DocumentPart dp, WriteContext writeContext) throws PropertyException; 300 301 /** 302 * Gets the facets available on this document (from the type and the instance facets). 303 * 304 * @return the facets 305 * @since 5.4.2 306 */ 307 Set<String> getAllFacets(); 308 309 /** 310 * Gets the facets defined on this document instance. The type facets are not returned. 311 * 312 * @return the facets 313 * @since 5.4.2 314 */ 315 String[] getFacets(); 316 317 /** 318 * Checks whether this document has a given facet, either from its type or added on the instance. 319 * 320 * @param facet the facet name 321 * @return {@code true} if the document has the facet 322 * @since 5.4.2 323 */ 324 boolean hasFacet(String facet); 325 326 /** 327 * Adds a facet to this document. 328 * <p> 329 * Does nothing if the facet was already present on the document. 330 * 331 * @param facet the facet name 332 * @return {@code true} if the facet was added, or {@code false} if it is already present 333 * @throws IllegalArgumentException if the facet does not exist 334 * @since 5.4.2 335 */ 336 boolean addFacet(String facet); 337 338 /** 339 * Removes a facet from this document. 340 * <p> 341 * It's not possible to remove a facet coming from the document type. 342 * 343 * @param facet the facet name 344 * @return {@code true} if the facet was removed, or {@code false} if it isn't present or is present on the type or 345 * does not exit 346 * @since 5.4.2 347 */ 348 boolean removeFacet(String facet); 349 350 /** 351 * Sets a lock on this document. 352 * 353 * @param lock the lock to set 354 * @return {@code null} if locking succeeded, or the existing lock if locking failed 355 */ 356 Lock setLock(Lock lock); 357 358 /** 359 * Removes a lock from this document. 360 * 361 * @param the owner to check, or {@code null} for no check 362 * @return {@code null} if there was no lock or if removal succeeded, or a lock if it blocks removal due to owner 363 * mismatch 364 */ 365 Lock removeLock(String owner); 366 367 /** 368 * Gets the lock if one set on this document. 369 * 370 * @return the lock, or {@code null} if no lock is set 371 */ 372 Lock getLock(); 373 374 /** 375 * Gets a child document given its name. 376 * <p> 377 * Throws {@link DocumentNotFoundException} if the document could not be found. 378 * 379 * @param name the name of the child to retrieve 380 * @return the child if exists 381 * @throws DocumentNotFoundException if the child does not exist 382 */ 383 Document getChild(String name); 384 385 /** 386 * Gets the children of the document. 387 * <p> 388 * Returns an empty list for non-folder documents. 389 * 390 * @return the children 391 */ 392 List<Document> getChildren(); 393 394 /** 395 * Gets a list of the children ids. 396 * <p> 397 * Returns an empty list for non-folder documents. 398 * 399 * @return a list of children ids. 400 * @since 1.4.1 401 */ 402 List<String> getChildrenIds(); 403 404 /** 405 * Checks whether this document has a child of the given name. 406 * <p> 407 * Returns {@code false} for non-folder documents. 408 * 409 * @param name the name of the child to check 410 * @return {@code true} if the child exists, {@code false} otherwise 411 */ 412 boolean hasChild(String name); 413 414 /** 415 * Tests if the document has any children. 416 * <p> 417 * Returns {@code false} for non-folder documents. 418 * 419 * @return {@code true} if the document has children, {@code false} otherwise 420 */ 421 boolean hasChildren(); 422 423 /** 424 * Creates a new child document of the given type. 425 * <p> 426 * Throws an error if this document is not a folder. 427 * 428 * @param name the name of the new child to create 429 * @param typeName the type of the child to create 430 * @return the newly created document 431 */ 432 Document addChild(String name, String typeName); 433 434 /** 435 * Orders the given source child before the destination child. 436 * <p> 437 * Both source and destination must be names that point to child documents of this document. The source document 438 * will be placed before the destination one. If destination is {@code null}, the source document will be appended 439 * at the end of the children list. 440 * 441 * @param src the document to move 442 * @param dest the document before which to place the source document 443 */ 444 void orderBefore(String src, String dest); 445 446 /** 447 * Creates a new version. 448 * 449 * @param label the version label 450 * @param checkinComment the checkin comment 451 * @return the created version 452 */ 453 Document checkIn(String label, String checkinComment); 454 455 void checkOut(); 456 457 /** 458 * Gets the list of version ids for this document. 459 * 460 * @return the list of version ids 461 * @since 1.4.1 462 */ 463 List<String> getVersionsIds(); 464 465 /** 466 * Gets the versions for this document. 467 * 468 * @return the versions of the document, or an empty list if there are no versions 469 */ 470 List<Document> getVersions(); 471 472 /** 473 * Gets the last version of this document. 474 * <p> 475 * Returns {@code null} if there is no version at all. 476 * 477 * @return the last version, or {@code null} if there is no version 478 */ 479 Document getLastVersion(); 480 481 /** 482 * Gets the source for this document. 483 * <p> 484 * For a version, it's the working copy. 485 * <p> 486 * For a proxy, it's the version the proxy points to. 487 * 488 * @return the source document 489 */ 490 Document getSourceDocument(); 491 492 /** 493 * Replaces this document's content with the version specified. 494 * 495 * @param version the version to replace with 496 */ 497 void restore(Document version); 498 499 /** 500 * Gets a version of this document, given its label. 501 * 502 * @param label the version label 503 * @return the version 504 */ 505 Document getVersion(String label); 506 507 /** 508 * Checks whether this document is a version document. 509 * 510 * @return {@code true} if it's a version, {@code false} otherwise 511 */ 512 boolean isVersion(); 513 514 /** 515 * Gets the version to which a checked in document is linked. 516 * <p> 517 * Returns {@code null} for a checked out document or a version or a proxy. 518 * 519 * @return the version, or {@code null} 520 */ 521 Document getBaseVersion(); 522 523 /** 524 * Checks whether this document is checked out. 525 * 526 * @return {@code true} if the document is checked out, or {@code false} otherwise 527 */ 528 boolean isCheckedOut(); 529 530 /** 531 * Gets the version creation date of this document if it's a version or a proxy. 532 * 533 * @return the version creation date, or {@code null} if it's not a version or a proxy 534 */ 535 Calendar getVersionCreationDate(); 536 537 /** 538 * Gets the version check in comment of this document if it's a version or a proxy. 539 * 540 * @return the check in comment, or {@code null} if it's not a version or a proxy 541 */ 542 String getCheckinComment(); 543 544 /** 545 * Gets the version series id. 546 * 547 * @return the version series id 548 */ 549 String getVersionSeriesId(); 550 551 /** 552 * Gets the version label. 553 * 554 * @return the version label 555 */ 556 String getVersionLabel(); 557 558 /** 559 * Checks whether this document is the latest version. 560 * 561 * @return {@code true} if this is the latest version, or {@code false} otherwise 562 */ 563 boolean isLatestVersion(); 564 565 /** 566 * Checks whether this document is a major version. 567 * 568 * @return {@code true} if this is a major version, or {@code false} otherwise 569 */ 570 boolean isMajorVersion(); 571 572 /** 573 * Checks whether this document is the latest major version. 574 * 575 * @return {@code true} if this is the latest major version, or {@code false} otherwise 576 */ 577 boolean isLatestMajorVersion(); 578 579 /** 580 * Checks if there is a checked out working copy for the version series of this document. 581 * 582 * @return {@code true} if there is a checked out working copy 583 */ 584 boolean isVersionSeriesCheckedOut(); 585 586 /** 587 * Gets the working copy for this document. 588 * 589 * @return the working copy 590 */ 591 Document getWorkingCopy(); 592 593 /** 594 * Gets the document (version or live document) to which this proxy points. 595 */ 596 Document getTargetDocument(); 597 598 /** 599 * Sets the document (version or live document) to which this proxy points. 600 */ 601 void setTargetDocument(Document target); 602 603}