Media Authoring
with Java API

Package tv.amwa.maj.iface

Specifications of all the persistent and meta classes of AAF as Java interfaces.

See:
          Description

Interface Summary
AAFFactory Specifies a factory for all concrete, persistent AAF classes.
AAFFile Specifies a representation of an AAF file.
AAFFileDescriptor Specifies a file descriptor that describes an essence source that is directly manipulated by an AAF application.
AES3PCMDescriptor Specifies an AES3 PCM descriptor that describes audio essence in the AES/EBU audio file format, as defined in the EBU/AES digital audio interface specification.
AIFCDescriptor Specifies the description of a file of audio essence formatted according to the Audio Interchange File Format with Compression (AIFC).
AuxiliaryDescriptor Specifies the description of an auxiliary file essence source.
BWFImportDescriptor Specifies the description of audio essence that is formatted according the the Broadcast Wave Format specifications, which is a file essence source that is not directly manipulated by an AAF application.
CDCIDescriptor Specifies the description of a file of video essence formatted with one luminance component and two color-difference components, as specified according to the AAF object specification v1.1.
ClassDefinition Specifies the definition of an AAF class.
CodecDefinition Specifies the definition of an essence codec.
CommentMarker Specifies a user comment associated with a point in time.
Component Specifies an essence element.
CompositionMob Specifies a material object that describes how to combine content data elements into a sequence, how to modify content data elements, and how to synchronize content data elements.
ConstantValue Specifies a a constant data value for an effect control value.
ContainerDefinition Specifies a definition for the mechanism used to store essence data.
ContentStorage Specifies storage for content that has mob and essence data within it.
ControlPoint Specifies a value and a time point (position) that is used to specify an effect control value.
DataDefinition Specifies a definition for the kind of data that can be stored in a component.
DataEssenceDescriptor Specifies the description of a file of data essence and identifies the data coding of that essence.
DefinitionObject Specifies a definition to be referenced.
DescriptiveClip Specifies what is being described in terms of mob slots and references a mob to provide that description.
DescriptiveFramework Specifies a framework for descriptive metadata.
DescriptiveMarker Specifies descriptive metadata associated with a point in time and the mob slots that the description refers to.
DescriptiveObject Specifies an item of descriptive metadata in a descriptive framework.
Dictionary Specifies a container for definitions.
DigitalImageDescriptor Specifies the description of video content data formatted either using RGBA or luminance/chrominance formatting.
EdgecodeSegment Specifies the storage of film edge code information.
EssenceAccess Specifies streaming access over a single channel of essence data.
EssenceData Specifies an essence container.
EssenceDescriptor Specifies the description of the format of the content data associated with a file source mob or of the media associated with a physical source mob.
EssenceFormat Specifies a collection of parameters (such as image height/width, audio sample width) which describes a piece of essence.
EssenceGroup Specifies the description of multiple digital representations of the same original content source.
EssenceMultiAccess Specifies streaming access over over multiple channels of essence data.
Event Specifies a text comment, a trigger, or an area in the image that has an associated interactive action.
EventMobSlot Specifies a container for a sequence of events.
Filler Specifies an unspecified value for the duration of a component.
FilmDescriptor Specifies the description of film media.
FindSourceInformation Specifies a search result containing source information about particular mob slots.
GetFileBits Specifies a mechanism to obtain the raw bits of a file after close.
GPITrigger Specifies a trigger action that should be taken when the GPI trigger is reached.
Header Specifies file-wide information and indexes.
HTMLClip Specifies a reference to HTML text essence.
HTMLDescriptor Specifies a description of essence data that is in HTML text format.
Identification Specifies identity information about the application that created or modified a file.
ImportDescriptor Specifies the description of a file essence source that is not directly manipulated by an AAF application.
InterchangeObject Specifies the root class for all AAF persistent classes.
InterpolationDefinition Specifies a definition for the mechanism used to calculate the values produced by a varying value using the specified control points.
KLVData Specifies a container for user data specified with a key (SMPTE label), length and value.
KLVDataDefinition Specifies the documentation for the KLV data objects used in a file.
Locator Specifies information to help find a file that contains the essence or to help find the physical media.
MasterMob Specifies a material object that provides access to source mobs and essence data.
MetaDefinition Specifies the definition of a class, type, or property in an AAF file.
Mob Specifies a material object (mob), which can describe a composition, essence, or physical media.
MobSlot Specifies a single track in a mob.
MPEGVideoDescriptor Specifies the description of picture essence that is encoded according to the MPEG specifications.
MultipleDescriptor Specifies the description of content data associated with a single file source mob that contains multiple tracks of essence.
NestedScope Specifies a scope and has an ordered set of segments.
NetworkLocator Specifies information to help find a file containing essence, using a uniform resource identifier (URI).
OperationDefinition Specifies the definition of an operation that is performed on an array of segments.
OperationGroup Specifies a container with an ordered set of segments and an operation that is performed on these segments.
Parameter Specifies an effect control value.
ParameterDefinition Specifies the definition of a kind of parameter for an effect.
PCMDescriptor Specifies the description of a file source mob that is associated with audio essence formatted according to the BWF file format.
PhysicalDescriptor Specifies the description of an essence source that is not directly manipulated by an AAF application.
PluginDefinition Specifies the definition of code objects that provide an implementation for a definition, such as a codec definition, or for a meta definition, such as a class definition.
Property Specifies the definition and current value of a property.
PropertyDefinition Specifies the description of a property allowed for a class.
PropertyValue Specifies the type and current value of a property.
Pulldown Specifies a conversion between film frame rates and videotape frame rates.
RandomFile Specialized file interface for use with files which exist on storage media which has random access capability.
RandomRawStorage This interface is used by the toolkit to access storage in which AAF files are to be read and written.
RawStorage This interface is used by the toolkit to access storage in which AAF files are to be read and written.
RecordingDescriptor Specifies the description of file source material which has no physical source.
RGBADescriptor Specifies the description of a file of video essence formatted with three color components or with three color components and an alpha component.
RIFFChunk Specifies a chunk of resource interchange file format (RIFF) data, identified by a 4-byte tag and variable size field.
ScopeReference Specifies a reference to a section in the specified mob slot or nested scope slot.
SearchSource Specifies a search for source information of a slot in a master mob or source mob.
Segment Specifies a component that is independent of any surrounding object.
Selector Specifies a selected value of a single segment while preserving references to unused alternatives.
Sequence Specifies the combination of an ordered list of segments and transitions.
SetFileBits This interface is implemented by the toolkit, and is provided to clients of AAF file to allow them to supply the raw bits of a file before open.
SoundDescriptor Specifies the description of a file source mob that is associated with audio essence.
SourceClip Specifies a representation of essence and identifies the source of the essence.
SourceMob Specifies the description of essence that is either stored in a digital form in a file or stored on a physical media, such as tape or film.
SourceReferenceSegment Specifies the representation of essence or other data described by a mob slot in a mob.
StaticMobSlot Specifies a single track of essence data that has no relationship to time, such as a static image.
SubDescriptor Specifies additional descriptor metadata that is not provided in the specified essence descriptor class hierarchy.
TaggedValue Specifies a user defined tag and value pair.
TaggedValueDefinition Specifies the documentation of tagged values used in a file.
TapeDescriptor Specifies the description of audio tape or video tape media.
TextClip Specifies a reference to text essence.
TextLocator Specifies information to help find a file containing the essence or to help find the physical media.
TIFFDescriptor Specifies the description of a file of video essence formatted according to the Tagged Image File Format (TIFF) specification.
TimecodeSegment Specifies the storage of video tape or audio tape timecode information.
TimecodeStream Specifies a stream of timecode data.
TimecodeStream12M Specifies a stream of timecode data in the SMPTE 12M format.
TimelineMobSlot Specifies a track that describes time-varying timeline essence.
Transition Specifies that the two adjacent Segments should be overlapped when they are played and that the overlapped sections should be combined using the specified effect.
TypeDefinition Specifies the definition of a property type.
TypeDefinitionCharacter Specifies the definition of a property type that has a value of a single 2-byte character.
TypeDefinitionEnumeration Specifies the definition of a property type that can have one of a set of integer values.
TypeDefinitionExtendibleEnumeration Specifies the definition of a property type that can have one of an extendible set of AUID values.
TypeDefinitionFixedArray Specifies the definition of a property type that has a fixed number of values of the underlying type.
TypeDefinitionIndirect Specifies the definition of property values whose type is specified in each instance.
TypeDefinitionInteger Specifies the definition of a property type that is an integer with the specified number of bytes.
TypeDefinitionObjectReference Specifies the definition of a property type that defines an object relationship.
TypeDefinitionOpaque Specifies the definition of property values whose type is specified in each instance, providing access to data opaque to this API and manipulated directly by an application through a handle.
TypeDefinitionRecord Specifies the definition of a property type that consists of an ordered set of fields, where each field has a name and type.
TypeDefinitionRename Specifies the definition a property type that has the same structure and representation as its underlying type but has a different meaning.
TypeDefinitionSet Specifies the definition of a property type that has a collection of object references to uniquely identified objects.
TypeDefinitionStream Specifies the definition of a property type that is stored in a stream and has a value that consists of a varying number of bytes.
TypeDefinitionString Specifies the definition of a property type that consists, effectively, of an array of the underlying character or integer type.
TypeDefinitionStrongObjectReference Specifies the definition of a property type that defines an object relationship where the target of the strong reference is owned by the object with the property with the strong object reference type.
TypeDefinitionVariableArray Specifies the definition of a property type that has a varying number of values of the underlying type.
TypeDefinitionWeakObjectReference Specifies the definition of a property type that defines an object relationship where the target of the weak reference is referenced by the object with the property with the weak object reference type.
VaryingValue Specifies a changing data value for an effect control value.
WAVEDescriptor Specifies the description of a file of audio essence formatted according to the RIFF Waveform Audio File Format (WAVE).
 

