/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Astroboa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.api.service; import java.util.List; import org.betaconceptframework.astroboa.api.model.BinaryChannel; import org.betaconceptframework.astroboa.api.model.CmsProperty; import org.betaconceptframework.astroboa.api.model.CmsRepositoryEntity; import org.betaconceptframework.astroboa.api.model.ComplexCmsProperty; import org.betaconceptframework.astroboa.api.model.ComplexCmsRootProperty; import org.betaconceptframework.astroboa.api.model.ContentObject; import org.betaconceptframework.astroboa.api.model.ContentObjectFolder; import org.betaconceptframework.astroboa.api.model.ContentObjectFolder.Type; import org.betaconceptframework.astroboa.api.model.LocalizableEntity; import org.betaconceptframework.astroboa.api.model.SimpleCmsProperty; import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.api.model.definition.Localization; import org.betaconceptframework.astroboa.api.model.io.FetchLevel; import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType; import org.betaconceptframework.astroboa.api.model.query.CacheRegion; import org.betaconceptframework.astroboa.api.model.query.CmsOutcome; import org.betaconceptframework.astroboa.api.model.query.criteria.ContentObjectCriteria; import org.betaconceptframework.astroboa.api.model.query.render.RenderProperties; /** * Service providing methods for managing {@link ContentObject content objects}. * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public interface ContentService { /** * Returns a binary channel using specified id. * * Useful method to retrieve binary data of a binary property without having * to load content object which contains binary property. * * @param binaryChannelId * {@link BinaryChannel#getId() Binary channel id}. * @return A binary channel for specified id. */ BinaryChannel getBinaryChannelById( String binaryChannelId); /** * Returns root content object folders. * * <p> * All {@link ContentObject content objects} are stored in content * repository in {@link ContentObjectFolder folders} according to their * {@link ContentObject#getContentObjectType()} type and their creation * date. * </p> * * <p> * Initially a folder for content object type is created (if not already * there). This folder is considered a root content object folder. Then * another folder is created representing the year of creation of content * object which by its turn contains a folder representing the month of * creation of content object which finally contains a folder representing * the day of creation of content object.In the last folder, newly created * content object is stored. For example if a content object of type * <code>article</code> was created at 30/12/2007 the following folder * hierarchy will be created * * <pre> * articleTypeFolder * | * + 2007 * | * + 12 * | * + 30 * - Content object * </pre> * * </p> * * * @param locale * Locale value as defined in {@link Localization} to be * used when user calls method {@link LocalizableEntity#getLocalizedLabelForCurrentLocale()} * to retrieve localized label for returned content object folders. * * @return A list of all content object folders, one for each content object * type. * */ List<ContentObjectFolder> getRootContentObjectFolders( String locale); /** * Returns a content object folder. * * @param contentObjectFolderId * {@link ContentObjectFolder#getId() content object folder id}. * @param depth * Number of levels of content object folder to return. * <code>-1</code> denotes that all content object folder * hierarchy will be returned. * @param renderContentObjectIds * <code>true</code> to load content object ids, in case a * content object folder is of type * {@link Type#DAY} (for 2.x.x versions) or {@link Type#SECOND} (for 3.x.x), <code>false</code> * otherwise. * @param locale * Locale value as defined in {@link Localization} to be * used when user calls method {@link LocalizableEntity#getLocalizedLabelForCurrentLocale()} * to retrieve localized label for returned content object folders. * * @return A Content object folder. */ ContentObjectFolder getContentObjectFolderTree( String contentObjectFolderId, int depth, boolean renderContentObjectIds, String locale); /** * Delete a content object from content repository. * * @param objectIdOrSystemName * Object {@link ContentObject#getId() id} or {@link ContentObject#getSystemName() system name}. * * @return <code>true</code> if object has been successfully deleted, <code>false</code> if no object with the provided id or name is found. */ boolean deleteContentObject( String objectIdOrSystemName); /** * Retrieves a specific version of a content object. * * @param contentObjectId * {@link ContentObject#getId() content object id}. * @param versionName * Content object version name. * @param locale * Locale value as defined in {@link Localization} to be * used when user calls method {@link LocalizableEntity#getLocalizedLabelForCurrentLocale()} * to retrieve localized label for content * {@link CmsRepositoryEntity entities}. * @param cacheRegion Specify how much time object will remain in cache * * @return A content object of specific version. */ ContentObject getContentObjectByVersionName( String contentObjectId, String versionName, String locale, CacheRegion cacheRegion); /** * Locks a content object. Lock is deep and open-scoped that is unlock must * be done explicitly. * * @param contentObjectId * {@link ContentObject#getId() content object id}. * @return Lock token necessary to unlock content object. */ String lockContentObject( String contentObjectId); /** * Removes a lock from a content object. * * @param contentObjectId * {@link ContentObject#getId() content object id}. * @param lockToken * Lock token necessary to unlock content object. */ void removeLockFromContentObject( String contentObjectId, String lockToken); /** * Checks if a content object is locked. * * @param contentObjectId * {@link ContentObject#getId() content object id}. * @return <code>true</code> if content object is locked, * <code>false</code> otherwise. */ boolean isContentObjectLocked( String contentObjectId); /** * Increase {@link ContentObject content objects's} view counter by <code>counter</code>. * * ViewCounter is an internal property of Content Object but not a built in. * Therefore its property path is <code>statistic.viewCounter</code> and * if it exists it will appear in native properties of a * {@link ContentObject content objects}. * * @param contentObjectId * {@link ContentObject#getId() content object id}. * @param counter Number of views */ void increaseContentObjectViewCounter( String contentObjectId, long counter); /** * Retrieve child cms property. * * Used to lazy load a child cms property for a specific parent complex cms property. * * Used mainly when calling method {@link ComplexCmsProperty#createNewValueForMulitpleComplexCmsProperty(String)} or * {@link ComplexCmsProperty#getChildProperty(String)} or {@link ComplexCmsProperty#getChildPropertyList(String)}. * * Users are STRONLGY encouraged to use the aforementioned methods for retrieving child cms properties. * * @param childPropertyName The name of the property to load * @param parentComplexCmsPropertyDefinitionFullPath Parent definition full path * @param jcrNodeUUIDWhichCorrespondsToParentComplexCmsProperty UUID of Jcr Node which corresponds to parent property * @param jcrNodeUUIDWhichCorrespondsToContentObejct UUID of Jcr Node which corresponds to content object * @param renderProperties Instructions to follow while rendering * * @return A list of all loaded child cms properties. A list is used in cases where multiple complex cms properties * are loaded for the specified childPropertyName */ List<CmsProperty<?,?>> loadChildCmsProperty(String childPropertyName, String parentComplexCmsPropertyDefinitionFullPath, String jcrNodeUUIDWhichCorrespondsToParentComplexCmsProperty, String jcrNodeUUIDWhichCorrespondsToContentObejct, RenderProperties renderProperties); /** * Utility method which transforms an aspect to a native property of all content objects of the provided content type. * * This is useful in cases where an aspect is needed by all content objects of a specific content type and therefore * it is more meaningful to be defined as a native property of this content type rather than an aspect. * * After this method successfully ends, content type definition must be updated with the definition of the property, * so that the property will become available as a normal native property of this content type. * * @param aspect Aspect name * @param newPropertyName New property name which replace aspect. If null then new property will have the same name with aspect * @param contentType Restrict the change to all content objects of this type only */ void moveAspectToNativePropertyForAllContentObjectsOFContentType(String aspect, String newPropertyName, String contentType); /** * Single entry point for retrieving an {@link ContentObject object} from a repository. * * <p> * A contentObject can be retrieved as XML, as JSON or as a {@link ContentObject} instance. * Each one of these representations can be specified through {@link ResourceRepresentationType} * which has been designed in such a way that the returned type is available * in compile time, avoiding unnecessary and ugly type castings. * * <pre> * String contentObjectXML = contentObjectService.getContentObject("id", ResourceRepresentationType.XML, FetchLevel.ENTITY, CacheRegion.ONE_MINUTE, null, false); * * String contentObjectJSON = contentObjectService.getContentObject("id", ResourceRepresentationType.JSON, FetchLevel.ENTITY_AND_CHILDREN, CacheRegion.ONE_MINUTE, Arrays.asList("profile.title","webPublication.webPublicationStartDate"), false); * * ContentObject contentObject = contentObjectService.getContentObject("id", ResourceRepresentationType.CONTENT_OBJECT_INSTANCE, FetchLevel.FULL, CacheRegion.ONE_MINUTE, null, false); * * CmsOutcome<ContentObject> contentObjectOutcome = contentObjectService.getContentObject("id", ResourceRepresentationType.CONTENT_OBJECT_LIST, FetchLevel.FULL, CacheRegion.ONE_MINUTE, null, false); * * </pre> * </p> * * <p> * You may have noticed that {@link ResourceRepresentationType#CONTENT_OBJECT_LIST} represents a list of * contentObjects, rather than one and therefore its use in this context is not recommended. * Nevertheless, if used, a list containing one contentObject will be provided. * </p> * * <p> * Users have also the option to pre-fetch specific or all contentObject's properties. * By default, regardless of the requested <code>output</code>, only the following properties are returned * (i.e. default value for <code>fetchLevel</code> is {@link FetchLevel#ENTITY}) * * <ul> * <li>Identifier</li> * <li>System Name</li> * <li>Content Type</li> * <li>Owner (external id, label, etc)</li> * <li>Url</li> * <li>Title (property profile.title)</li> * </ul> * * * </p> * * <p> * This is very convenient in cases where the user requested a {@link ContentObject} instance * or a list of {@link ContentObject} instances ({@link CmsOutcome}) and would like to take * advantage of the lazy loading mechanism, i.e. load a property only when its value is requested. * </p> * * <p> * However, in cases of XML or JSON representation, lazy loading is not available and thus, users * must be able to explicitly define which properties should be preloaded. This can be done with * the combination of <code>fetchLevel</code> and <code>propertyPathsToInclude</code> : * (The following rules apply for all resource representation types of the result) * * <ul> * <li> {@link FetchLevel#FULL} : Loads all properties of a {@link ContentObject}. * Value of <code>propertyPathsToInclude</code> is ignored</li> * <li> {@link FetchLevel#ENTITY} : Loads the aforementioned properties of a * {@link ContentObject} plus any property specified in <code>propertyPathsToInclude</code>. If <code>propertyPathsToInclude</code> is empty * properties <code>owner</code> and <profile.title</code> are not loaded. * <li> {@link FetchLevel#ENTITY_AND_CHILDREN} : Loads the aforementioned properties (except owner and title) of a * {@link ContentObject} plus any property specified in <code>propertyPathsToInclude</code>. It should be stated that * if {@link ResourceRepresentationType#CONTENT_OBJECT_INSTANCE} or {@link ResourceRepresentationType#CONTENT_OBJECT_LIST} resource representation is selected then * the 'owner' is always returned. Also, if <code>propertyPathsToInclude</code> is null or empty, the behavior is exactly the same with {@link FetchLevel#ENTITY}</li> * </ul> * </p> * * <p> * Also, in cases where no output type is defined, a {@link ContentObject} instance is returned. * </p> * * <p> * In JSON representation, note that root element has been stripped out. * i.e result will look like this * * <pre> * {"cmsIdentifier":"092831be-43a4-4357-8bd8-5b9b43807f87","name":"myContentObject","localization":{"label":{"en":"My first contentObject"}}} * </pre> * * and not like this * * <pre> * {"contentObject":{"cmsIdentifier":"092831be-43a4-4357-8bd8-5b9b43807f87","name":"myContentObject","localization":{"label":{"en":"My first contentObject"}}} * </pre> * * </p> * * <p> * Finally, in case no contentObject is found for provided <code>contentObjectId</code>, * <code>null</code>is returned. * </p> * * @param <T> {@link String}, {@link ContentObject} or {@link CmsOutcome} * @param contentObjectIdOrSystemName {@link ContentObject#getId() contentObject id} or {@link ContentObject#getSystemName() contentObject system name} * @param output ContentObject representation output, one of XML, JSON or {@link ContentObject}. Default is {@link ResourceRepresentationType#CONTENT_OBJECT_INSTANCE} * @param fetchLevel Specify whether to load {@link ContentObject}'s only properties, its children as well or the whole {@link ContentObject}. * Default is {@link FetchLevel#ENTITY} * @param cacheRegion Specify how much time object will remain in cache * @param propertyPathsToInclude A list of property paths whose values will be included (i.e. preloaded) in the export * @param serializeBinaryContent <code>true</code> to export binary content, <code>false</code> otherwise. In any case * URL of binary content is provided. This property is valid for output formats {@link ResourceRepresentationType#XML} or * {@link ResourceRepresentationType#JSON} only * * @return A contentObject as XML, JSON or {@link ContentObject}, or <code>null</code> of none is found. */ <T> T getContentObject(String contentObjectIdOrSystemName, ResourceRepresentationType<T> output, FetchLevel fetchLevel, CacheRegion cacheRegion, List<String> propertyPathsToInclude, boolean serializeBinaryContent); /** * Saves or updates a content object. * * <p> * This method expects either a {@link ContentObject} instance * or a {@link String} instance which corresponds to an XML or * JSON representation of the entity to be saved. * </p> * * In case content object is locked, use <code>lockToken</code> to unlock it. * * <p> * If no {@link ContentObject#setContentObjectType(String) content object type} is provided or type * provided does not correspond to a {@link ContentObjectTypeDefinition definition} * an exception is thrown. * </p> * * <p> * In case of an update, if {@link ContentObject#setContentObjectType(String) content object type} * is different than the one existed, an exception is thrown. * </p> * * <p> * If {@link ContentObject#getOwner() owner} does not have an id or it does not exist, * an exception is thrown. * </p> * <p> * Whether save or update process is followed depends on whether <code>contentObject</code> * is a new contentObject or not. <code>contentObject</code> is considered new if there is no * {@link ContentObject#getId() id} or <code>id</code> is provided but there is * no {@link ContentObject contentObject} in repository for the provided <code>id</code>. In this case * <code>contentObject</code> will be saved with the provided <code>id</code>. * </p> * * <p> * The following steps take place in the save process (<code>contentObject</code> is considered new) * <ul> * <li> Create a new {@link ContentObject#getId() id} or use the provided <code>id</code>. * <li> Create value for property <code>profile.created</code> to denote content object's creation date. * If property <code>profile.created</code> is defined and a value for that property is provided, * then that value is used. Otherwise (if no value exists or that property is not defined) * current date time will be used to denote content object's creation date. * <li> Relate <code>contentObject</code> with the provided {@link ContentObject#getOwner() owner}. * ContentObject's owner MUST already exist. If not, an exception is thrown. * <li> Inserts all provided {@link CmsProperty properties} found under {@link ComplexCmsRootProperty root property} * into repository. * <li> A {@link SimpleCmsProperty simple property} with no {@link SimpleCmsProperty#getSimpleTypeValues() values} * at all, is not saved. If this property is mandatory an exception is thrown. * <li> A {@link ComplexCmsProperty complex property} with no {@link ComplexCmsProperty#getChildProperties() child properties} * at all, is not saved. If this property is mandatory an exception is thrown. The same occurs if this property contains * child properties but ALL of them on their part are considered empty, that is have no values. * </ul> * </p> * * <p> * The following steps take place in the update process (<code>topic</code> already exists in repository) * * <ul> * <li> Relate <code>contentObject</code> with the provided {@link ContentObject#getOwner() owner}. * ContentObject's owner MUST already exist. If not, an exception is thrown. * <li> Updates all provided {@link CmsProperty properties} found under {@link ComplexCmsRootProperty root property} * into repository. * <li> A {@link SimpleCmsProperty simple property} with no {@link SimpleCmsProperty#getSimpleTypeValues() values} * at all, is not saved. If this property is mandatory an exception is thrown. * <li> A {@link ComplexCmsProperty complex property} with no {@link ComplexCmsProperty#getChildProperties() child properties} * at all, is not saved. If this property is mandatory an exception is thrown. The same occurs if this property contains * child properties but ALL of them on their part are considered empty, that is have no values. * </ul> * </p> * * <p> * Finally, in order to remove a {@link CmsProperty property}, one must call * {@link ContentObject#removeCmsProperty(String)} or {@link ComplexCmsProperty#removeChildProperty(String)} * and then save content object. Again if this property is mandatory an exception is thrown. * </p> * * <p> * Every time a content object is saved, unless specified otherwise, * Astroboa updates value of built in property <code>profile.modified</code> * to current datetime. Set value <code>false</code> for <code>updateLastModificationDate</code> * to disable above behavior. * </p> * * <p> * Please note in all cases, property {@link ContentObject#setContentObjectType(String) contentObjectType} * must be provided. * </p> * * @param contentObject * {@link ContentObject} to be saved or updated. * @param version * <code>true</code> to create a new version for content * object, <code>false</code> otherwise. * @param updateLastModificationDate <code>true</code> to change last modification date, <code>false</code> otherwise * @param lockToken * Token created when content object was locked. * * @throws {@link CmsException} * in case content object is locked. * * @return Newly created or updated {@link ContentObject} instance. */ ContentObject save(Object contentObject, boolean version, boolean updateLastModificationTime, String lockToken); /** * Query content using {@link ContentObjectCriteria} and specifying * result output representation. * * <p> * Query results can be retrieved as XML, as JSON or as a {@link CmsOutcome<ContentObject>} instance. * Each one of these representations can be specified through {@link ResourceRepresentationType} * which has been designed in such a way that the returned type is available * in compile time, avoiding unnecessary and ugly type castings. * * <pre> * String resultAsXML = contentObjectService.searchContentObjects(contentObjectCriteria, ResourceRepresentationType.XML); * * String resultAsJSON = contentObjectService.searchContentObjects(contentObjectCriteria, ResourceRepresentationType.JSON); * * ContentObject contentObject = contentObjectService.searchContentObjects(contentObjectCriteria, ResourceRepresentationType.CONTENT_OBJECT_INSTANCE); * * CmsOutcome<ContentObject> resultAsOutcome = contentObjectService.searchContentObjects(contentObjectCriteria, ResourceRepresentationType.CONTENT_OBJECT_LIST); * * </pre> * </p> * * <p> * You may have noticed that {@link ResourceRepresentationType#CONTENT_OBJECT_INSTANCE} represents one content object * only, rather than a list and therefore its use in this context is not recommended. However in the following * cases a single content object or null is returned, instead of throwing an exception. * * <ul> * <li>User specified limit to be 1 ({@link ContentObjectCriteria#setLimit(1)}). * In this case the first content object matching criteria is returned, or null if none matched criteria.<li> * <li>User specified no limit or limit greater than 1. In this case if more than one content objects match * criteria an exception is thrown</li> * </ul> * </p> * * <p> * Also, in cases where no output type is defined a {@link CmsOutcome<ContentObject>} instance is returned. * </p> * * <p> * In JSON representation, note that root element has been stripped out. * i.e result will look like this * * <pre> * {"cmsIdentifier":"092831be-43a4-4357-8bd8-5b9b43807f87","name":"myContentObject","localization":{"label":{"en":"My first contentObject"}}} * </pre> * * and not like this * * <pre> * {"contentObject":{"cmsIdentifier":"092831be-43a4-4357-8bd8-5b9b43807f87","name":"myContentObject","localization":{"label":{"en":"My first contentObject"}}} * </pre> * * </p> * * <p> * Finally, if no result is found, * * <ul> * <li><code>null</code> is returned if <code>output</code> {@link ResourceRepresentationType#CONTENT_OBJECT_INSTANCE}</li> * <li><pre>{ * "totalResourceCount" : "0", * "offset" : "0" * } * </pre> is returned if <code>output</code> {@link ResourceRepresentationType#JSON}</li> * <li><pre><?xml version="1.0" encoding="UTF-8"?> * <bccmsapi:resourceResponse * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" * xmlns:bccmsmodel="http://www.betaconceptframework.org/schema/astroboa/model" * xmlns:astroboa-api="http://www.betaconceptframework.org/schema/astroboa/api" * offset="0" * totalResourceCount="0" * /> * </pre> is returned if <code>output</code> {@link ResourceRepresentationType#XML}</li> * <li>empty {@link CmsOutcome<ContentObject>} is returned if <code>output</code> {@link ResourceRepresentationType#CONTENT_OBJECT_LIST}</li> * </ul> * * </p> * * @param <T> {@link String}, {@link ContentObject} or {@link CmsOutcome} * @param contentObjectCriteria * Restrictions for content object and render instructions for * query results. * @param output ContentObject representation output, one of XML, JSON or {@link ContentObject}. * Default is {@link ResourceRepresentationType#CONTENT_OBJECT_LIST} * * @return ContentObjects as XML, JSON or {@link CmsOutcome<ContentObject>} */ <T> T searchContentObjects(ContentObjectCriteria contentObjectCriteria, ResourceRepresentationType<T> output); /** * Support for deep copy of a contentObject. * * <p> * This method is responsible to return an exact copy of the specified {@link ContentObject}. * It does not save fresh copy. * </p> * * <p> * In cases where logged in user is not the owner of the content object, copy is allowed only if * user has read permissions on that content object. * In these cases, copied {@link ContentObject}'s owner is the user currently logged in. * </p> * * <p> * During copy operation, content object system name and title change in order to * make apparent that this content object is a fresh copy. Users, of course, can change * them according to their needs. * </p> * * <p> * Prefix 'copy' plus the index of the copy is added to contentObject's system name. * Copy index is added at the end of the title as well. * </p> * * <p> * Copy index is calculated by retrieving all content objects whose system name ends with * source content object's system name. These most likely have been copies of the content object. * Of course, index cannot always be correct but in most cases it is a good approach * to calculate copy index. * </p> * * * @param contetObjectId Identifier of ContentObject to be copied * @return Cloned {@link ContentObject} or an exception if no content object is found or user is not authorized to * perform this operation */ ContentObject copyContentObject(String contetObjectId); /** * Check that provided property has a value. * * <p> * This method does not load property and its values. It just checks whether there is a value * for this property in the repository. * </p> * * <p> * Used mainly when calling method {@link ComplexCmsProperty#hasValueForChildProperty(String)} or * {@link ContentObject#hasValueForProperty(String)} * * Users are STRONLGY encouraged to use the aforementioned methods for checking value existence of child cms properties. * </p> * * @param propertyPath The name of the property to load * @param jcrNodeUUIDWhichCorrespondsToParentComplexCmsProperty UUID of Jcr Node which corresponds to parent property * * @return <code>true</code> if value exists for the provided property, <code>false</code> otherwise */ boolean hasValueForProperty(String propertyPath, String jcrNodeUUIDWhichCorrespondsToParentComplexCmsProperty); /** * Import content object resource collection (XML, JSON or {@link List} of {@link ContentObject}) to the repository. * * <p> * Very convenient method for batch saving. Users may use this method to save * modified query results which were returned by method {@link #searchContentObjects(org.betaconceptframework.astroboa.api.model.query.criteria.ContentObjectCriteria, org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType)} * </p> * * <p> * The same security rules with {@link ContentService#save(Object, boolean, boolean, String)} * apply to each resource. * </p> * * <p> * Once this functionality is stable, it will be removed under the {@link #save(Object, boolean, boolean, String)} method. * Track the progress of this issue at http://jira.betaconceptframework.org/browse/ASTROBOA-118 *</p> * @param contentSource Xml or JSON or {@link ResourceRepresentationType#CONTENT_OBJECT_LIST} representation of a collection of {@link ContentObject}s. * @param version * <code>true</code> to create a new version for content * object, <code>false</code> otherwise. Taken into account only if <code>save</code> is <code>true</code> * @param updateLastModificationDate <code>true</code> to change last modification date, <code>false</code> otherwise. * Taken into account only if <code>save</code> is <code>true</code> * @param lockToken * Token created when content object was locked. * @return Imported {@link ContentObject} */ List<ContentObject> saveContentObjectResourceCollection(Object contentSource,boolean version, boolean updateLastModificationTime, String lockToken); /** * Return the content of a binary channel. * * <p> * Used mainly for lazy loading the content of a {@link BinaryChannel} when calling method {@link BinaryChannel#getContent()} or * {@link BinaryChannel#getContentAsStream()} * * Users are STRONLGY encouraged to use the aforementioned methods for retrieving the content of a bunary channel. * </p> * * @param jcrNodeUUIDWhichCorrespondsToTheBinaryChannel UUID of Jcr Node which corresponds to the binary channel * * @return <code>true</code> if value exists for the provided property, <code>false</code> otherwise */ byte[] getBinaryChannelContent(String jcrNodeUUIDWhichCorrespondsToTheBinaryChannel); }