Industry for manufacturing, storing and making instances of classes and meta-classes, referenced by names and registered identifiers. This package includes the tools required to carry out the runtime linkage between the Java programming language and media-specific standards from AMWA and SMPTE. Also included are tools to generate database mappings and schema.

The package is generic and permits types other than those defined for AAF from being used to write an application. This package has been designed to ensure full support for the AAF meta model and has been tested for the AAF object model but is not tied to it.

# Core industrial units

Developer's of applications the create and manipulate media data using MAJ need to use the three main classes of static methods in the MAJ industry package. The heavy lifting of the MAJ API is carried out by the following three classes:

- New instances of objects and values can be made using the {@linkplain tv.amwa.maj.industry.Forge forge}.
- Existing objects can be manipulated using the {@linkplain tv.amwa.maj.industry.MediaEngine media engine}.
- An registration and search capability for shared definitions, including all classes and types known to the running virtual machine, are stored in the runtime-dynamic {@linkplain tv.amwa.maj.industry.Warehouse warehouse}.

Every virtual machine needs to have a warehouse full of all classes, types, enumerations elements etc. before useful applications can be written Most applications will need to start by registering all the AAF classes and types etc. using the convenience static method {@link tv.amwa.maj.industry.MediaEngine#initializeAAF() MediaEngine.initializeAAF()} method. User defined types are then registered.

# Link to Java

## Implemented interfaces

All classes that are to be manipulated by the {@linkplain tv.amwa.maj.industry.MediaEngine media engine} and serialized to and from files must implement the {@link tv.amwa.maj.industry.MetadataObject MetadataObject} interface. This is an empty interface with no additional requirements and is used to signal to MAJ that you want to permit the object to be treated as an item of media metadata.

Any classes that are also to be treated as persistent entities should instead implement the {@link tv.amwa.maj.industry.MediaEntity MediaEntity} interface, which extends the {@link tv.amwa.maj.industry.MetadataObject MetadataObject} interface. A media interface gas a unique persistent identifier for its type for the database where it is to be stored. It also has a list index value for occasions when the entity is part of an ordered list and that list needs to be persisted in the correct order in a database.

## Annotations

This package defines a number of Java annotations that can be used to enhance a Java class and provide additional information that is required to use the class for representing media data. The annotations are read at runtime and used to plumb the class into the capabilities of the media engine and input/output libraries. The annotations provide missing information, such as SMPTE universal labels and AAF type names that cannot be extracted directly from the Java class itself. Specifically:

- A Java class can become the specification of an AAF {@linkplain tv.amwa.maj.meta.ClassDefinition class definition} by annotating it as a {@linkplain tv.amwa.maj.industry.MediaClass media class}.
- The set and get methods of a class can become {@linkplain tv.amwa.maj.meta.PropertyDefinition properties} of a class by annotating methods with {@linkplain tv.amwa.maj.industry.MediaProperty media property getter} and {@linkplain tv.amwa.maj.industry.MediaPropertySetter media property setter} annotations.
- For methods relating to properties of a collection, additional annotations are defined, including:
  - {@linkplain tv.amwa.maj.industry.MediaPropertyContains collection contains};
  - {@linkplain tv.amwa.maj.industry.MediaPropertyCount count the number of elements};
  - {@linkplain tv.amwa.maj.industry.MediaPropertyClear clear the collection to empty};
  - {@linkplain tv.amwa.maj.industry.MediaPropertyRemove remove an element}.
- To label a method used to add elements to a set, the specific {@linkplain tv.amwa.maj.industry.MediaSetAdd add to set} annotation is provided;
- For methods relating to elements of a list, the following annotations should be used:
  - {@linkplain tv.amwa.maj.industry.MediaListAppend append an element to the list};
  - {@linkplain tv.amwa.maj.industry.MediaListPrepend prepend an element to the list};
  - {@linkplain tv.amwa.maj.industry.MediaListGetAt get an element at a specific index};
  - {@linkplain tv.amwa.maj.industry.MediaListInsertAt insert an element at a specific index};
  - {@linkplain tv.amwa.maj.industry.MediaListRemoveAt remove an element at a specific index}.

In general, the inheritance class hierarchy of the Java classes is mirrored in the media class definitions. However, sometimes the mechanics of an application require more classes in the Java class hierarchy than are represented in the media class hierarchy. The extra Java classes should be annotated as {@linkplain tv.amwa.maj.industry.HiddenClass hidden classes}.

## Data types

In general, where an obvious mapping between an AAF data type and a Java data type exist, such as between an Int32 and an `int`, this is used and documented in the appropriate package. Some special case mappings not covered elsewhere are described in this section.

### Baseline definitions

All baseline type definitions of AAF are contained in the {@link tv.amwa.maj.industry.TypeDefinitions TypeDefinitions} interface. Static reference can be made to these types and the interface can be implemented to provide localised access.

All baseline classes of the AAF object model to the version currently supported by MAJ are listed in the static fields of the {@link tv.amwa.maj.industry.AAFSpecifiedClasses AAFSpecifiedClasses} interface.

### Weak references

Some references between objects in an AAF-based meta model are weak, allowing the target of the reference to be shared by many sources. The reference is made by using the unique identifier of the targeted item. All potential targets of weak references are required to implement the {@link tv.amwa.maj.industry.WeakReferenceTarget WeakReferenceTarget} interface, which provides a unique name and identifier by which the item can be referenced.

The source of the reference should be implemented as a field within a class as the generic class {@link tv.amwa.maj.industry.WeakReference WeakReference}. This provides mechanisms within a specific Java virtual machine for resolving and persisting weak references. However, the get and set methods for the property should use the target object itself.

When persisted to a file, a container within the file will store all the weak reference targets so that they can be resolved at runtime. For example, the {@linkplain tv.amwa.maj.model.Dictionary dictionary} stores all the {@linkplain tv.amwa.maj.model.DefinitionObject definitions} used within a file.

### Weak reference collections

Sets of weak references are represented by a field of the owning class with generic type {@link tv.amwa.maj.industry.WeakReferenceSet WeakReferenceSet}. The methods of the generic type can be used to provide the property manipulating methods of the owing class.

Similarly, lists of weak references are represented by a field of the owning class with generic type {@link tv.amwa.maj.industry.WeakReferenceVector WeakReferenceVector}. The methods of the generic type can be used to provide the property manipulating methods of the owing class.

### Strong references

A strong reference in MAJ is represented by the interface for the target class. As the source of the reference owns the target, MAJ is very particular to clone all implementing objects on setting and getting the values to avoid side effects. Be aware, however, that Java cloning is shallow and a developer still needs to take care to avoid side effects if setting multiple strong reference type properties with the same instance of a class.

### Strong reference collections

Sets of strong references are represented as a field of their owning class by a {@link java.util.Set java.util.Set}, parameterized by the type of element in the set. Static, generic methods for manipulating the set are provided in the {@link tv.amwa.maj.industry.StrongReferenceSet StrongReferenceSet} class and these can be used as a basis the methods that manipulate the value of the set property.

Similarly, lists of string references are represented as a field of their owning class by a {@link java.util.List java.util.List}, parameterized by the type of the element in the list. Static, generic methods for manipulating the list are provided in the {@link tv.amwa.maj.industry.StrongReferenceVector StrongReferenceVector} class and these can be used as a basic for the methods that manipulate the value of the list property. For lists, this has the specific advantage that list order indexes used when persisting the list to a database are maintained for you.

It is recommended that synchronized sets and lists are used in implementation to avoid runtime clashes.

### Streams

A value of {@linkplain tv.amwa.maj.meta.TypeDefinitionStream stream type} is represented by an implementation of the {@link tv.amwa.maj.industry.Stream Stream} interface. This interface provides a means to seek, read and write bytes to and from an underlying stream. A {@linkplain tv.amwa.maj.industry.MemoryResidentStream memory resident stream} and a {@linkplain tv.amwa.maj.industry.FileStream basic file stream for raw essence access} are provided in this package. File-type-specific stream access is provided by implementations of this class for, for example for {@linkplain tv.amwa.maj.io.aaf.AAFStream streams in structured storage containers (AAF)} or {@linkplain tv.amwa.maj.io.aaf.MXFStream wrapped in KLV streams (MXF)}.

A mechanism is also provided to resolve a stream identifier reference to a specific stream location using the {@linkplain tv.amwa.maj.industry.StreamResolver stream resolver}. A default {@linkplain tv.amwa.maj.industry.LocalFileResolver local file resolver} provides access to local streams through the relevant methods of the {@linkplain tv.amwa.maj.industry.MediaEngine media engine}. Alternative stream resolvers can be implemented and used in place of the default one.

## Property type mapping table

The table below describes the data type mappings carried out by MAJ when {@linkplain tv.amwa.maj.industry.MediaEngine#getPropertyValue(tv.amwa.maj.industry.MetadataObject, java.lang.String) getting} and {@linkplain tv.amwa.maj.industry.MediaEngine#setPropertyValue(tv.amwa.maj.industry.MetadataObject, java.lang.String, java.lang.Object) setting} properties using the generic methods of the {@linkplain tv.amwa.maj.industry.MediaEngine media engine} and creating objects using the {@linkplain tv.amwa.maj.industry.Forge forge}. For generic handling of individual property values, the {@linkplain tv.amwa.maj.industry.PropertyValue PropertyValue} interface is provided as a container for both the {@linkplain tv.amwa.maj.meta.TypeDefinition type definition} and the Java-based representation of the value.

Type classification | Accepted Java types | Returned Java type
{@linkplain tv.amwa.maj.meta.TypeDefinitionInteger Integer} | primitive `int`, `short`, `int` or `long` value. {@link java.lang.Byte}, {@link java.lang.Short}, {@link java.lang.Integer} or {@link java.lang.Long} value. A {@link java.lang.String} representation of the number. `byte[]` or {@linkplain java.nio.ByteBuffer} value with enough bytes to represent the type of value. | {@link java.lang.Byte}, {@link java.lang.Short}, {@link java.lang.Integer} or {@link java.lang.Long} value, depending on integer bit size.
{@linkplain tv.amwa.maj.meta.TypeDefinitionString String} | {@link java.lang.String} `byte[]` or {@linkplain java.nio.ByteBuffer} UTF-16 encoding of the string. | {@link java.lang.String}
{@linkplain tv.amwa.maj.meta.TypeDefinitionEnumeration Enumeration} | Enumeration value of type {@link java.lang.Enum}. Element name for the enumeration value. {@linkplain tv.amwa.maj.industry.MediaEnumerationValue#symbol() Symbol} for the enumeration value. {@linkplain tv.amwa.maj.industry.MediaEnumerationValue#value() Numerical code} for the enumeration value. `byte[]` or {@linkplain java.nio.ByteBuffer} encoding of the value. `boolean` or {@link java.lang.Boolean} for the Boolean enumeration only. | Enumeration value of type {@link java.lang.Enum} or primitive `boolean` for Boolean enumeration
{@linkplain tv.amwa.maj.meta.TypeDefinitionExtendibleEnumeration Extendible Enumeration} | Element value, which is an {@linkplain tv.amwa.maj.record.AUID}. Element value encoded as a string, e.g. starting "`urn:smpte:ul:...`". Element name for the enumeration value. `byte[]` or {@linkplain java.nio.ByteBuffer} 16-byte encoding of the AUID value. | Element value, which is an {@linkplain tv.amwa.maj.record.AUID}.
{@linkplain tv.amwa.maj.meta.TypeDefinitionStream Stream} | `byte[]` or {@linkplain java.nio.ByteBuffer} representation of the stream. To be improved with external file reference ... | Implementation of the {@link tv.amwa.maj.industry.Stream Stream} interface.
{@linkplain tv.amwa.maj.meta.TypeDefinitionRecord Record} | Value implementing the {@linkplain tv.amwa.maj.meta.TypeDefinitionRecord#getSpecification() associated interface specification}, e.g. the interfaces in the `tv.amwa.maj.record` package. String representation of the value, e.g. "`3/4`" for a {@linkplain tv.amwa.maj.record.Rational rational value}. An array of {@linkplain tv.amwa.maj.industry.PropertyValue property values} in the property order of the record. `byte[]` or {@linkplain java.nio.ByteBuffer} representation of the record value. | Value implementing the {@linkplain tv.amwa.maj.meta.TypeDefinitionRecord#getSpecification() associated interface specification}, e.g. the interfaces in the `tv.amwa.maj.record` package.
{@linkplain tv.amwa.maj.meta.TypeDefinitionIndirect Indirect} | Unwrapped {@linkplain tv.amwa.maj.industry.PropertyValue property value} of the indirect value, which contains its actual type and value. | Unwrapped {@linkplain tv.amwa.maj.industry.PropertyValue property value} of the indirect value, which contains its actual type and value.
{@linkplain tv.amwa.maj.meta.TypeDefinitionIndirect Opaque} | `byte[]` or {@linkplain java.nio.ByteBuffer} representing the opaque value. | {@linkplain java.nio.ByteBuffer} representing the opaque value.
{@linkplain tv.amwa.maj.meta.TypeDefinitionFixedArray FixedArray} | Array of elements of the array's underlying type. Array of {@linkplain tv.amwa.maj.industry.PropertyValue property values}. {@linkplain java.util.Colleciton Collection} of elements of the array's underlying type or {@linkplain tv.amwa.maj.industry.PropertyValue property values}. `byte[]` or {@linkplain java.nio.ByteBuffer} representing a sequence of elements of the array's underlying type. | Array of elements of the array's underlying type as an `Object[]`.
{@linkplain tv.amwa.maj.meta.TypeDefinitionStrongObjectReference Strong Object Reference} | Referenced object of the referenced type. {@linkplain tv.amwa.maj.industry.PropertyValue property value} containing the referenced value. | Referenced object of the referenced type.
{@linkplain tv.amwa.maj.meta.TypeDefinitionWeakObjectReference Weak Object Reference} | Referenced object of the referenced type. {@linkplain tv.amwa.maj.industry.PropertyValue property value} containing the referenced value. Name of target of the reference to be looked up and resolved in the warehouse. | Referenced object of the referenced type.
{@linkplain tv.amwa.maj.meta.TypeDefinitionSet Set} | {@linkplain java.util.Collection Collection} of objects of the referenced type or a {@linkplain java.util.Collection collection} of {@linkplain tv.amwa.maj.industry.PropertyValue property values} containing the referenced values. Array of objects of the referenced type or an array of {@linkplain tv.amwa.maj.industry.PropertyValue property values} containing the referenced values. A single value of the referenced type or a single {@linkplain tv.amwa.maj.industry.PropertyValue property value} to make a set of size one from. | {@linkplain java.util.Set Set} of objects of the referenced type.
{@linkplain tv.amwa.maj.meta.TypeDefinitionVariableArray Variable Array} | {@linkplain java.util.Collection Collection} of objects of the referenced type or a {@linkplain java.util.Collection collection} of {@linkplain tv.amwa.maj.industry.PropertyValue property values} containing the referenced values. Array of objects of the referenced type or an array of {@linkplain tv.amwa.maj.industry.PropertyValue property values} containing the referenced values. A single value of the referenced type or a single {@linkplain tv.amwa.maj.industry.PropertyValue property value} to make a set of size one from. | {@linkplain java.util.List List} of objects of the referenced type.

## Database mapping

A Java Persistence API configuration file for a given set of classes can be generated by MAJ using the static methods of the {@link tv.amwa.maj.industry.JPAGenerator JPAGenerator} class. To be able to persist AAF, pass in the lists of {@linkplain tv.amwa.maj.industry.AAFSpecifiedClasses baseline classes}.

@see tv.amwa.maj.util.AutoGeneration