Class Summary
DescriptiveMarker.AllSlotsDescribed Contrived inner class that represents the set of all positive integers and zero.
 

Package tv.amwa.maj.iface Description

Specifications of all the persistent and meta classes of AAF as Java interfaces.

The root class for all persistent classes that can be serialized to an AAF file is InterchangeObject and the MAJ API provides implementation of these classes in the entity package. The root class for the meta definition of those classes is MetaDefinition, which can also be serialized to an AAF file used as part of a meta dictionary, have implementations in the meta package.

Heritage

The interfaces in this package were derived from the COM API provided with the C++ reference implementation for AAF in file "AAF.idl". This COM API provides a set of public interfaces to AAF classes that map well to Java interfaces, with the benefit that the translated interfaces will have a similar names and support similar implementation patterns to those of the reference implementation. This will be an advantage in the event that any existing C-based code using the reference implementation is ported to Java.

This section describes issues that were encountered in the translation of the interfaces and methods from the COM API into Java interfaces. These include a different approach to exceptional conditions, representation of optional properties, enumerators over collections and default values.

Table of contents

Derivation from COM interfaces

The file "AAF.idl" in the C-based AAF reference implementation contains the specifications of a number of interfaces and their associated methods. These interfaces cover all of the classes of the AAF object specification, including meta definitions. Additional interfaces are also specified relating to file handling and, where appropriate, these have been included in the MAJ API. Where the standard Java API provides built-in features duplicated in the COM interfaces, the Java approach is chosen in preference.

