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.setId(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 && !isRoot); 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) 344 throws CmsException { 345 346 ObjectDataImpl result = new ObjectDataImpl(); 347 ObjectInfoImpl objectInfo = new ObjectInfoImpl(); 348 result.setProperties(collectProperties(cms, resource, filter, objectInfo)); 349 350 if (includeAllowableActions) { 351 result.setAllowableActions(collectAllowableActions(cms, resource)); 352 } 353 354 if (includeAcl) { 355 result.setAcl(collectAcl(cms, resource, true)); 356 result.setIsExactAcl(Boolean.FALSE); 357 } 358 359 if ((includeRelationships != null) && (includeRelationships != IncludeRelationships.NONE)) { 360 RelationshipDirection direction; 361 if (includeRelationships == IncludeRelationships.SOURCE) { 362 direction = RelationshipDirection.SOURCE; 363 } else if (includeRelationships == IncludeRelationships.TARGET) { 364 direction = RelationshipDirection.TARGET; 365 } else { 366 direction = RelationshipDirection.EITHER; 367 } 368 369 List<ObjectData> relationData = m_repository.getRelationshipObjectData( 370 context, 371 cms, 372 resource, 373 direction, 374 CmsCmisUtil.splitFilter("*"), 375 false); 376 result.setRelationships(relationData); 377 } 378 379 result.setRenditions(collectRenditions(cms, resource, renditionFilter, objectInfo)); 380 381 if (context.isObjectInfoRequired()) { 382 objectInfo.setObject(result); 383 context.getObjectInfoHandler().addObjectInfo(objectInfo); 384 } 385 return result; 386 } 387 388 /** 389 * Gathers all base properties of a file or folder. 390 * 391 * @param cms the current CMS context 392 * @param resource the file for which we want the properties 393 * @param orgfilter the property filter 394 * @param objectInfo the object info handler 395 * 396 * @return the properties for the given resource 397 */ 398 protected Properties collectProperties( 399 CmsObject cms, 400 CmsResource resource, 401 Set<String> orgfilter, 402 ObjectInfoImpl objectInfo) { 403 404 CmsCmisTypeManager tm = m_repository.getTypeManager(); 405 406 if (resource == null) { 407 throw new IllegalArgumentException("Resource may not be null."); 408 } 409 410 // copy filter 411 Set<String> filter = (orgfilter == null ? null : new LinkedHashSet<String>(orgfilter)); 412 413 // find base type 414 String typeId = null; 415 416 List<String> relationSourceIds = new ArrayList<String>(); 417 List<String> relationTargetIds = new ArrayList<String>(); 418 try { 419 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.ALL); 420 for (CmsRelation relation : relations) { 421 if (resource.getStructureId().equals(relation.getSourceId())) { 422 relationTargetIds.add(relation.getTargetId().toString()); 423 } 424 if (resource.getStructureId().equals(relation.getTargetId())) { 425 relationSourceIds.add(relation.getSourceId().toString()); 426 } 427 } 428 } catch (CmsException e) { 429 throw new CmisStorageException(e.getLocalizedMessage(), e); 430 } 431 432 if (resource.isFolder()) { 433 typeId = CmsCmisTypeManager.FOLDER_TYPE_ID; 434 objectInfo.setBaseType(BaseTypeId.CMIS_FOLDER); 435 objectInfo.setTypeId(typeId); 436 objectInfo.setContentType(null); 437 objectInfo.setFileName(null); 438 objectInfo.setHasAcl(true); 439 objectInfo.setHasContent(false); 440 objectInfo.setVersionSeriesId(null); 441 objectInfo.setIsCurrentVersion(true); 442 objectInfo.setRelationshipSourceIds(relationSourceIds); 443 objectInfo.setRelationshipTargetIds(relationTargetIds); 444 objectInfo.setSupportsDescendants(true); 445 objectInfo.setSupportsFolderTree(true); 446 objectInfo.setSupportsPolicies(false); 447 objectInfo.setSupportsRelationships(true); 448 objectInfo.setWorkingCopyId(null); 449 objectInfo.setWorkingCopyOriginalId(null); 450 } else { 451 typeId = CmsCmisTypeManager.DOCUMENT_TYPE_ID; 452 objectInfo.setBaseType(BaseTypeId.CMIS_DOCUMENT); 453 objectInfo.setTypeId(typeId); 454 objectInfo.setHasAcl(true); 455 objectInfo.setHasContent(true); 456 objectInfo.setHasParent(true); 457 objectInfo.setVersionSeriesId(null); 458 objectInfo.setIsCurrentVersion(true); 459 objectInfo.setRelationshipSourceIds(relationSourceIds); 460 objectInfo.setRelationshipTargetIds(relationTargetIds); 461 objectInfo.setSupportsDescendants(false); 462 objectInfo.setSupportsFolderTree(false); 463 objectInfo.setSupportsPolicies(false); 464 objectInfo.setSupportsRelationships(true); 465 objectInfo.setWorkingCopyId(null); 466 objectInfo.setWorkingCopyOriginalId(null); 467 } 468 try { 469 PropertiesImpl result = new PropertiesImpl(); 470 471 String id = resource.getStructureId().toString(); 472 addPropertyId(tm, result, typeId, filter, PropertyIds.OBJECT_ID, id); 473 objectInfo.setId(id); 474 475 String name = resource.getName(); 476 if ("".equals(name)) { 477 name = "/"; 478 } 479 addPropertyString(tm, result, typeId, filter, PropertyIds.NAME, name); 480 objectInfo.setName(name); 481 482 // created and modified by 483 CmsUUID creatorId = resource.getUserCreated(); 484 CmsUUID modifierId = resource.getUserLastModified(); 485 String creatorName = creatorId.toString(); 486 String modifierName = modifierId.toString(); 487 try { 488 CmsUser user = cms.readUser(creatorId); 489 creatorName = user.getName(); 490 } catch (CmsException e) { 491 // ignore, use id as name 492 } 493 try { 494 CmsUser user = cms.readUser(modifierId); 495 modifierName = user.getName(); 496 } catch (CmsException e) { 497 // ignore, use id as name 498 } 499 500 addPropertyString(tm, result, typeId, filter, PropertyIds.CREATED_BY, creatorName); 501 addPropertyString(tm, result, typeId, filter, PropertyIds.LAST_MODIFIED_BY, modifierName); 502 objectInfo.setCreatedBy(creatorName); 503 504 // creation and modification date 505 GregorianCalendar lastModified = millisToCalendar(resource.getDateLastModified()); 506 GregorianCalendar created = millisToCalendar(resource.getDateCreated()); 507 508 addPropertyDateTime(tm, result, typeId, filter, PropertyIds.CREATION_DATE, created); 509 addPropertyDateTime(tm, result, typeId, filter, PropertyIds.LAST_MODIFICATION_DATE, lastModified); 510 objectInfo.setCreationDate(created); 511 objectInfo.setLastModificationDate(lastModified); 512 513 // change token - always null 514 addPropertyString(tm, result, typeId, filter, PropertyIds.CHANGE_TOKEN, null); 515 516 // directory or file 517 if (resource.isFolder()) { 518 // base type and type name 519 addPropertyId(tm, result, typeId, filter, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_FOLDER.value()); 520 addPropertyId( 521 tm, 522 result, 523 typeId, 524 filter, 525 PropertyIds.OBJECT_TYPE_ID, 526 CmsCmisTypeManager.FOLDER_TYPE_ID); 527 String path = resource.getRootPath(); 528 addPropertyString(tm, result, typeId, filter, PropertyIds.PATH, (path.length() == 0 ? "/" : path)); 529 530 // folder properties 531 if (resource.getRootPath().length() > 1) { 532 CmsResource parent = cms.readParentFolder(resource.getStructureId()); 533 addPropertyId(tm, result, typeId, filter, PropertyIds.PARENT_ID, ( 534 535 parent.getStructureId().toString())); 536 objectInfo.setHasParent(true); 537 } else { 538 addPropertyId(tm, result, typeId, filter, PropertyIds.PARENT_ID, null); 539 objectInfo.setHasParent(false); 540 } 541 542 addPropertyIdList(tm, result, typeId, filter, PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS, null); 543 } else { 544 // base type and type name 545 addPropertyId(tm, result, typeId, filter, PropertyIds.BASE_TYPE_ID, BaseTypeId.CMIS_DOCUMENT.value()); 546 addPropertyId( 547 tm, 548 result, 549 typeId, 550 filter, 551 PropertyIds.OBJECT_TYPE_ID, 552 CmsCmisTypeManager.DOCUMENT_TYPE_ID); 553 554 // file properties 555 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_IMMUTABLE, false); 556 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_LATEST_VERSION, true); 557 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_MAJOR_VERSION, true); 558 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_LATEST_MAJOR_VERSION, true); 559 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_LABEL, resource.getName()); 560 addPropertyId( 561 tm, 562 result, 563 typeId, 564 filter, 565 PropertyIds.VERSION_SERIES_ID, 566 resource.getStructureId().toString()); 567 addPropertyBoolean(tm, result, typeId, filter, PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, false); 568 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, null); 569 addPropertyString(tm, result, typeId, filter, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, null); 570 addPropertyString(tm, result, typeId, filter, PropertyIds.CHECKIN_COMMENT, ""); 571 addPropertyInteger(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_LENGTH, resource.getLength()); 572 addPropertyString( 573 tm, 574 result, 575 typeId, 576 filter, 577 PropertyIds.CONTENT_STREAM_MIME_TYPE, 578 OpenCms.getResourceManager().getMimeType( 579 resource.getRootPath(), 580 null, 581 CmsResourceManager.MIMETYPE_TEXT)); 582 addPropertyString(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_FILE_NAME, resource.getName()); 583 objectInfo.setHasContent(true); 584 objectInfo.setContentType( 585 OpenCms.getResourceManager().getMimeType( 586 resource.getRootPath(), 587 null, 588 CmsResourceManager.MIMETYPE_TEXT)); 589 objectInfo.setFileName(resource.getName()); 590 addPropertyId(tm, result, typeId, filter, PropertyIds.CONTENT_STREAM_ID, null); 591 } 592 // normal OpenCms properties 593 List<CmsProperty> props = cms.readPropertyObjects(resource, false); 594 Set<String> propertiesToAdd = new LinkedHashSet<String>( 595 m_repository.getTypeManager().getCmsPropertyNames()); 596 for (CmsProperty prop : props) { 597 addPropertyString( 598 tm, 599 result, 600 typeId, 601 filter, 602 CmsCmisTypeManager.PROPERTY_PREFIX + prop.getName(), 603 prop.getValue()); 604 propertiesToAdd.remove(prop.getName()); 605 } 606 for (String propName : propertiesToAdd) { 607 addPropertyString(tm, result, typeId, filter, CmsCmisTypeManager.PROPERTY_PREFIX + propName, null); 608 } 609 610 // inherited OpenCms properties 611 List<CmsProperty> inheritedProps = cms.readPropertyObjects(resource, true); 612 Set<String> inheritedPropertiesToAdd = new LinkedHashSet<String>( 613 m_repository.getTypeManager().getCmsPropertyNames()); 614 for (CmsProperty prop : inheritedProps) { 615 addPropertyString( 616 tm, 617 result, 618 typeId, 619 filter, 620 CmsCmisTypeManager.INHERITED_PREFIX + prop.getName(), 621 prop.getValue()); 622 inheritedPropertiesToAdd.remove(prop.getName()); 623 } 624 for (String propName : inheritedPropertiesToAdd) { 625 addPropertyString(tm, result, typeId, filter, CmsCmisTypeManager.INHERITED_PREFIX + propName, null); 626 } 627 628 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(resource); 629 addPropertyString( 630 tm, 631 result, 632 typeId, 633 filter, 634 CmsCmisTypeManager.PROPERTY_RESOURCE_TYPE, 635 resType.getTypeName()); 636 CmsCmisUtil.addDynamicProperties(cms, m_repository.getTypeManager(), result, typeId, resource, filter); 637 return result; 638 639 } catch (Exception e) { 640 if (e instanceof CmisBaseException) { 641 throw (CmisBaseException)e; 642 } 643 throw new CmisRuntimeException(e.getMessage(), e); 644 } 645 } 646 647 /** 648 * Collects renditions for a resource.<p> 649 * 650 * @param cms the CMS context 651 * @param resource the resource for which we want the renditions 652 * @param renditionFilterString the filter string for the renditions 653 * @param objectInfo the object info in which the renditions should be saved 654 * 655 * @return the rendition data for the given resource 656 */ 657 protected List<RenditionData> collectRenditions( 658 CmsObject cms, 659 CmsResource resource, 660 String renditionFilterString, 661 ObjectInfoImpl objectInfo) { 662 663 List<I_CmsCmisRenditionProvider> providers = m_repository.getRenditionProviders( 664 new CmsCmisRenditionFilter(renditionFilterString)); 665 List<RenditionData> result = new ArrayList<RenditionData>(); 666 List<RenditionInfo> renditionInfos = new ArrayList<RenditionInfo>(); 667 for (I_CmsCmisRenditionProvider provider : providers) { 668 RenditionData renditionData = provider.getRendition(cms, resource); 669 if (renditionData != null) { 670 RenditionInfoImpl renditionInfo = new RenditionInfoImpl(); 671 renditionInfo.setContentType(renditionData.getMimeType()); 672 renditionInfo.setKind(renditionData.getKind()); 673 renditionInfo.setId(renditionData.getStreamId()); 674 result.add(renditionData); 675 renditionInfos.add(renditionInfo); 676 } 677 } 678 if (objectInfo != null) { 679 objectInfo.setRenditionInfos(renditionInfos); 680 } 681 return result; 682 683 } 684 685}