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 * Gets the life cycle state of this document. 191 * 192 * @return the life cycle state 193 */ 194 String getLifeCycleState(); 195 196 /** 197 * Sets the life cycle state of this document. 198 * 199 * @param state the life cycle state 200 */ 201 void setCurrentLifeCycleState(String state); 202 203 /** 204 * Gets the life cycle policy of this document. 205 * 206 * @return the life cycle policy 207 */ 208 String getLifeCyclePolicy(); 209 210 /** 211 * Sets the life cycle policy of this document. 212 * 213 * @param policy the life cycle policy 214 */ 215 void setLifeCyclePolicy(String policy); 216 217 /** 218 * Follows a given life cycle transition. 219 * <p> 220 * This will update the life cycle state of the document. 221 * 222 * @param transition the name of the transition to follow 223 */ 224 void followTransition(String transition) throws LifeCycleException; 225 226 /** 227 * Returns the allowed state transitions for this document. 228 * 229 * @return a collection of state transitions 230 */ 231 Collection<String> getAllowedStateTransitions(); 232 233 /** 234 * Checks whether or not this document is a proxy. 235 * 236 * @return {@code true} if this document is a proxy, {@code false} otherwise 237 */ 238 boolean isProxy(); 239 240 /** 241 * Gets the repository in which the document lives. 242 * 243 * @return the repository name. 244 */ 245 String getRepositoryName(); 246 247 /** 248 * Sets a system property. 249 */ 250 void setSystemProp(String name, Serializable value); 251 252 /** 253 * Gets a system property. 254 */ 255 <T extends Serializable> T getSystemProp(String name, Class<T> type); 256 257 /** 258 * Gets the current change token for this document. 259 * 260 * @return the change token 261 * @since 9.1 262 */ 263 String getChangeToken(); 264 265 /** 266 * Validates that the passed user-visible change token is compatible with the one for this document. 267 * 268 * @return {@code false} if the change token is not valid 269 * @since 9.2 270 */ 271 boolean validateUserVisibleChangeToken(String changeToken); 272 273 /** 274 * Marks the document as being modified by a user change. 275 * <p> 276 * This causes an additional change token increment and check during save. 277 * 278 * @since 9.2 279 */ 280 void markUserChange(); 281 282 /** 283 * Loads a {@link DocumentPart} from storage. 284 * <p> 285 * Reading data is done by {@link DocumentPart} because of per-proxy schemas. 286 */ 287 void readDocumentPart(DocumentPart dp) throws PropertyException; 288 289 /** 290 * Reads a set of prefetched fields. 291 * <p> 292 * Reading data is done by {@link ComplexType} because of per-proxy schemas. 293 * 294 * @since 5.9.4 295 */ 296 Map<String, Serializable> readPrefetch(ComplexType complexType, Set<String> xpaths) throws PropertyException; 297 298 /** 299 * Context passed to write operations to optionally record things to do at {@link #flush} time. 300 * 301 * @since 7.3 302 */ 303 interface WriteContext { 304 /** 305 * Gets the recorded changed xpaths. 306 */ 307 Set<String> getChanges(); 308 309 /** 310 * Flushes recorded write operations. 311 * 312 * @param doc the base document being written 313 */ 314 void flush(Document doc); 315 } 316 317 /** 318 * Gets a write context for the current document. 319 * 320 * @since 7.3 321 */ 322 WriteContext getWriteContext(); 323 324 /** 325 * Writes a {@link DocumentPart} to storage. 326 * <p> 327 * Writing data is done by {@link DocumentPart} because of per-proxy schemas. 328 * 329 * @return {@code true} if something changed 330 */ 331 boolean writeDocumentPart(DocumentPart dp, WriteContext writeContext) throws PropertyException; 332 333 /** 334 * Gets the facets available on this document (from the type and the instance facets). 335 * 336 * @return the facets 337 * @since 5.4.2 338 */ 339 Set<String> getAllFacets(); 340 341 /** 342 * Gets the facets defined on this document instance. The type facets are not returned. 343 * 344 * @return the facets 345 * @since 5.4.2 346 */ 347 String[] getFacets(); 348 349 /** 350 * Checks whether this document has a given facet, either from its type or added on the instance. 351 * 352 * @param facet the facet name 353 * @return {@code true} if the document has the facet 354 * @since 5.4.2 355 */ 356 boolean hasFacet(String facet); 357 358 /** 359 * Adds a facet to this document. 360 * <p> 361 * Does nothing if the facet was already present on the document. 362 * 363 * @param facet the facet name 364 * @return {@code true} if the facet was added, or {@code false} if it is already present 365 * @throws IllegalArgumentException if the facet does not exist 366 * @since 5.4.2 367 */ 368 boolean addFacet(String facet); 369 370 /** 371 * Removes a facet from this document. 372 * <p> 373 * It's not possible to remove a facet coming from the document type. 374 * 375 * @param facet the facet name 376 * @return {@code true} if the facet was removed, or {@code false} if it isn't present or is present on the type or 377 * does not exit 378 * @since 5.4.2 379 */ 380 boolean removeFacet(String facet); 381 382 /** 383 * Sets a lock on this document. 384 * 385 * @param lock the lock to set 386 * @return {@code null} if locking succeeded, or the existing lock if locking failed 387 */ 388 Lock setLock(Lock lock); 389 390 /** 391 * Removes a lock from this document. 392 * 393 * @param the owner to check, or {@code null} for no check 394 * @return {@code null} if there was no lock or if removal succeeded, or a lock if it blocks removal due to owner 395 * mismatch 396 */ 397 Lock removeLock(String owner); 398 399 /** 400 * Gets the lock if one set on this document. 401 * 402 * @return the lock, or {@code null} if no lock is set 403 */ 404 Lock getLock(); 405 406 /** 407 * Gets a child document given its name. 408 * <p> 409 * Throws {@link DocumentNotFoundException} if the document could not be found. 410 * 411 * @param name the name of the child to retrieve 412 * @return the child if exists 413 * @throws DocumentNotFoundException if the child does not exist 414 */ 415 Document getChild(String name); 416 417 /** 418 * Gets the children of the document. 419 * <p> 420 * Returns an empty list for non-folder documents. 421 * 422 * @return the children 423 */ 424 List<Document> getChildren(); 425 426 /** 427 * Gets a list of the children ids. 428 * <p> 429 * Returns an empty list for non-folder documents. 430 * 431 * @return a list of children ids. 432 * @since 1.4.1 433 */ 434 List<String> getChildrenIds(); 435 436 /** 437 * Checks whether this document has a child of the given name. 438 * <p> 439 * Returns {@code false} for non-folder documents. 440 * 441 * @param name the name of the child to check 442 * @return {@code true} if the child exists, {@code false} otherwise 443 */ 444 boolean hasChild(String name); 445 446 /** 447 * Tests if the document has any children. 448 * <p> 449 * Returns {@code false} for non-folder documents. 450 * 451 * @return {@code true} if the document has children, {@code false} otherwise 452 */ 453 boolean hasChildren(); 454 455 /** 456 * Creates a new child document of the given type. 457 * <p> 458 * Throws an error if this document is not a folder. 459 * 460 * @param name the name of the new child to create 461 * @param typeName the type of the child to create 462 * @return the newly created document 463 */ 464 Document addChild(String name, String typeName); 465 466 /** 467 * Orders the given source child before the destination child. 468 * <p> 469 * Both source and destination must be names that point to child documents of this document. The source document 470 * will be placed before the destination one. If destination is {@code null}, the source document will be appended 471 * at the end of the children list. 472 * 473 * @param src the document to move 474 * @param dest the document before which to place the source document 475 */ 476 void orderBefore(String src, String dest); 477 478 /** 479 * Creates a new version. 480 * 481 * @param label the version label 482 * @param checkinComment the checkin comment 483 * @return the created version 484 */ 485 Document checkIn(String label, String checkinComment); 486 487 void checkOut(); 488 489 /** 490 * Gets the list of version ids for this document. 491 * 492 * @return the list of version ids 493 * @since 1.4.1 494 */ 495 List<String> getVersionsIds(); 496 497 /** 498 * Gets the versions for this document. 499 * 500 * @return the versions of the document, or an empty list if there are no versions 501 */ 502 List<Document> getVersions(); 503 504 /** 505 * Gets the last version of this document. 506 * <p> 507 * Returns {@code null} if there is no version at all. 508 * 509 * @return the last version, or {@code null} if there is no version 510 */ 511 Document getLastVersion(); 512 513 /** 514 * Gets the source for this document. 515 * <p> 516 * For a version, it's the working copy. 517 * <p> 518 * For a proxy, it's the version the proxy points to. 519 * 520 * @return the source document 521 */ 522 Document getSourceDocument(); 523 524 /** 525 * Replaces this document's content with the version specified. 526 * 527 * @param version the version to replace with 528 */ 529 void restore(Document version); 530 531 /** 532 * Gets a version of this document, given its label. 533 * 534 * @param label the version label 535 * @return the version 536 */ 537 Document getVersion(String label); 538 539 /** 540 * Checks whether this document is a version document. 541 * 542 * @return {@code true} if it's a version, {@code false} otherwise 543 */ 544 boolean isVersion(); 545 546 /** 547 * Gets the version to which a checked in document is linked. 548 * <p> 549 * Returns {@code null} for a checked out document or a version or a proxy. 550 * 551 * @return the version, or {@code null} 552 */ 553 Document getBaseVersion(); 554 555 /** 556 * Checks whether this document is checked out. 557 * 558 * @return {@code true} if the document is checked out, or {@code false} otherwise 559 */ 560 boolean isCheckedOut(); 561 562 /** 563 * Gets the version creation date of this document if it's a version or a proxy. 564 * 565 * @return the version creation date, or {@code null} if it's not a version or a proxy 566 */ 567 Calendar getVersionCreationDate(); 568 569 /** 570 * Gets the version check in comment of this document if it's a version or a proxy. 571 * 572 * @return the check in comment, or {@code null} if it's not a version or a proxy 573 */ 574 String getCheckinComment(); 575 576 /** 577 * Gets the version series id. 578 * 579 * @return the version series id 580 */ 581 String getVersionSeriesId(); 582 583 /** 584 * Gets the version label. 585 * 586 * @return the version label 587 */ 588 String getVersionLabel(); 589 590 /** 591 * Checks whether this document is the latest version. 592 * 593 * @return {@code true} if this is the latest version, or {@code false} otherwise 594 */ 595 boolean isLatestVersion(); 596 597 /** 598 * Checks whether this document is a major version. 599 * 600 * @return {@code true} if this is a major version, or {@code false} otherwise 601 */ 602 boolean isMajorVersion(); 603 604 /** 605 * Checks whether this document is the latest major version. 606 * 607 * @return {@code true} if this is the latest major version, or {@code false} otherwise 608 */ 609 boolean isLatestMajorVersion(); 610 611 /** 612 * Checks if there is a checked out working copy for the version series of this document. 613 * 614 * @return {@code true} if there is a checked out working copy 615 */ 616 boolean isVersionSeriesCheckedOut(); 617 618 /** 619 * Gets the working copy for this document. 620 * 621 * @return the working copy 622 */ 623 Document getWorkingCopy(); 624 625 /** 626 * Gets the document (version or live document) to which this proxy points. 627 */ 628 Document getTargetDocument(); 629 630 /** 631 * Sets the document (version or live document) to which this proxy points. 632 */ 633 void setTargetDocument(Document target); 634 635}