In general, each interface in "AAF.idl" maps to a public Java interface in this package. Due to Java rules constraining one public interface to be defined in one file, this means that the single file in the existing reference implementation has mapped to 117 files in the MAJ API! An interface named IAAFMob becomes just Mob in the MAJ API. Translation of the material object (mob) interface will now be used as an example of how interfaces have been translated from the COM API into the MAJ API.

Interface translation

For each interface in the COM API, documentation refers to a number of independent interfaces that must be additionally implemented by any implementation of the interface to achieve the AAF class hierarchy. This approach could have been adopted in the MAJ API but no automatic compiler checking would take place to ensure all the required methods were provided in any implementation. Instead, the MAJ API uses interface inheritance. For the mob example, the COM API documentation says that all all mobs must also implement IAAFObject. In the MAJ API, this interface is known by its specified name of InterchangeObject and the mob interface extends this.

    public interface Mob
        extends InterchangeObject {
        
            ...
    }

When the COM API is extended to support new features, extra interfaces are added. In the case of a mob, new methods have been specified in interface IAAFMob2. These extended interfaces have been merged into one interface in the MAJ API, meaning that all the methods of interface IAAFMob2 from the COM API are included in interface Mob in the MAJ API.

Basic method translation

Every mob has a mob id property with get and set methods that allow that property to be set in both the COM API and MAJ API. These methods are specified in the COM API as follows:

    HRESULT GetMobID (
        [out] aafMobID_t *  pMobID);
        
    HRESULT SetMobID (
        [in, ref] aafMobID_constref  mobID);  

