001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.cmis; 029 030import static org.opencms.cmis.CmsCmisUtil.addAction; 031import static org.opencms.cmis.CmsCmisUtil.addPropertyBoolean; 032import static org.opencms.cmis.CmsCmisUtil.addPropertyDateTime; 033import static org.opencms.cmis.CmsCmisUtil.addPropertyId; 034import static org.opencms.cmis.CmsCmisUtil.addPropertyIdList; 035import static org.opencms.cmis.CmsCmisUtil.addPropertyInteger; 036import static org.opencms.cmis.CmsCmisUtil.addPropertyString; 037import static org.opencms.cmis.CmsCmisUtil.ensureLock; 038import static org.opencms.cmis.CmsCmisUtil.getAcePrincipalName; 039import static org.opencms.cmis.CmsCmisUtil.getCmisPermissions; 040import static org.opencms.cmis.CmsCmisUtil.getNativePermissions; 041import static org.opencms.cmis.CmsCmisUtil.handleCmsException; 042import static org.opencms.cmis.CmsCmisUtil.hasChildren; 043import static org.opencms.cmis.CmsCmisUtil.millisToCalendar; 044import static org.opencms.cmis.CmsCmisUtil.splitFilter; 045 046import org.opencms.file.CmsObject; 047import org.opencms.file.CmsProperty; 048import org.opencms.file.CmsResource; 049import org.opencms.file.CmsResourceFilter; 050import org.opencms.file.CmsUser; 051import org.opencms.file.types.I_CmsResourceType; 052import org.opencms.loader.CmsResourceManager; 053import org.opencms.lock.CmsLock; 054import org.opencms.main.CmsException; 055import org.opencms.main.OpenCms; 056import org.opencms.relations.CmsRelation; 057import org.opencms.relations.CmsRelationFilter; 058import org.opencms.security.CmsAccessControlEntry; 059import org.opencms.security.CmsPermissionSet; 060import org.opencms.util.CmsUUID; 061 062import java.util.ArrayList; 063import java.util.GregorianCalendar; 064import java.util.LinkedHashSet; 065import java.util.List; 066import java.util.Set; 067 068import org.apache.chemistry.opencmis.commons.PropertyIds; 069import org.apache.chemistry.opencmis.commons.data.Ace; 070import org.apache.chemistry.opencmis.commons.data.Acl; 071import org.apache.chemistry.opencmis.commons.data.AllowableActions; 072import org.apache.chemistry.opencmis.commons.data.ObjectData; 073import org.apache.chemistry.opencmis.commons.data.Properties; 074import org.apache.chemistry.opencmis.commons.data.RenditionData; 075import org.apache.chemistry.opencmis.commons.enums.Action; 076import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; 077import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; 078import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection; 079import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException; 080import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; 081import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; 082import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; 083import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException; 084import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl; 085import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl; 086import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl; 087import org.apache.chemistry.opencmis.commons.impl.dataobjects.AllowableActionsImpl; 088import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectDataImpl; 089import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl; 090import org.apache.chemistry.opencmis.commons.impl.server.ObjectInfoImpl; 091import org.apache.chemistry.opencmis.commons.impl.server.RenditionInfoImpl; 092import org.apache.chemistry.opencmis.commons.server.RenditionInfo; 093 094/** 095 * Helper class for CRUD operations on resources.<p> 096 */ 097public class CmsCmisResourceHelper implements I_CmsCmisObjectHelper { 098 099 /** The underlying repository. */ 100 private CmsCmisRepository m_repository; 101 102 /** 103 * Creates a new instance.<p> 104 * 105 * @param repository the underlying repository 106 */ 107 public CmsCmisResourceHelper(CmsCmisRepository repository) { 108 109 m_repository = repository; 110 } 111 112 /** 113 * Deletes a CMIS object.<p> 114 * 115 * @param context the call context 116 * @param objectId the id of the object to delete 117 * @param allVersions flag to delete all version 118 */ 119 public synchronized void deleteObject(CmsCmisCallContext context, String objectId, boolean allVersions) { 120 121 try { 122 CmsObject cms = m_repository.getCmsObject(context); 123 CmsUUID structureId = new CmsUUID(objectId); 124 CmsResource resource = cms.readResource(structureId); 125 if (resource.isFolder()) { 126 boolean isLeaf = !hasChildren(cms, resource); 127 if (!isLeaf) { 128 throw new CmisConstraintException("Only leaf resources can be deleted."); 129 } 130 } 131 ensureLock(cms, resource); 132 cms.deleteResource(resource.getRootPath(), CmsResource.DELETE_PRESERVE_SIBLINGS); 133 } catch (CmsException e) { 134 handleCmsException(e); 135 } 136 } 137 138 /** 139 * Gets the ACL for an object.<p> 140 * 141 * @param context the call context 142 * @param objectId the object id 143 * @param onlyBasicPermissions flag to only get basic permissions 144 * 145 * @return the ACL for the object 146 */ 147 public synchronized Acl getAcl(CmsCmisCallContext context, String objectId, boolean onlyBasicPermissions) { 148 149 try { 150 151 CmsObject cms = m_repository.getCmsObject(context); 152 CmsUUID structureId = new CmsUUID(objectId); 153 CmsResource resource = cms.readResource(structureId); 154 return collectAcl(cms, resource, onlyBasicPermissions); 155 } catch (CmsException e) { 156 handleCmsException(e); 157 return null; 158 } 159 160 } 161 162 /** 163 * Gets the allowable actions for an object.<p> 164 * 165 * @param context the call context 166 * @param objectId the object id 167 * @return the allowable actions 168 */ 169 public synchronized AllowableActions getAllowableActions(CmsCmisCallContext context, String objectId) { 170 171 try { 172 CmsObject cms = m_repository.getCmsObject(context); 173 CmsUUID structureId = new CmsUUID(objectId); 174 CmsResource file = cms.readResource(structureId); 175 return collectAllowableActions(cms, file); 176 } catch (CmsException e) { 177 handleCmsException(e); 178 return null; 179 } 180 } 181 182 /** 183 * Gets the data for a CMIS object.<p> 184 * 185 * @param context the CMIS call context 186 * @param objectId the id of the object 187 * @param filter the property filter 188 * @param includeAllowableActions flag to include allowable actions 189 * @param includeRelationships flag to include relationships 190 * @param renditionFilter the rendition filter string 191 * @param includePolicyIds flag to include policy ids 192 * @param includeAcl flag to include ACLs 193 * 194 * @return the CMIS object data 195 */ 196 public synchronized ObjectData getObject( 197 CmsCmisCallContext context, 198 String objectId, 199 String filter, 200 boolean includeAllowableActions, 201 IncludeRelationships includeRelationships, 202 String renditionFilter, 203 boolean includePolicyIds, 204 boolean includeAcl) { 205 206 try { 207 // if (renditionFilter.equals("cmis:none") && context.isObjectInfoRequired()) { 208 // renditionFilter = "*"; 209 // } 210 // check id 211 if (objectId == null) { 212 throw new CmisInvalidArgumentException("Object Id must be set."); 213 } 214 CmsObject cms = m_repository.getCmsObject(context); 215 // get the file or folder 216 CmsResource file = cms.readResource(new CmsUUID(objectId)); 217 218 // split filter 219 Set<String> filterCollection = splitFilter(filter); 220 221 // gather properties 222 return collectObjectData( 223 context, 224 cms, 225 file, 226 filterCollection, 227 renditionFilter, 228 includeAllowableActions, 229 includeAcl, 230 includeRelationships); 231 } catch (CmsException e) { 232 handleCmsException(e); 233 return null; 234 } 235 } 236 237 /** 238 * Compiles the ACL for a file or folder. 239 * @param cms the CMS context 240 * @param resource the resource for which to collect the ACLs 241 * @param onlyBasic flag to only include basic ACEs 242 * 243 * @return the ACL for the resource 244 * @throws CmsException if something goes wrong 245 */ 246 protected Acl collectAcl(CmsObject cms, CmsResource resource, boolean onlyBasic) throws CmsException { 247 248 AccessControlListImpl cmisAcl = new AccessControlListImpl(); 249 List<Ace> cmisAces = new ArrayList<Ace>(); 250 List<CmsAccessControlEntry> aces = cms.getAccessControlEntries(resource.getRootPath(), true); 251 for (CmsAccessControlEntry ace : aces) { 252 boolean isDirect = ace.getResource().equals(resource.getResourceId()); 253 CmsUUID principalId = ace.getPrincipal(); 254 String principalName = getAcePrincipalName(cms, principalId); 255 AccessControlEntryImpl cmisAce = new AccessControlEntryImpl(); 256 AccessControlPrincipalDataImpl cmisPrincipal = new AccessControlPrincipalDataImpl(); 257 cmisPrincipal.setPrincipalId(principalName); 258 cmisAce.setPrincipal(cmisPrincipal); 259 cmisAce.setPermissions(onlyBasic ? getCmisPermissions(ace) : getNativePermissions(ace)); 260 cmisAce.setDirect(isDirect); 261 cmisAces.add(cmisAce); 262 } 263 cmisAcl.setAces(cmisAces); 264 cmisAcl.setExact(Boolean.FALSE); 265 return cmisAcl; 266 } 267 268 /** 269 * Compiles the allowable actions for a file or folder. 270 * 271 * @param cms the current CMS context 272 * @param file the resource for which we want the allowable actions 273 * 274 * @return the allowable actions for the given resource 275 */ 276 protected AllowableActions collectAllowableActions(CmsObject cms, CmsResource file) { 277 278 try { 279 280 if (file == null) { 281 throw new IllegalArgumentException("File must not be null!"); 282 } 283 CmsLock lock = cms.getLock(file); 284 CmsUser user = cms.getRequestContext().getCurrentUser(); 285 boolean canWrite = !cms.getRequestContext().getCurrentProject().isOnlineProject() 286 && (lock.isOwnedBy(user) || lock.isLockableBy(user)) 287 && cms.hasPermissions(file, CmsPermissionSet.ACCESS_WRITE, false, CmsResourceFilter.DEFAULT); 288 boolean isReadOnly = !canWrite; 289 boolean isFolder = file.isFolder(); 290 boolean isRoot = file.getRootPath().length() <= 1; 291 292 Set<Action> aas = new LinkedHashSet<Action>(); 293 addAction(aas, Action.CAN_GET_OBJECT_PARENTS, !isRoot); 294 addAction(aas, Action.CAN_GET_PROPERTIES, true); 295 addAction(aas, Action.CAN_UPDATE_PROPERTIES, !isReadOnly); 296 addAction(aas, Action.CAN_MOVE_OBJECT, !isReadOnly); 297 addAction(aas, Action.CAN_DELETE_OBJECT, !isReadOnly && !isRoot); 298 if (isFolder) { 299 addAction(aas, Action.CAN_GET_DESCENDANTS, true); 300 addAction(aas, Action.CAN_GET_CHILDREN, true); 301 addAction(aas, Action.CAN_GET_FOLDER_PARENT, !isRoot); 302 addAction(aas, Action.CAN_GET_FOLDER_TREE, true); 303 addAction(aas, Action.CAN_CREATE_DOCUMENT, !isReadOnly); 304 addAction(aas, Action.CAN_CREATE_FOLDER, !isReadOnly); 305 addAction(aas, Action.CAN_DELETE_TREE, !isReadOnly); 306 } else { 307 addAction(aas, Action.CAN_GET_CONTENT_STREAM, true); 308 addAction(aas, Action.CAN_SET_CONTENT_STREAM, !isReadOnly); 309 addAction(aas, Action.CAN_GET_ALL_VERSIONS, true); 310 } 311 AllowableActionsImpl result = new AllowableActionsImpl(); 312 result.setAllowableActions(aas); 313 return result; 314 } catch (CmsException e) { 315 handleCmsException(e); 316 return null; 317 } 318 } 319 320 /** 321 * Fills in an ObjectData record.<p> 322 * 323 * @param context the call context 324 * @param cms the CMS context 325 * @param resource the resource for which we want the ObjectData 326 * @param filter the property filter 327 * @param renditionFilter the rendition filter string 328 * @param includeAllowableActions true if the allowable actions should be included 329 * @param includeAcl true if the ACL entries should be included 330 * @param includeRelationships true if relationships should be included 331 * 332 * @return the object data 333 * @throws CmsException if something goes wrong 334 */ 335 protected ObjectData collectObjectData( 336 CmsCmisCallContext context, 337 CmsObject cms, 338 CmsResource resource, 339 Set<String> filter, 340 String renditionFilter, 341 boolean includeAllowableActions, 342 boolean includeAcl, 343 IncludeRelationships includeRelationships) throws CmsException { 344 345 ObjectDataImpl result = new ObjectDataImpl(); 346 ObjectInfoImpl objectInfo = new ObjectInfoImpl(); 347 result.setProperties(collectProperties(cms, resource, filter, objectInfo)); 348 349 if (includeAllowableActions) { 350 result.setAllowableActions(collectAllowableActions(cms, resource)); 351 } 352 353 if (includeAcl) { 354 result.setAcl(collectAcl(cms, resource, true)); 355 result.setIsExactAcl(Boolean.FALSE); 356 } 357 358 if ((includeRelationships != null) && (includeRelationships != IncludeRelationships.NONE)) { 359 RelationshipDirection direction; 360 if (includeRelationships == IncludeRelationships.SOURCE) { 361 direction = RelationshipDirection.SOURCE; 362 } else if (includeRelationships == IncludeRelationships.TARGET) { 363 direction = RelationshipDirection.TARGET; 364 } else { 365 direction = RelationshipDirection.EITHER; 366 } 367 368 List<ObjectData> relationData = m_repository.getRelationshipObjectData( 369 context, 370 cms, 371 resource, 372 direction, 373 CmsCmisUtil.splitFilter("*"), 374 false); 375 result.setRelationships(relationData); 376 } 377 378 result.setRenditions(collectRenditions(cms, resource, renditionFilter, objectInfo)); 379 380 if (context.isObjectInfoRequired()) { 381 objectInfo.setObject(result); 382 context.getObjectInfoHandler().addObjectInfo(objectInfo); 383 } 384 return result; 385 } 386 387 /** 388 * Gathers all base properties of a file or folder. 389 * 390 * @param cms the current CMS context 391 * @param resource the file for which we want the properties 392 * @param orgfilter the property filter 393 * @param objectInfo the object info handler 394 * 395 * @return the properties for the given resource 396 */ 397 protected Properties collectProperties( 398 CmsObject cms, 399 CmsResource resource, 400 Set<String> orgfilter, 401 ObjectInfoImpl objectInfo) { 402 403 CmsCmisTypeManager tm = m_repository.getTypeManager(); 404 405 if (resource == null) { 406 throw new IllegalArgumentException("Resource may not be null."); 407 } 408 409 // copy filter 410 Set<String> filter = (orgfilter == null ? null : new LinkedHashSet<String>(orgfilter)); 411 412 // find base type 413 String typeId = null; 414 415 List<String> relationSourceIds = new ArrayList<String>(); 416 List<String> relationTargetIds = new ArrayList<String>(); 417 try { 418 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.ALL); 419 for (CmsRelation relation : relations) { 420 if (resource.getStructureId().equals(relation.getSourceId())) { 421 relationTargetIds.add(relation.getTargetId().toString()); 422 } 423 if (resource.getStructureId().equals(relation.getTargetId())) { 424 relationSourceIds.add(relation.getSourceId().toString()); 425 } 426 } 427 } catch (CmsException e) { 428 throw new CmisStorageException(e.getLocalizedMessage(), e); 429 } 430 431 if (resource.isFolder()) { 432 typeId = CmsCmisTypeManager.FOLDER_TYPE_ID; 433 objectInfo.setBaseType(BaseTypeId.CMIS_FOLDER); 434 objectInfo.setTypeId(typeId); 435 objectInfo.setContentType(null); 436 objectInfo.setFileName(null); 437 objectInfo.setHasAcl(true); 438 objectInfo.setHasContent(false); 439 objectInfo.setVersionSeriesId(null); 440 objectInfo.setIsCurrentVersion(true); 441 objectInfo.setRelationshipSourceIds(relationSourceIds); 442 objectInfo.setRelationshipTargetIds(relationTargetIds); 443 objectInfo.setSupportsDescendants(true); 444 objectInfo.setSupportsFolderTree(true); 445 objectInfo.setSupportsPolicies(false); 446 objectInfo.setSupportsRelationships(true); 447 objectInfo.setWorkingCopyId(null); 448 objectInfo.setWorkingCopyOriginalId(null); 449 } else { 450 typeId = CmsCmisTypeManager.DOCUMENT_TYPE_ID; 451 objectInfo.setBaseType(BaseTypeId.CMIS_DOCUMENT); 452 objectInfo.setTypeId(typeId); 453 objectInfo.setHasAcl(true); 454 objectInfo.setHasContent(true); 455 objectInfo.setHasParent(true); 456 objectInfo.setVersionSeriesId(null); 457 objectInfo.setIsCurrentVersion(true); 458 objectInfo.setRelationshipSourceIds(relationSourceIds); 459 objectInfo.setRelationshipTargetIds(relationTargetIds); 460 objectInfo.setSupportsDescendants(false); 461 objectInfo.setSupportsFolderTree(false); 462 objectInfo.setSupportsPolicies(false); 463 objectInfo.setSupportsRelationships(true); 464 objectInfo.setWorkingCopyId(null); 465 objectInfo.setWorkingCopyOriginalId(null); 466 } 467 try { 468 PropertiesImpl result = new PropertiesImpl(); 469 470 String id = resource.getStructureId().toString(); 471 addPropertyId(tm, result, typeId, filter, PropertyIds.OBJECT_ID, id); 472 objectInfo.setId(id); 473 474 String name = resource.getName(); 475 if ("".equals(name)) { 476 name = "/"; 477 } 478 addPropertyString(tm, result, typeId, filter, PropertyIds.NAME, name); 479 objectInfo.setName(name); 480 481 // created and modified by 482 CmsUUID creatorId = resource.getUserCreated(); 483 CmsUUID modifierId = resource.getUserLastModified(); 484 String creatorName = creatorId.toString(); 485 String modifierName = modifierId.toString(); 486 try { 487 CmsUser user = cms.readUser(creatorId); 488 creatorName = user.getName(); 489 } catch (CmsException e) { 490 // ignore, use id as name 491 } 492 try { 493 CmsUser user = cms.readUser(modifierId); 494 modifierName = user.getName(); 495 } catch (CmsException e) { 496 // ignore, use id as name 497 } 498 499 addPropertyString(tm, result, typeId, filter, PropertyIds.CREATED_BY, creatorName); 500 addPropertyString(tm, result, typeId, filter, PropertyIds.LAST_MODIFIED_BY, modifierName); 501 objectInfo.setCreatedBy(creatorName); 502 503 // creation and modification date 504 GregorianCalendar lastModified = millisToCalendar(resource.getDateLastModified()); 505 GregorianCalendar created = millisToCalendar(resource.getDateCreated()); 506 507 addPropertyDateTime(tm, result, typeId, filter, PropertyIds.CREATION_DATE, created); 508 addPropertyDateTime(tm, result, typeId, filter, PropertyIds.LAST_MODIFICATION_DATE, lastModified); 509 objectInfo.setCreationDate(created); 510 objectInfo.setLastModificationDate(lastModified); 511 512 // change token - always null 513 addPropertyString(tm, result, typeId, filter, PropertyIds.CHANGE_TOKEN, null); 514 515 // directory or file 516 if (resource.isFolder()) { 517 // base type and type name 518 addPropertyId(tm, result, typeId, filter, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_FOLDER.value()); 519 addPropertyId( 520 tm, 521 result, 522 typeId, 523 filter, 524 PropertyIds.OBJECT_TYPE_ID, 525 CmsCmisTypeManager.FOLDER_TYPE_ID); 526 String path = resource.getRootPath(); 527 addPropertyString(tm, result, typeId, filter, PropertyIds.PATH, (path.length() == 0 ? "/" : path)); 528 529 // folder properties 530 if (resource.getRootPath().length() > 1) { 531 CmsResource parent = cms.readParentFolder(resource.getStructureId()); 532 addPropertyId(tm, result, typeId, filter, PropertyIds.PARENT_ID, ( 533 534 parent.getStructureId().toString())); 535 objectInfo.setHasParent(true); 536 } else { 537 addPropertyId(tm, result, typeId, filter, PropertyIds.PARENT_ID, null); 538 objectInfo.setHasParent(false); 539 } 540 541 addPropertyIdList(tm, result, typeId, filter, PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, null); 542 } else { 543 // base type and type name 544 addPropertyId(tm, result, typeId, filter, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value()); 545 addPropertyId( 546 tm, 547 result, 548 typeId, 549 filter, 550 PropertyIds.OBJECT_TYPE_ID, 551 CmsCmisTypeManager.DOCUMENT_TYPE_ID); 552 553 // file properties 554 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_IMMUTABLE, false); 555 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_LATEST_VERSION, true); 556 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_MAJOR_VERSION, true); 557 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_LATEST_MAJOR_VERSION, true); 558 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_LABEL, resource.getName()); 559 addPropertyId( 560 tm, 561 result, 562 typeId, 563 filter, 564 PropertyIds.VERSION_SERIES_ID, 565 resource.getStructureId().toString()); 566 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, false); 567 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, null); 568 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, null); 569 addPropertyString(tm, result, typeId, filter, PropertyIds.CHECKIN_COMMENT, ""); 570 addPropertyInteger(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_LENGTH, resource.getLength()); 571 addPropertyString( 572 tm, 573 result, 574 typeId, 575 filter, 576 PropertyIds.CONTENT_STREAM_MIME_TYPE, 577 OpenCms.getResourceManager().getMimeType( 578 resource.getRootPath(), 579 null, 580 CmsResourceManager.MIMETYPE_TEXT)); 581 addPropertyString(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_FILE_NAME, resource.getName()); 582 objectInfo.setHasContent(true); 583 objectInfo.setContentType( 584 OpenCms.getResourceManager().getMimeType( 585 resource.getRootPath(), 586 null, 587 CmsResourceManager.MIMETYPE_TEXT)); 588 objectInfo.setFileName(resource.getName()); 589 addPropertyId(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_ID, null); 590 } 591 // normal OpenCms properties 592 List<CmsProperty> props = cms.readPropertyObjects(resource, false); 593 Set<String> propertiesToAdd = new LinkedHashSet<String>( 594 m_repository.getTypeManager().getCmsPropertyNames()); 595 for (CmsProperty prop : props) { 596 addPropertyString( 597 tm, 598 result, 599 typeId, 600 filter, 601 CmsCmisTypeManager.PROPERTY_PREFIX + prop.getName(), 602 prop.getValue()); 603 propertiesToAdd.remove(prop.getName()); 604 } 605 for (String propName : propertiesToAdd) { 606 addPropertyString(tm, result, typeId, filter, CmsCmisTypeManager.PROPERTY_PREFIX + propName, null); 607 } 608 609 // inherited OpenCms properties 610 List<CmsProperty> inheritedProps = cms.readPropertyObjects(resource, true); 611 Set<String> inheritedPropertiesToAdd = new LinkedHashSet<String>( 612 m_repository.getTypeManager().getCmsPropertyNames()); 613 for (CmsProperty prop : inheritedProps) { 614 addPropertyString( 615 tm, 616 result, 617 typeId, 618 filter, 619 CmsCmisTypeManager.INHERITED_PREFIX + prop.getName(), 620 prop.getValue()); 621 inheritedPropertiesToAdd.remove(prop.getName()); 622 } 623 for (String propName : inheritedPropertiesToAdd) { 624 addPropertyString(tm, result, typeId, filter, CmsCmisTypeManager.INHERITED_PREFIX + propName, null); 625 } 626 627 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(resource); 628 addPropertyString( 629 tm, 630 result, 631 typeId, 632 filter, 633 CmsCmisTypeManager.PROPERTY_RESOURCE_TYPE, 634 resType.getTypeName()); 635 CmsCmisUtil.addDynamicProperties(cms, m_repository.getTypeManager(), result, typeId, resource, filter); 636 return result; 637 638 } catch (Exception e) { 639 if (e instanceof CmisBaseException) { 640 throw (CmisBaseException)e; 641 } 642 throw new CmisRuntimeException(e.getMessage(), e); 643 } 644 } 645 646 /** 647 * Collects renditions for a resource.<p> 648 * 649 * @param cms the CMS context 650 * @param resource the resource for which we want the renditions 651 * @param renditionFilterString the filter string for the renditions 652 * @param objectInfo the object info in which the renditions should be saved 653 * 654 * @return the rendition data for the given resource 655 */ 656 protected List<RenditionData> collectRenditions( 657 CmsObject cms, 658 CmsResource resource, 659 String renditionFilterString, 660 ObjectInfoImpl objectInfo) { 661 662 List<I_CmsCmisRenditionProvider> providers = m_repository.getRenditionProviders( 663 new CmsCmisRenditionFilter(renditionFilterString)); 664 List<RenditionData> result = new ArrayList<RenditionData>(); 665 List<RenditionInfo> renditionInfos = new ArrayList<RenditionInfo>(); 666 for (I_CmsCmisRenditionProvider provider : providers) { 667 RenditionData renditionData = provider.getRendition(cms, resource); 668 if (renditionData != null) { 669 RenditionInfoImpl renditionInfo = new RenditionInfoImpl(); 670 renditionInfo.setContentType(renditionData.getMimeType()); 671 renditionInfo.setKind(renditionData.getKind()); 672 renditionInfo.setId(renditionData.getStreamId()); 673 result.add(renditionData); 674 renditionInfos.add(renditionInfo); 675 } 676 } 677 if (objectInfo != null) { 678 objectInfo.setRenditionInfos(renditionInfos); 679 } 680 return result; 681 682 } 683 684}