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