These methods translate to the following methods in the MAJ API:

    public @MobIDType tv.amwa.maj.record.MobID getMobID();
    
    public void setMobID(
            @MobIDType tv.amwa.maj.record.MobID mobId)
        throws NullPointerException;

The steps taken in the method translation illustrated by the code above are as follows:

String property method translation

String handling is different between the C-based COM API, which uses null-terminated sequences of aafCharacter_t values, and the MAJ API, which uses the built-in Java string class. For the mob interface, the following methods are defined to set the name of the mob:

    HRESULT SetName (
        [in, string] aafCharacter_constptr  pName);
        
    HRESULT GetNameBufLen (
        [out] aafUInt32 *  pBufSize);
        
    HRESULT GetName (
        [out, string, size_is(bufSize)] aafCharacter *  pName,
        [in] aafUInt32  bufSize);

These three methods translate to the following methods in the mob interface of the MAJ API:

    public void setName(
        @AAFString String name);
                        
    public @AAFString String getName()
        throws PropertyNotPresentException;

The GetNameBufLen method of the COM API is required so that a character buffer of the appropriate size can be passed to GetName. Java can return a string object without the need for a buffer to be provided, so a name buffer length method is not required.

The name property is optional for the AAF specified Mob class. If the GetName method of the COM API is called when the name is not present, a AAFRESULT_PROP_NOT_PRESENT result code is returned. In the MAJ API, this is replaced by throwing a PropertyNotPresentException exception. Most result codes from the COM API have been translated to Java exceptions, either as standard Java exceptions or newly created, MAJ API-specific exceptions are described further in the description of the exception package. Also, see the MAJ API approach to omitted property values.

Multiple out parameters

Some methods in the COM API have multiple out parameters. Java only supports the return of one parameter from a method, but this can be an interface to an object with several properties, acting like a record. Where this is the case, an interface to access multi-parameter return values has been created in the record package with an implementation in the argument package.

As an example, consider the following method in the COM API that returns the fade values of a source clip:

    HRESULT GetFade (
        [out] aafLength_t *    pFadeInLen,
        [out] aafFadeType_t *  pFadeInType,
        [out] aafBoolean_t *   pFadeInPresent,
        [out] aafLength_t *    pFadeOutLen,
        [out] aafFadeType_t *  pFadeOutType,
        [out] aafBoolean_t *   pFadeOutPresent);

This is replaced by the following method in the MAJ API:

    public tv.amwa.maj.record.Fade getFade();

The fade interface of the MAJ API is specified to have the following methods:

    public interface Fade {
    
        public @LengthType long getFadeInLength();
        public void setFadeInLength(@LengthType long fadeInLength);
        
        public FadeType getFadeInType();
        public void setFadeInType(FadeType fadeInType);
        
        public boolean isFadeInPresent();
        
        public @LengthType long getFadeOutLength();
        public void setFadeOutLength(@LengthType long fadeOutLength);
        
        public FadeType getFadeOutType();
        public void setFadeOutType(FadeType fadeOutType);
        
        public boolean isFadeOutPresent();
    }

Object initialization

In the COM API, some objects are represented as having a not initialized and initialized state. The specification of these classes may define an initialize method, which could return an already initialized result if the object is already in an initialized state. Also, many methods in the reference implementation are specified to return a not initialized result to indicate that the object on which they were called is in the not initialized state.

In the MAJ API interfaces, all objects are considered initialized once they are created, which greatly simplifies the resulting code and relies on Java's object state management rather than requiring an implementor to write their own. Therefore, no public mechanism is provided to create a class without setting its required parameters. Instead, use the factory methods of this package or the public constructors of the implementations in the entity package.

If an interface defines an initialize method in the COM API, this is used to ensure that all required parameters without default values are provided before an object can be considered as initialized. These parameters have been ported over to the factory methods of the MAJ API's factory.

As an example, the following is the initialize method for a filler in the COM API:

    HRESULT Initialize (
        [in] IAAFDataDef *  pDataDef,
        [in] aafLength_t    length);

In the MAJ API, the same result is achieved using the makeFiller() method:

    Filler makeFiller(
            DataDefinition dataDefinition,
            @LengthType long length)
        throws java.lang.NullPointerException,
            BadLengthException;

