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