Defines constant values used throughout the MAJ API and defined by external specifications. Typically, these are unique identifiers defined by an {@linkplain tv.amwa.maj.record.AUID AUID} that fall into two categories:

  1. Unique identifiers for {@linkplain tv.amwa.maj.model.DefinitionObject defined objects} that can appear in the AAF {@linkplain tv.amwa.maj.model.Dictionary dictionary}. These definitions are annotated and managed as described below.
  2. Unique identifiers used as enumeration items in {@linkplain tv.amwa.maj.meta.TypeDefinitionExtendibleEnumeration extendible enumerations}.

The constants are all implemented within interfaces in useful groupings. For example, all the constants uniquely identifying container types are public final static fields within the {@link tv.amwa.maj.constant.ContainerConstant} interface. To make these constants available within a class, simply implement the interface. None of the interfaces in this package have methods so no requirement is placed on the implementor to write implementations for additional methods.

Heritage

Due to package and interface names providing a scope for constant names in Java, the preceding scope part of a definition's name in the MAJ API has been removed from the equivalent C name. For example, the codec definition identified as "CodecDef_JPEG" in the C-based AAF SDK (file "CodecDefs.h") is represented in the MAJ API by "{@link tv.amwa.maj.constant.CodecConstant#JPEG}". However, forName() methods of the various definition classes will accept both the MAJ API name and the C name.

Managing definitions dynamically

Every AAF file contains a {@linkplain tv.amwa.maj.model.Dictionary dictionary} holding a number of {@linkplain tv.amwa.maj.model.DefinitionObject definitions} for items used to specify instances of AAF classes. A number of definitions are specified by the SMPTE registries, other SMPTE specifications and more proprietary definitions. The interfaces of this package contain many of the specified or soon to be specified definitions. This section describes how the specified definitions can be turned into {@linkplain tv.amwa.maj.model.DefinitionObject definition object} instances and how extension definitions can be specified in the same way.

From this point onwards, {@linkplain tv.amwa.maj.model.CodecDefinition codec definitions} will be discussed as an example. However, everything said here about codec definitions applies equally to other kinds of definition objects. The table below shows the relationship between: the interface describing a classification of definition type; the interface containing unique identifiers for that class of definition; the annotation that provides additional metadata that is used to instantiate a definition.

definition interfaceunique identifiersmetadata annotation
{@link tv.amwa.maj.model.CodecDefinition} {@link tv.amwa.maj.constant.CodecConstant} {@link tv.amwa.maj.constant.CodecDescription}
{@link tv.amwa.maj.model.ContainerDefinition} {@link tv.amwa.maj.constant.ContainerConstant} {@link tv.amwa.maj.constant.ContainerDescription}
{@link tv.amwa.maj.model.DataDefinition} {@link tv.amwa.maj.constant.DataDefinitionConstant} {@link tv.amwa.maj.constant.DataDefinitionDescription}
{@link tv.amwa.maj.model.InterpolationDefinition} {@link tv.amwa.maj.constant.InterpolationConstant} {@link tv.amwa.maj.constant.InterpolationDescription}
{@link tv.amwa.maj.model.OperationDefinition} {@link tv.amwa.maj.constant.OperationConstant} {@link tv.amwa.maj.constant.OperationDescription}
{@link tv.amwa.maj.model.ParameterDefinition} {@link tv.amwa.maj.constant.ParameterConstant} {@link tv.amwa.maj.constant.ParameterDescription}

Creating definition instances

Definition instances can be created using the {@linkplain tv.amwa.maj.industry.Forge forge}:

    ContainerDefinition external = Forge.make(ContainerDefinitions.class,
        "DefinitionObjectIdentification", ContainerConstant.External,
        "DefinitionObjectName", "External");

Registering a definition instance