The implementation of a filler in the entity package also has a matching public constructor:

    public Filler(
            tv.amwa.maj.iface.DataDefinition dataDefinition,
            @LengthType long length)
        throws NullPointerException,
            BadLengthException { ... }

In general, the factory methods of the MAJ API are not a direct mapping to the initialize methods of the COM API, providing an application with a different set of options for object creation.

Naming

COM API names and Java names

The COM API uses a number of abbreviations in its names for methods and classes, such as "Def" for "Definition". As many IDEs for Java offer auto-completion facilities, the approach adopted for the MAJ API is that names should be as close as possible to full-length English words. The intention is to make any Java code as readable as possible. The table below shows some of the expansions:

COM API aliasMAJ API nameCOM API exampleMAJ API equivalent
DefDefinitionOperationDefOperationDefinition
EnumEnumerationTypeDefEnumTypeDefinitionEnumeration
IntIntegerTypeDefIntTypeDefinitionInteger
ObjectInterchangeObjectIAAFObjectInterchangeObject
ObjRefObjectReferenceTypeDefWeakObjectRefTypeDefinitionWeakObjectReference

Wherever possible, the names used in the MAJ API match those used in AAF object specification. Names that are abbreviated in the specification remain abbreviated for the MAJ API, such as "AlphaMinRef".

Naming conflicts

Applying the mapping of the film edge code data type in the "AAFTypes.h" to Java in the same way as other structures would create a Java interface in the MAJ API called Edgecode. Applying the mapping of COM API interfaces to the existing AAF reference implementation to Java interfaces would also create an interface called Edgecode. To resolve this naming conflict, the edgecode structure is mapped to an EdgecodeValue and the AAF specified class becomes EdgecodeSegment.

A similar naming conflict has been encountered for Timecode. The timecode structure maps to a Java interface in the MAJ API called TimecodeValue and the timecode interface for the specified AAF class is called TimecodeSegment.

Another conflict existed between the AAF specified class SourceReference and structure "aafSourceRef_t". The source reference structure maps to a Java interface in the MAJ API called SourceReferenceValue and the source reference interface for the specified AAF class is called SourceReferenceSegment.

To avoid conflicts with commonly used Java class names in the Java API, some classes in the MAJ API have had the letters "AAF" appended to the start of their names or reverted to their specified names. These include:

AAF ref. impl. nameMAJ API nameto avoid conflict with
File AAFFilejava.io.File
FileDescriptor AAFFileDescriptorjava.io.FileDescriptor
Object InterchangeObjectjava.lang.Object

Representing lists, arrays and sets

The AAF object specification specifies three data types for the representation of collections: fixed size arrays, variable size arrays and sets. Methods of the COM API that allow access to properties of these types may return type-specific enumerators over the elements of a collection or pointers to arrays with the size of that array. The MAJ API approach is different and depends on the type defined for a property.

Fixed and variable sized arrays

For arrays of values that are represented in the COM API by an out parameter that is a pointer to a block of memory containing a sequence of values, such as the channel ids property of a source reference segment, the MAJ API returns a Java array. This is the case for arrays of values of primitive types, such as UInt32, or record values, such as AUID.

The following code is the COM API method for retrieving the current value of the channel IDs property:

    HRESULT GetChannelIDs (
        [in] aafUInt32  numberElements,
        [in] aafUInt32*  pChannelIDs);

In the MAJ API, this has been translated to:

    public @UInt32Array int[] getChannelIDs();

For variable size arrays, the COM API also returns a length. This is not necessary in Java as every Java array is an object with access to its current length through its length field. For example:

    int[] channelIds = mySource.getChannelIDs();
    int channelIdsLength = channelIds.length;

Weak and strong reference vectors

The data types known as weak reference vectors and strong reference vectors in the AAF object specification are ordered collections of references to other AAF persistent objects or meta objects. These are not collections of elements of primitive or record types. The COM API includes a standard set of methods for manipulating any property of vector type, including append, insert at, remove at etc., as well as specifying a type-specific enumerator for ordered access to the elements. In the translation to the MAJ API, the methods are included and the type-specific enumerators are replaced by the use of the Java generic collections framework list type.

