001/* 002 * Copyright (c) 2006-2011 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 * Florent Guillaume 011 */ 012package org.nuxeo.ecm.core.opencmis.impl.client; 013 014import java.math.BigInteger; 015import java.util.ArrayList; 016import java.util.Collection; 017import java.util.List; 018import java.util.Locale; 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.chemistry.opencmis.client.api.ChangeEvent; 023import org.apache.chemistry.opencmis.client.api.ChangeEvents; 024import org.apache.chemistry.opencmis.client.api.CmisObject; 025import org.apache.chemistry.opencmis.client.api.Document; 026import org.apache.chemistry.opencmis.client.api.Folder; 027import org.apache.chemistry.opencmis.client.api.ItemIterable; 028import org.apache.chemistry.opencmis.client.api.ObjectId; 029import org.apache.chemistry.opencmis.client.api.ObjectType; 030import org.apache.chemistry.opencmis.client.api.OperationContext; 031import org.apache.chemistry.opencmis.client.api.Policy; 032import org.apache.chemistry.opencmis.client.api.QueryResult; 033import org.apache.chemistry.opencmis.client.api.QueryStatement; 034import org.apache.chemistry.opencmis.client.api.Relationship; 035import org.apache.chemistry.opencmis.client.api.Session; 036import org.apache.chemistry.opencmis.client.api.Tree; 037import org.apache.chemistry.opencmis.client.runtime.ObjectIdImpl; 038import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl; 039import org.apache.chemistry.opencmis.client.runtime.QueryResultImpl; 040import org.apache.chemistry.opencmis.client.runtime.QueryStatementImpl; 041import org.apache.chemistry.opencmis.client.runtime.util.AbstractPageFetcher; 042import org.apache.chemistry.opencmis.client.runtime.util.CollectionIterable; 043import org.apache.chemistry.opencmis.commons.PropertyIds; 044import org.apache.chemistry.opencmis.commons.data.Ace; 045import org.apache.chemistry.opencmis.commons.data.Acl; 046import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken; 047import org.apache.chemistry.opencmis.commons.data.ContentStream; 048import org.apache.chemistry.opencmis.commons.data.ObjectData; 049import org.apache.chemistry.opencmis.commons.data.ObjectList; 050import org.apache.chemistry.opencmis.commons.data.Properties; 051import org.apache.chemistry.opencmis.commons.data.PropertyData; 052import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; 053import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; 054import org.apache.chemistry.opencmis.commons.enums.AclPropagation; 055import org.apache.chemistry.opencmis.commons.enums.BindingType; 056import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; 057import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection; 058import org.apache.chemistry.opencmis.commons.enums.VersioningState; 059import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; 060import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException; 061import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; 062import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl; 063import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl; 064import org.apache.chemistry.opencmis.commons.server.CallContext; 065import org.apache.chemistry.opencmis.commons.server.CmisService; 066import org.nuxeo.ecm.core.api.CoreSession; 067import org.nuxeo.ecm.core.api.DocumentModel; 068import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData; 069 070/** 071 * Nuxeo Persistent Session, having a direct connection to a Nuxeo {@link CoreSession}. 072 */ 073public class NuxeoSession implements Session { 074 075 private static final long serialVersionUID = 1L; 076 077 public static final OperationContext DEFAULT_CONTEXT = new OperationContextImpl(null, false, true, false, 078 IncludeRelationships.NONE, null, true, null, true, 10); 079 080 private final CoreSession coreSession; 081 082 private final String repositoryId; 083 084 protected final NuxeoObjectFactory objectFactory; 085 086 private final CmisService service; 087 088 private final NuxeoBinding binding; 089 090 private OperationContext defaultContext = DEFAULT_CONTEXT; 091 092 public NuxeoSession(NuxeoBinding binding, CallContext context) { 093 this.coreSession = binding.getCoreSession(); 094 repositoryId = context.getRepositoryId(); 095 objectFactory = new NuxeoObjectFactory(this); 096 service = binding.service; 097 this.binding = binding; 098 } 099 100 @Override 101 public NuxeoObjectFactory getObjectFactory() { 102 return objectFactory; 103 } 104 105 @Override 106 public NuxeoBinding getBinding() { 107 return binding; 108 } 109 110 public CmisService getService() { 111 return service; 112 } 113 114 protected CoreSession getCoreSession() { 115 return coreSession; 116 } 117 118 @Override 119 public void clear() { 120 } 121 122 public void save() { 123 coreSession.save(); 124 } 125 126 @Override 127 public void setDefaultContext(OperationContext defaultContext) { 128 this.defaultContext = defaultContext; 129 } 130 131 @Override 132 public OperationContext getDefaultContext() { 133 return defaultContext; 134 } 135 136 protected String getRepositoryId() { 137 return coreSession.getRepositoryName(); 138 } 139 140 @Override 141 public ObjectId createObjectId(String id) { 142 return new ObjectIdImpl(id); 143 } 144 145 @Override 146 public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream, 147 VersioningState versioningState) { 148 return createDocument(properties, folderId, contentStream, versioningState, null, null, null); 149 } 150 151 /** Converts from an untyped map to a {@link Properties} object. */ 152 protected Properties convertProperties(Map<String, ?> properties) { 153 if (properties == null) { 154 return null; 155 } 156 // find type 157 String typeId = (String) properties.get(PropertyIds.OBJECT_TYPE_ID); 158 if (typeId == null) { 159 throw new IllegalArgumentException("Missing type"); 160 } 161 ObjectType type = getTypeDefinition(typeId); 162 if (type == null) { 163 throw new IllegalArgumentException("Unknown type: " + typeId); 164 } 165 return objectFactory.convertProperties(properties, type, null, null); 166 } 167 168 @Override 169 public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream, 170 VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) { 171 String id = service.createDocument(repositoryId, convertProperties(properties), folderId == null ? null 172 : folderId.getId(), contentStream, versioningState, objectFactory.convertPolicies(policies), 173 objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null); 174 return createObjectId(id); 175 } 176 177 @Override 178 public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId) { 179 return createFolder(properties, folderId, null, null, null); 180 } 181 182 @Override 183 public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId, List<Policy> policies, 184 List<Ace> addAces, List<Ace> removeAces) { 185 String id = service.createFolder(repositoryId, convertProperties(properties), folderId == null ? null 186 : folderId.getId(), objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces), 187 objectFactory.convertAces(removeAces), null); 188 return createObjectId(id); 189 } 190 191 @Override 192 public OperationContext createOperationContext() { 193 return new OperationContextImpl(); 194 } 195 196 @Override 197 public OperationContext createOperationContext(Set<String> filter, boolean includeAcls, 198 boolean includeAllowableActions, boolean includePolicies, IncludeRelationships includeRelationships, 199 Set<String> renditionFilter, boolean includePathSegments, String orderBy, boolean cacheEnabled, 200 int maxItemsPerPage) { 201 // TODO Auto-generated method stub 202 throw new UnsupportedOperationException(); 203 } 204 205 @Override 206 public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId) { 207 return createPolicy(properties, folderId, null, null, null); 208 } 209 210 @Override 211 public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId, List<Policy> policies, 212 List<Ace> addAces, List<Ace> removeAces) { 213 // TODO Auto-generated method stub 214 throw new UnsupportedOperationException(); 215 } 216 217 @Override 218 public ObjectId createRelationship(Map<String, ?> properties) { 219 return createRelationship(properties, null, null, null); 220 } 221 222 @Override 223 public ObjectId createRelationship(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces, 224 List<Ace> removeAces) { 225 String id = service.createRelationship(repositoryId, convertProperties(properties), 226 objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces), 227 objectFactory.convertAces(removeAces), null); 228 return createObjectId(id); 229 } 230 231 @Override 232 public ObjectId createItem(Map<String, ?> properties, ObjectId folderId, List<Policy> policies, List<Ace> addAces, 233 List<Ace> removeAces) { 234 throw new CmisNotSupportedException(); 235 } 236 237 @Override 238 public ObjectId createItem(Map<String, ?> properties, ObjectId folderId) { 239 throw new CmisNotSupportedException(); 240 } 241 242 @Override 243 public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId, 244 VersioningState versioningState) { 245 return createDocumentFromSource(source, properties, folderId, versioningState, null, null, null); 246 } 247 248 @Override 249 public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId, 250 VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) { 251 // TODO Auto-generated method stub 252 throw new UnsupportedOperationException(); 253 } 254 255 @Override 256 public ItemIterable<Document> getCheckedOutDocs() { 257 // TODO Auto-generated method stub 258 throw new UnsupportedOperationException(); 259 } 260 261 @Override 262 public ItemIterable<Document> getCheckedOutDocs(OperationContext context) { 263 // TODO Auto-generated method stub 264 throw new UnsupportedOperationException(); 265 } 266 267 @Override 268 public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems) { 269 return getContentChanges(changeLogToken, includeProperties, maxNumItems, getDefaultContext()); 270 } 271 272 @Override 273 public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems, 274 OperationContext context) { 275 // TODO Auto-generated method stub 276 throw new UnsupportedOperationException(); 277 } 278 279 @Override 280 public ItemIterable<ChangeEvent> getContentChanges(String changeLogToken, boolean includeProperties) { 281 return getContentChanges(changeLogToken, includeProperties, getDefaultContext()); 282 }; 283 284 @Override 285 public ItemIterable<ChangeEvent> getContentChanges(String changeLogToken, boolean includeProperties, 286 OperationContext context) { 287 // TODO Auto-generated method stub 288 throw new UnsupportedOperationException(); 289 }; 290 291 @Override 292 public Locale getLocale() { 293 // TODO Auto-generated method stub 294 throw new UnsupportedOperationException(); 295 } 296 297 @Override 298 public CmisObject getObject(ObjectId objectId) { 299 return getObject(objectId, getDefaultContext()); 300 } 301 302 @Override 303 public CmisObject getObject(String objectId) { 304 return getObject(objectId, getDefaultContext()); 305 } 306 307 /** Gets a CMIS object given a Nuxeo {@link DocumentModel}. */ 308 public CmisObject getObject(DocumentModel doc, OperationContext context) { 309 ObjectData data = new NuxeoObjectData(service, doc, context); 310 return objectFactory.convertObject(data, context); 311 } 312 313 @Override 314 public CmisObject getObject(ObjectId objectId, OperationContext context) { 315 if (objectId == null) { 316 throw new CmisInvalidArgumentException("Missing object ID"); 317 } 318 return getObject(objectId.getId(), context); 319 } 320 321 @Override 322 public CmisObject getObject(String objectId, OperationContext context) { 323 if (objectId == null) { 324 throw new CmisInvalidArgumentException("Missing object ID"); 325 } 326 if (context == null) { 327 throw new CmisInvalidArgumentException("Missing operation context"); 328 } 329 ObjectData data = service.getObject(repositoryId, objectId, context.getFilterString(), 330 Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(), 331 context.getRenditionFilterString(), Boolean.valueOf(context.isIncludePolicies()), 332 Boolean.valueOf(context.isIncludeAcls()), null); 333 return objectFactory.convertObject(data, context); 334 } 335 336 @Override 337 public CmisObject getObjectByPath(String path) { 338 return getObjectByPath(path, getDefaultContext()); 339 } 340 341 @Override 342 public CmisObject getObjectByPath(String path, OperationContext context) { 343 if (path == null || !path.startsWith("/")) { 344 throw new CmisInvalidArgumentException("Invalid path: " + path); 345 } 346 if (context == null) { 347 throw new CmisInvalidArgumentException("Missing operation context"); 348 } 349 ObjectData data = service.getObjectByPath(repositoryId, path, context.getFilterString(), 350 Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(), 351 context.getRenditionFilterString(), Boolean.valueOf(context.isIncludePolicies()), 352 Boolean.valueOf(context.isIncludeAcls()), null); 353 return getObjectFactory().convertObject(data, context); 354 } 355 356 @Override 357 public RepositoryInfo getRepositoryInfo() { 358 return service.getRepositoryInfo(repositoryId, null); 359 } 360 361 @Override 362 public Folder getRootFolder() { 363 return getRootFolder(getDefaultContext()); 364 } 365 366 @Override 367 public Folder getRootFolder(OperationContext context) { 368 String id = getRepositoryInfo().getRootFolderId(); 369 CmisObject folder = getObject(createObjectId(id), context); 370 if (!(folder instanceof Folder)) { 371 throw new CmisRuntimeException("Root object is not a Folder but: " + folder.getClass().getName()); 372 } 373 return (Folder) folder; 374 } 375 376 @Override 377 public ItemIterable<ObjectType> getTypeChildren(String typeId, boolean includePropertyDefinitions) { 378 // TODO Auto-generated method stub 379 throw new UnsupportedOperationException(); 380 } 381 382 @Override 383 public ObjectType getTypeDefinition(String typeId) { 384 TypeDefinition typeDefinition = service.getTypeDefinition(repositoryId, typeId, null); 385 return objectFactory.convertTypeDefinition(typeDefinition); 386 } 387 388 @Override 389 public ObjectType getTypeDefinition(String typeId, boolean useCache) { 390 return getTypeDefinition(typeId); 391 } 392 393 @Override 394 public List<Tree<ObjectType>> getTypeDescendants(String typeId, int depth, boolean includePropertyDefinitions) { 395 // TODO Auto-generated method stub 396 throw new UnsupportedOperationException(); 397 } 398 399 @Override 400 public ItemIterable<QueryResult> query(String statement, boolean searchAllVersions) { 401 // TODO Auto-generated method stub 402 throw new UnsupportedOperationException(); 403 } 404 405 @Override 406 public ItemIterable<QueryResult> query(final String statement, final boolean searchAllVersions, 407 final OperationContext context) { 408 AbstractPageFetcher<QueryResult> pageFetcher = new AbstractPageFetcher<QueryResult>( 409 context.getMaxItemsPerPage()) { 410 @Override 411 protected Page<QueryResult> fetchPage(long skipCount) { 412 ObjectList results = service.query(repositoryId, statement, Boolean.valueOf(searchAllVersions), 413 Boolean.valueOf(context.isIncludeAllowableActions()), context.getIncludeRelationships(), 414 context.getRenditionFilterString(), BigInteger.valueOf(maxNumItems), 415 BigInteger.valueOf(skipCount), null); 416 // convert objects 417 List<QueryResult> page = new ArrayList<QueryResult>(); 418 if (results.getObjects() != null) { 419 for (ObjectData data : results.getObjects()) { 420 page.add(new QueryResultImpl(NuxeoSession.this, data)); 421 } 422 } 423 return new Page<QueryResult>(page, results.getNumItems(), results.hasMoreItems()); 424 } 425 }; 426 return new CollectionIterable<QueryResult>(pageFetcher); 427 } 428 429 @Override 430 public ItemIterable<CmisObject> queryObjects(String typeId, String where, boolean searchAllVersions, 431 OperationContext context) { 432 // TODO Auto-generated method stub 433 throw new UnsupportedOperationException(); 434 } 435 436 @Override 437 public QueryStatement createQueryStatement(String statement) { 438 return new QueryStatementImpl(this, statement); 439 } 440 441 @Override 442 public QueryStatement createQueryStatement(Collection<String> selectPropertyIds, Map<String, String> fromTypes, 443 String whereClause, List<String> orderByPropertyIds) { 444 return new QueryStatementImpl(this, selectPropertyIds, fromTypes, whereClause, orderByPropertyIds); 445 } 446 447 @Override 448 public ItemIterable<Relationship> getRelationships(final ObjectId objectId, 449 final boolean includeSubRelationshipTypes, final RelationshipDirection relationshipDirection, 450 final ObjectType type, final OperationContext context) { 451 final String typeId = type == null ? null : type.getId(); 452 AbstractPageFetcher<Relationship> pageFetcher = new AbstractPageFetcher<Relationship>( 453 context.getMaxItemsPerPage()) { 454 @Override 455 protected Page<Relationship> fetchPage(long skipCount) { 456 ObjectList relations = service.getObjectRelationships(repositoryId, objectId.getId(), 457 Boolean.valueOf(includeSubRelationshipTypes), relationshipDirection, typeId, null, null, 458 BigInteger.valueOf(maxNumItems), BigInteger.valueOf(skipCount), null); 459 // convert objects 460 List<Relationship> page = new ArrayList<Relationship>(); 461 if (relations.getObjects() != null) { 462 for (ObjectData data : relations.getObjects()) { 463 CmisObject ob; 464 if (data instanceof NuxeoObjectData) { 465 ob = objectFactory.convertObject(data, context); 466 } else { 467 ob = getObject(data.getId(), context); 468 } 469 if (!(ob instanceof Relationship)) { 470 // should not happen... 471 continue; 472 } 473 page.add((Relationship) ob); 474 } 475 } 476 return new Page<Relationship>(page, relations.getNumItems(), relations.hasMoreItems()); 477 } 478 }; 479 return new CollectionIterable<Relationship>(pageFetcher); 480 } 481 482 @Override 483 public Acl getAcl(ObjectId objectId, boolean onlyBasicPermissions) { 484 return service.getAcl(repositoryId, objectId.getId(), Boolean.valueOf(onlyBasicPermissions), null); 485 } 486 487 @Override 488 public Acl setAcl(ObjectId objectId, List<Ace> aces) { 489 return service.applyAcl(repositoryId, objectId.getId(), new AccessControlListImpl(aces), null); 490 } 491 492 @Override 493 public Acl applyAcl(ObjectId objectId, List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) { 494 return service.applyAcl(repositoryId, objectId.getId(), new AccessControlListImpl(addAces), 495 new AccessControlListImpl(removeAces), aclPropagation, null); 496 } 497 498 @Override 499 public void applyPolicy(ObjectId objectId, ObjectId... policyIds) { 500 throw new CmisNotSupportedException(); 501 } 502 503 @Override 504 public void removePolicy(ObjectId objectId, ObjectId... policyIds) { 505 throw new CmisNotSupportedException(); 506 } 507 508 @Override 509 public void removeObjectFromCache(ObjectId objectId) { 510 } 511 512 @Override 513 public void removeObjectFromCache(String objectId) { 514 } 515 516 @Override 517 public void delete(ObjectId objectId) { 518 delete(objectId, true); 519 } 520 521 @Override 522 public void delete(ObjectId objectId, boolean allVersions) { 523 service.deleteObject(repositoryId, objectId.getId(), Boolean.valueOf(allVersions), null); 524 } 525 526 @Override 527 public ContentStream getContentStream(ObjectId docId) { 528 return getContentStream(docId, null, null, null); 529 } 530 531 @Override 532 public ContentStream getContentStream(ObjectId docId, String streamId, BigInteger offset, BigInteger length) { 533 if (docId == null) { 534 throw new CmisInvalidArgumentException("Missing object ID"); 535 } 536 return service.getContentStream(repositoryId, docId.getId(), streamId, offset, length, null); 537 } 538 539 @Override 540 public ObjectType createType(TypeDefinition type) { 541 throw new CmisNotSupportedException(); 542 } 543 544 @Override 545 public ObjectType updateType(TypeDefinition type) { 546 throw new CmisNotSupportedException(); 547 } 548 549 @Override 550 public void deleteType(String typeId) { 551 throw new CmisNotSupportedException(); 552 } 553 554 @Override 555 public List<BulkUpdateObjectIdAndChangeToken> bulkUpdateProperties(List<CmisObject> objects, 556 Map<String, ?> properties, List<String> addSecondaryTypeIds, List<String> removeSecondaryTypeIds) { 557 List<BulkUpdateObjectIdAndChangeToken> idts = new ArrayList<BulkUpdateObjectIdAndChangeToken>(objects.size()); 558 for (CmisObject object : objects) { 559 idts.add(new BulkUpdateObjectIdAndChangeTokenImpl(object.getId(), object.getChangeToken())); 560 } 561 return service.bulkUpdateProperties(repositoryId, idts, convertProperties(properties), addSecondaryTypeIds, 562 removeSecondaryTypeIds, null); 563 } 564 565 @Override 566 public Document getLatestDocumentVersion(ObjectId objectId) { 567 return getLatestDocumentVersion(objectId, false, getDefaultContext()); 568 } 569 570 @Override 571 public Document getLatestDocumentVersion(String objectId, OperationContext context) { 572 if (objectId == null) { 573 throw new IllegalArgumentException("Object ID must be set!"); 574 } 575 return getLatestDocumentVersion(createObjectId(objectId), false, context); 576 } 577 578 @Override 579 public Document getLatestDocumentVersion(String objectId, boolean major, OperationContext context) { 580 if (objectId == null) { 581 throw new IllegalArgumentException("Object ID must be set!"); 582 } 583 return getLatestDocumentVersion(createObjectId(objectId), major, context); 584 } 585 586 @Override 587 public Document getLatestDocumentVersion(String objectId) { 588 if (objectId == null) { 589 throw new IllegalArgumentException("Object ID must be set!"); 590 } 591 return getLatestDocumentVersion(createObjectId(objectId), false, getDefaultContext()); 592 } 593 594 @Override 595 public Document getLatestDocumentVersion(ObjectId objectId, OperationContext context) { 596 return getLatestDocumentVersion(objectId, false, context); 597 } 598 599 @Override 600 /** 601 * @See org.apache.chemistry.opencmis.client.runtime.SessionImpl 602 */ 603 public Document getLatestDocumentVersion(ObjectId objectId, boolean major, OperationContext context) { 604 if (objectId == null || objectId.getId() == null) { 605 throw new IllegalArgumentException("Object ID must be set!"); 606 } 607 608 if (context == null) { 609 throw new IllegalArgumentException("Operation context must be set!"); 610 } 611 612 CmisObject result = null; 613 614 String versionSeriesId = null; 615 616 // first attempt: if we got a Document object, try getting the version 617 // series ID from it 618 if (objectId instanceof Document) { 619 versionSeriesId = ((Document) objectId).getVersionSeriesId(); 620 } 621 622 // third attempt (Web Services only): get the version series ID from the 623 // repository 624 // (the AtomPub and Browser binding don't need the version series ID -> 625 // avoid roundtrip) 626 if (versionSeriesId == null) { 627 BindingType bindingType = getBinding().getBindingType(); 628 if (bindingType == BindingType.WEBSERVICES || bindingType == BindingType.CUSTOM) { 629 630 // get the document to find the version series ID 631 ObjectData sourceObjectData = binding.getObjectService().getObject(getRepositoryId(), objectId.getId(), 632 PropertyIds.OBJECT_ID + "," + PropertyIds.VERSION_SERIES_ID, false, IncludeRelationships.NONE, 633 "cmis:none", false, false, null); 634 635 if (sourceObjectData.getProperties() != null 636 && sourceObjectData.getProperties().getProperties() != null) { 637 PropertyData<?> verionsSeriesIdProp = sourceObjectData.getProperties().getProperties().get( 638 PropertyIds.VERSION_SERIES_ID); 639 if (verionsSeriesIdProp != null && verionsSeriesIdProp.getFirstValue() instanceof String) { 640 versionSeriesId = (String) verionsSeriesIdProp.getFirstValue(); 641 } 642 } 643 644 // the Web Services binding needs the version series ID -> fail 645 if (versionSeriesId == null) { 646 throw new IllegalArgumentException("Object is not a document or not versionable!"); 647 } 648 } 649 } 650 651 // get the object 652 ObjectData objectData = binding.getVersioningService().getObjectOfLatestVersion(getRepositoryId(), 653 objectId.getId(), versionSeriesId, major, context.getFilterString(), 654 context.isIncludeAllowableActions(), context.getIncludeRelationships(), 655 context.getRenditionFilterString(), context.isIncludePolicies(), context.isIncludeAcls(), null); 656 657 result = getObjectFactory().convertObject(objectData, context); 658 659 // check result 660 if (!(result instanceof Document)) { 661 throw new IllegalArgumentException("Latest version is not a document!"); 662 } 663 664 return (Document) result; 665 } 666 667 @Override 668 public String getLatestChangeLogToken() { 669 return getBinding().getRepositoryService().getRepositoryInfo(getRepositoryId(), null).getLatestChangeLogToken(); 670 } 671 672}