Definitions are registered with the {@linkplain tv.amwa.maj.industry.Warehouse warehouse} so that they can be referenced from any other instance by their identifier. The warehouse provides the {@link tv.amwa.maj.industry.Warehouse#register(tv.amwa.maj.model.DefinitionObject)} method for registration, for example:

    Warehouse.register(Forge.make(ContainerDefinitions.class,
        "DefinitionObjectIdentification", ContainerConstant.External,
        "DefinitionObjectName", "External") );

The registration takes place at runtime so that the range of definitions supported can be dynamically extended. Note that such a registration remains local within a virtual machine.

To lookup and use a registered definition, use the {@link tv.amwa.maj.industry.Warehouse#lookup(Class, String)} or {@linkplain tv.amwa.maj.industry.Warehouse#lookup(Class, tv.amwa.maj.record.AUID)} mehods. For example:

    ContainerDefinition external =
        Warehouse.lookup(ContainerDefinition.class, "External");

Registering a group of definition instances

All of the unique identifiers of this package related to definitions are annotated with additional metadata so that they can be used to instaciate definitions. For example, the {@linkplain tv.amwa.maj.constant.CodecConstant#JPEG JPEG codec} is defined with a {@linkplain tv.amwa.maj.constant.CodecDescription codec description annotation} as follows:

    @CodecDescription(fileDescriptorClass = "CDCIDescriptor",
        dataDefinitions = { "DataDef_Picture", "DataDef_LegacyPicture" },
        description = "Supports a constrained form of ISO/IEC 10918-1 JPEG images ...")
    public final static AUID JPEG = new tv.amwa.maj.embeddable.AUID(
            0x18634f8c, (short) 0x3bab, (short) 0x11d3,
            new byte[] { (byte) 0xbf, (byte) 0xd6, 0x00, 0x10, 0x4b, (byte) 0xc9, 0x15, 0x6d} );

The annotation has all the additional parameters required to construct a codec definition over and above just its name and unique identifier. To avoid duplication, the name and identifier are not repeated in the annotation

To register all the annotated constants defined in any interface or class, internally the {@linkplain java.lang.Class Java class} of an interface containing such annotated constants is passed to the registerXFromClass() method of a definitions implementation, replacing X with the name of the definition kind. For example, to register all of the codec definitions with unique identifiers in {@link tv.amwa.maj.model.CodecDefinition}:

    CodecDefinitionImpl.registerCodecsFromClass(CodecConstant.class);

In fact, any class containing an {@linkplain tv.amwa.maj.record.AUID AUID} constant annotated with a definition description can be passed to the appropriate registration method. The registration method looks through the class for the relevant annotations and registers any constants that it finds. There should never be a need to use the exact line above as it is executed automatically when the codec definition implementation class is loaded. This registration process is provided to enable dynamic runtime extension of the supported range of definitions.

Extending the range of definitions

This section describes the under-the-hood mechanism for bootstrapping definitions. A future version of the MAJ API will expose this capability through the warehouse.

The range of supported definitions can be extended beyond those provided as part of the MAJ API. To do this:

  1. Create an interface (or class) containing public static final fields of {@linkplain tv.amwa.maj.record.AUID AUID} values, with the name of the Java static field being the same as the name of the required definition. Take care to define an AUID so that it does not conflict with an existing SMPTE UL or UUID scheme used on your systems.
  2. Annotate the fields with the appropriate description, such as {@link tv.amwa.maj.constant.CodecDescription}. Some elements of the annotation are required and so values must be provided.
  3. Compile the interface (or class) and make sure it is available in the same classpath as the MAJ API.
  4. Register all of the definitions in your interface (or class) by calling the appropriate registerXFromClass() methods. For example:
        CodecDefinitionImpl.registerCodecsFromClass(my_package.MyCodecs.class);
     

Note that registering a definition within a Java local machine has no direct impact on the creation or management of {@linkplain tv.amwa.maj.model.Dictionary dictionaries}. The calls of the MAJ API described here are provided to help with dictionary management and to ensure consistent representation of definitions across dictionaries. The way that a dictionary is managed and interpreted is an application-specific issue.