For example, the IEnumAAFMobSlots interface in the COM API is replaced by the Java java.util.List<? extends MobSlot> generic list in the MAJ API. The following code shows the COM API methods for managing the list of mob slots of a mob:

    HRESULT AppendSlot (
        [in] IAAFMobSlot * pSlot);
    HRESULT PrependSlot (
        [in] IAAFMobSlot * pSlot);
    HRESULT InsertSlotAt (
        [in] aafUInt32  index,
        [in] IAAFMobSlot * pSlot);
    HRESULT RemoveSlotAt (
        [in] aafUInt32  index);
    HRESULT GetSlotAt (
        [in] aafUInt32  index,
        [out, retval] IAAFMobSlot ** ppSlot);
    HRESULT GetSlots (
        [out] IEnumAAFMobSlots ** ppEnum);

This translates to the following methods in the MAJ API:

    public void appendSlot(
            MobSlot slot);
    public void prependSlot(
            MobSlot slot);
    public void insertSlotAt(
            int index,
            MobSlot slot);
    public void removeSlotAt(
            int index);
    public MobSlot getSlotAt(
            int index);
    public java.util.List<? extends MobSlot> getSlots();

Weak and strong reference sets

The data types known as weak reference sets or strong reference sets in the AAF object specification are unordered collections of references to other AAF persistent objects or meta objects. These are not collections elements of primitive types or record values. The COM API includes a standard set of methods for manipulating any property of set type, including add, count and remove etc., as well as specifying a type-specific enumerator for access to the elements in no particular order. In the translation to the MAJ API, the methods are included and the type-specific enumerators are replaced by the use of the Java generic collections framework set type.

For example, the IEnumAAFEssenceData interface in the COM API is replaced by the Java java.util.Set<? extends EssenceData> generic set in the MAJ API. The following code shows the COM API methods for managing the set of essence data items stored in a content storage:

    HRESULT AddEssenceData (
        [in] IAAFEssenceData * pEssenceData);
    HRESULT CountEssenceData (
        [out, retval] aafUInt32 *  pResult);
    HRESULT RemoveEssenceData (
        [in] IAAFEssenceData * pEssenceData);
    HRESULT LookupEssenceData (
        [in, ref] aafMobID_constref  mobID,
        [out,retval] IAAFEssenceData ** ppEssenceData);
    HRESULT EnumEssenceData (
        [out,retval] IEnumAAFEssenceData ** ppEnum);

This translates to the following methods in the MAJ API:

    public void addEssenceData(
            EssenceData essenceData);
    public @UInt32 int countEssenceData();
    public void removeEssenceData(
            EssenceData essenceData);
    public EssenceData lookupEssenceData(
            tv.amwa.maj.record.MobID mobId);
    public java.util.Set<? extends EssenceData> enumEssenceData();       

Shallow copy of a collection

The collections returned by methods such as Mob.getSlots() and ContentStorage.enumEssenceData() are specified to be shallow copies. This means that the actual collection object returned by the method is not the same as the one stored in the persistent object on which the method was called. Modifications to the structures of collection returned will not cause any side effects on the stored collection. However, the elements within the returned collection are not cloned and modifications to any of the elements will have a side effect on the elements stored within the persistent object owning the collection.

All MAJ API implementations of the interfaces in this package support cloning, so creating a deep copy of a collection is possible with code similar to the following example:

    Collection<? extends InterchangeObject> group;
    ...
    for ( InterchangeObject item : group ) {
        group.remove(item);
        group.add(item.clone());
    }

Although the interfaces of this package specify shallow copies only, an implementation of the interfaces of this package may return a deep copy of all collections. For reasons of efficiency, the implementations provided with the MAJ API only return shallow copies of collections. In general, this is acceptable for the manipulation of a file whereas for the creation of a media asset management system based on these classes, care needs to be taken when sharing items between collections.

Optional properties and default values

A property of an AAF persistent class or meta definition class may be either optional or required. Required properties shall always provide a value for any instance of their class. If a property is optional for a class, it may be either present or omitted from an instance of that class. This makes a lot of sense for efficient serialized representations of AAF objects where a sequence of bytes representing the instance of a class does not have to contain any bytes for a particular property. However, for a Java object or an entity persisted to a database in a media asset management system, it is necessary to provide get and set methods and have a column available to store all properties. This section describes the MAJ API approach to optional properties.

Required properties

Required properties are always considered as present and typically have a pair of get and set methods each, which work as follows:

