/* * 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.model; import java.util.List; import java.util.Locale; import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.api.model.definition.Localization; import org.betaconceptframework.astroboa.api.model.exception.MultipleOccurenceException; /** * * Represents an organization's content repository entity. From Astroboa * perspective organization's, content is a set of ContentObject of several types * (Text, Audio, Video, etc). * * This interface relates Astroboa built-in content repository model with * organizaion's content repository model. * * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public interface ContentObject extends CmsRepositoryEntity { /** * Returns the name of content object type as specified by organization. * * @return A {@link String} representing content object type. */ String getContentObjectType(); /** * Sets the name of content object type as specified by organization. * * @param contentObjectType * A {@link String} representing content object type. */ void setContentObjectType(String contentObjectType); /** * Returns the owner of content object. * * @return A {@link RepositoryUser} representing content object owner. */ RepositoryUser getOwner(); /** * Sets the owner of content object. * * @param owner * A {@link RepositoryUser} representing content object owner. */ void setOwner(RepositoryUser owner); /** * Checks if content object is locked by another process or application. * * @return <code>true</code> if content object is locked, * <code>false</code> otherwise. */ boolean isLocked(); /** * Locks or unlocks a content object. * * <p> * Content Object must be save to make changes persistent. * </p> * * @param locked * <code>true</code> to lock content object, <code>false</code> * otherwise. */ void setLocked(boolean locked); /** * Returns the definition of content object type. * * @return Content object type's definition. */ ContentObjectTypeDefinition getTypeDefinition(); /** * Returns content object root property which holds all properties for a * content object. * * @return Content Object's property container. */ ComplexCmsRootProperty getComplexCmsRootProperty(); /** * Returns a list of all content object properties found under specified * path. * * <p> * Convenient method instead of calling * {@link ComplexCmsRootProperty#getChildPropertyList(String propertyPath)} * </p> * * @param relativePropertyPath * A period-delimited {@link String} as described in * {@link CmsProperty#getPath()}. * * @return A list containing all content object properties under specified * <code>propertyPath</code>. */ List<CmsProperty<?,?>> getCmsPropertyList(String relativePropertyPath); /** * Returns at most one content object property found under specified path. * * <p> * Convenient method instead of calling * {@link ComplexCmsRootProperty#getChildProperty(String propertyPath)} * </p> * * @see ComplexCmsProperty#getChildProperty(String) for more details * * @param relativePropertyPath * A period-delimited {@link String} as described in * {@link CmsProperty#getPath()}. * @return A content object property under specified * <code>propertyPath</code>. * @throws MultipleOccurenceException * If property is defined as a a multiple value property. */ CmsProperty<?, ?> getCmsProperty(String relativePropertyPath) throws MultipleOccurenceException; /** * Removes a content object property found in specified path. * * <p> * Convenient method instead of calling * {@link ComplexCmsRootProperty#removeChildProperty(String propertyPath)} * </p> * * <p> * This method is mainly used when user needs to remove a {@link ComplexCmsProperty}. * In cases where a {@link SimpleCmsProperty} must be removed, it is recommended to use * method {@link SimpleCmsProperty#removeValues()}. * </p> * * * <p> * Note that, you have to save content object, to complete property removal. * </p> * * @return <code>true</code> if property and its values have been successfully removed, <code>false</code> otherwise. * * @param relativePropertyPath * A period-delimited {@link String} as described in * {@link CmsProperty#getPath()}. */ boolean removeCmsProperty(String relativePropertyPath); /** * Get the system name for this entity. * * @return Entity's system name */ String getSystemName(); /** * Specify the system name of this entity. * * <p> * System name represents a human readable value * which identifies (more preferably uniquely) this entity. It may be used * as opposed to Id in cases where Id does not provide an immediate clue of what * this entity represents. * </p> * * <p> * System name is restricted to follow pattern <code>[A-Za-z0-9_\\-]+</code>, that is only Latin characters * are permitted along with digits and/or '-', '_'. * </p> * * @param systemName String following pattern [A-Za-z0-9_\\-]+ */ void setSystemName(String systemName); /** * * This method adds a new {@link ComplexCmsProperty} to the provided path. * * <p> * This method should be used when user wants to add a new complex property but does not * know the number of existing complex properties under the same relative path. * For example, there is a complex property named "comment" and user wants to add a new comment. * * If user already knows how many comments exist so far (by executing method * <pre>int size = getCmsPropertyList("comment").size()</pre>, be aware of NullPointerException) * then she may call * <pre>getCmsProperty("comment["+size+"]")</pre>. Otherwise she must use this method * <pre>createNewValueForMulitpleComplexCmsProperty("comment")</pre> * </p> * * <p> * Property corresponding to provided path must be a multivalued {@link ComplexCmsProperty}. Otherwise an * exception is thrown. Note that prior to creating a new property all existed properties for * provided path will be loaded. * </p> * * @param relativePropertyPath * A period-delimited {@link String} as described in * {@link CmsProperty#getPath()}. * * @return Newly created property. */ CmsProperty<?,?> createNewValueForMulitpleComplexCmsProperty(String relativePropertyPath); /** * Provides an xml representation of specified <code>cmsRepositoryEntity</code> * following content object type's xml schema as defined by * organization XML schemas. * * <p> * Only specified properties will be exported. If no properties are defined, * then all its properties which have values will be exported and this will * cause all its properties to be lazy loaded in {@link ContentObject} the instance. * </p> * * <p> * Be sure to know exactly what you are doing in case you set parameter <code>serializeBinaryContent</code> * to <code>true</code>. * </p> * * @param prettyPrint <code>true</code> to enable pretty printer functionality such as * adding identation and linefeeds in order to make output more human readable, <code>false<code> otherwise * @param serializeBinaryContent <code>true</code> to export binary content, <code>false</code> otherwise. In any case * URL of binary content is provided. * @param propertiesToBeExported Array of property path * * @return XML instance for this <code>cmsRepositoryEntity</code>. */ String xml(boolean prettyPrint, boolean serializeBinaryContent, String... propertiesToBeExported); /** * Provides a JSON representation of specified <code>cmsRepositoryEntity</code> * following Mapped convention. * * The mapped JSON notation is used with stripped root element. * <p>Example JSON expression:<pre> * {"columns":[{"id":"userid","label":"UserID"},{"id":"name","label":"User Name"}],"rows":[{"userid":1621,"name":"Grotefend"}]} * </pre> * </p> * * <p> * Only specified properties will be exported. If no properties are defined, * then all its properties which have values will be exported and this will * cause all its properties to be lazy loaded in {@link ContentObject} the instance. * </p> * * <p> * Be sure to know exactly what you are doing in case you set parameter <code>serializeBinaryContent</code> * to <code>true</code>. * </p> * * @param prettyPrint <code>true</code> to enable pretty printer functionality such as * adding indentation and linefeeds in order to make output more human readable, <code>false<code> otherwise * @param serializeBinaryContent <code>true</code> to export binary content, <code>false</code> otherwise. In any case * URL of binary content is provided. * @param propertiesToBeExported Array of property path * * @return JSON representation for this <code>cmsRepositoryEntity</code>. */ String json(boolean prettyPrint, boolean serializeBinaryContent, String... propertiesToBeExported); /** * Checks whether there is a value for the specified property, regardless of whether * property has been loaded to {@link ContentObject} or not. * * <p> * This method does not reflect the persistent state of the {@link ContentObject} but rather * the state of the specific instance. * </p> * <p> * It first checks whether the property has been loaded to {@link ContentObject} * instance. If it has not, then it checks the repository for its value existence. * Otherwise, it checks the loaded property. * </p> * * <p> * In cases where , user has removed property but has not yet saved {@link ContentObject}, * this method returns false, even though changes are not yet persisted. * </p> * * <p> * For example, user loads a {@link ContentObject} from a repository and wants to check whether * property <code>profile.creator</code> has a value * * <ul> * <li>If user has never called method {@link #getCmsProperty(String)}, then this method will check the repository * for value existence</li> * <li>If user has called method {@link #getCmsProperty(String)} or retrieved {@link ContentObject} with all its properties, then * this method will check loaded properties and will not check the repository.</li> * </ul> * * At any case, this method does not create a new property if no value is found. * </p> * * @param relativePropertyPath * A period-delimited {@link String} as described in * {@link CmsProperty#getPath()}. * @return <code>true</code> if <code>propertyPath</code> has a value, <code>false</code> otherwise. */ boolean hasValueForProperty(String relativePropertyPath); /** * Auxiliary method which allows users to retrieve a unique (most of the times) label * for this object other than object's title or system name or its identifier. * * <p> * The label is a concatenation of the values of one or more properties of this object. * The paths of these properties are defined in the schema of the object's type * (see more in {@link ContentObjectTypeDefinition#getPropertyPathsWhoseValuesCanBeUsedAsALabel()}). * Comma (,) is used to separate each value. * </p> * * <p> * For each path provided, if the corresponding property has at least * one value then if the type of the property is: * * <ul> * <li>a 'primitive' type ({@link ValueType#Boolean}, {@link ValueType#Long},{@link ValueType#Date},{@link ValueType#Double} * {@link ValueType#String}), the first (if property has multiple values) value is used. * <li>a {@link ValueType#Topic topic reference}, {@link Topic reference topic}'s localized label for provided locale is used. * <li>a {@link ValueType#Space space reference}, {@link Space reference space}'s localized label for provided locale is used. * <li>an {@link ValueType#ContentObject object reference}, {@link ContentObject Content object}'s <code>profile.title</code> value is used. * If no <code>profile.title</code> is provided then objetc's localized label for its {@link ContentObjectTypeDefinition type} is provided. * <li>{@link ValueType#Binary binary}, {@link BinaryChannel binaryChanel}'s {@link BinaryChannel#getSourceFilename() source file name}, is used. * If no source file name is provided, its url is used instead. If the latter is null, {@link BinaryChannel#getName() name} is used. * <li>a {@link ValueType#RepositoryUser repository user}, its {@link RepositoryUser#getLabel() label} is used or its * {@link RepositoryUser#getExternalId() external Id}, if no label is provided. * <li> {@link ValueType#Complex complex}, an empty string is returned. In this case a warning is issued as well. * <ul> * </p> * * <p> * It may be the case that provided property path has the keyword {locale}. In this case {locale} * is replaced by provided <code>locale</code> parameter, and then a search for a specific simple property * is conducted.For example if path is <code>localizedLabels.{locale}</code> and <code>locale</code> * parameter has value <code>en</code> then property with path <code>localizedLabels.en</code> will be searched. * </p> * @param locale * Locale value as defined in {@link Localization}. In case * where <code>locale</code> is blank (empty or null), * {@link Locale#ENGLISH English} locale will be * used. * @return String representation of this object's label according to value type of property found under * specified property path, <code>null</code> if no property path is provided. */ String getLabel(String locale); }