As discussed earlier, the required mob id property's get and set methods for the mob class in the COM API:

    HRESULT GetMobID (
        [out] aafMobID_t *  pMobID);
        
    HRESULT SetMobID (
        [in, ref] aafMobID_constref  mobID);

The equivalent methods in the MAJ API are:

    public @MobIDType MobID getMobID();
    
    public void setMobID(
            @MobIDType MobID mobId)
        throws NullPointerException;

Omitted properties are Java null values

Java provides the null keyword to allow the value of any object to be interpretted by an application as undefined or not present. Any optional value within the MAJ API implementation of the interfaces of this package uses null internally to represent an omitted property value.

The behaviour of the interface methods for optional properties without default values are as follows:

Primitive types in Java, such as int and char, cannot be set to null. However, each of the primitive types has a corresponding object representation in the java.lang package, such as Integer and Character, that can be set to null. Therefore, set methods for optional properties of these types use the object representation as parameters so the property can be set to be omitted. Java provides auto-boxing and un-boxing of primitive values to/from their object-representation equivalent types, so there is no need to convert an int value to an Integer value before calling the set method.

For example, the optional "AudioRefLevel" property of a sound descriptor has no default value and the following get/set methods in the COM API:

    HRESULT GetAudioRefLevel (
        [out] aafInt8 *  pLevel);
        
    HRESULT SetAudioRefLevel (
        [in] aafInt8  level);

The get method shown above may return a result of AAFRESULT_PROP_NOT_PRESENT. The equivalent methods in the MAJ API are:

    public @Int8 byte getAudioRefLevel()
        throws PropertyNotPresentException;
    
    public void setAudioRefLevel(
            @Int8 Byte audioRefLevel);

Note that the use of Byte as the type for the parameter for the set method is deliberate to allow the property to be omitted by setting it to null.

Default values

Some optional properties have default values specified in the AAF object specification. For these properties, the interfaces of this package are specified to return the default value if an optional property is omitted. The default values are specified as constant values in the interface specification containing the associated optional property. For an RGBADescriptor, these are:

The behaviour of the interface methods for optional properties with default values are as follows:

This approach can make it difficult to find out if a property is present or omitted. Some interfaces include a is property present method, such as Fade.isFadeOutPresent(). An alternative approach is to use the isPropertyPresent() method of every interchange object. For example, use the following code to find out if the "AlphaMinRef" property is present for a RGBADescriptor:

    RGBADescriptor imageInfo;
    ...
    ClassDefinition imageInfoClass = imageInfo.getDefinition();
    PropertyDefinition alphaMinRefProperty = 
        imageInfoClass.lookupPropertyDefinition("AlphaMinRef");
    boolean alphaMinPresent = imageInfo.isPropertyPresent(alphaMinRefProperty);

As an example of an optional property with a default value, here are the methods to set and get the "AlphaMinRef" property in the COM API:

    HRESULT GetAlphaMinRef (
        [out] aafUInt32 *  pAlphaMinRef);
    
    HRESULT SetAlphaMinRef (
        [in] aafUInt32  alphaMinRef);

For the get method, the COM API does not return the default value when the property is omitted. Instead, it returns an AAFRESULT_PROP_NOT_PRESENT code. In contrast, the following equivalent MAJ API methods always succeed with the get method returning the default value when the property is omitted:

    public @UInt32 int getAlphaMinRef();
    
    public void setAlphaMinRef(
            @UInt32 Integer alphaMinRef);

The set method can be called with null to omit this property.

Cardinality and collections

Some collection properties are optional, some are allowed to be empty. The MAJ API represents collections of a specified cardinality as shown in the following table:

optional collectionrequired collection
0..* Property is omitted when the collection is empty. Property is present when it contains at least one item. No representation of an empty collection. Collection may be empty and present.
1..* Property is either omitted or the property is present and contains at least one value. Property should always contains at least one element.

This is problematic in the case that an AAF file deliberately represents an empty collection for a present optional property. The MAJ API makes no distinction between an empty optional collection property and an omitted optional collection property. Reading in a file with an empty present collection property will result in an internal MAJ API representation as a omitted collection property. Subsequent writing of the same data will omit the property.

Author:
Richard Cartwright

Media Authoring
with Java API

(c) 2007-2008 Richard Cartwright, all rights reserved. Subject to the terms of the AAF SDK Public Source License.