TOP

ASN.1/Java Compiler Representation

Applies to: ASN.1/Java 7.1

Project Packages

The packages and classes generated by the OSS ASN.1 compiler for Java are placed in the project package directory whose name is derived from the name of the last ASN.1 file input to the compiler (it can also be specified with the -output compiler option and converted to lowercase letters).

Projects and Project Classes

A project consists of ASN.1 files that are input to the compiler and Java packages and classes generated by the compiler. For more information, see the ASN1Project class subsection.

A project class takes the name of the package. This class defines information used internally by the encoders/decoders and methods for accessing the Coders.

Example

public class Example extends ASN1Project {
   public ProjectInfo getProjectInfo()
   public static Coder getDefaultCoder()
   public static BERCoder getBERCoder()
   public static DERCoder getDERCoder()
   public static PERAllignedCoder getPERAlignedCoder()
   public static PERUnalignedCoder getPERUnalignedCoder()
   public static XERCoder getXERCoder()
   public static CXERCoder getCXERCoder()
   public static EXERCoder getEXERCoder()
}

A project class can also provide an optional helper API for PDU detection and decoding. When the -helperAPI pdudecoder command line option is specified, the project class will contain PDU and PDU_ID inner classes that define the PDU decoding API.

Example with -helperAPI pdudecoder specified

public class Example extends ASN1Project {
   public ProjectInfo getProjectInfo()
   public static Coder getDefaultCoder()
   public static BERCoder getBERCoder()
   public static DERCoder getDERCoder()
   public static PERAllignedCoder getPERAlignedCoder()
   public static PERUnalignedCoder getPERUnalignedCoder()
   public static XERCoder getXERCoder()
   public static CXERCoder getCXERCoder()
   public static EXERCoder getEXERCoder()

   public static enum PDU_ID {...}
   public static class PDU extends AbstractPDU<PDU_ID> {
     public static PDU decode(java.io.InputStream source, BERCoder coder)
     public static PDU decode(java.io.InputStream source, DERCoder coder)
     public static PDU decode(java.io.InputStream source, XERCoder coder)
     public static PDU decode(java.io.InputStream source, CXERCoder coder)
   }
}

Version Information

The -helperAPI pdudecoder option is available in version 7.0 and later.

Module Packages and Module Classes

The name of each ASN.1 module found in the ASN.1 source specification is used to create a module package.

A module package consists of module classes and classes generated by the compiler to represent ASN.1 types found within a module.

Example

ASN.1 compiler for Java command line:

asn1pjav test  o p.myproject  valuerefs

ASN.1:

MyProtocol DEFINITIONS ::= BEGIN
    bufferSize INTEGER ::= 1024
    Data ::=   SEQUENCE {
                  name PrintableString
               }
END

Created directories:

p/myproject/                             - project package
p/myproject/Myproject.java               - project class
p/myproject/myprotocol/                  - module package
p/myproject/myprotocol/MyProtocol.java   - module class
p/myproject/myprotocol/Data.java         - typereference Data class

Generated project class in the p/myproject subdirectory:

package p.myproject;

import com.oss.asn1.*;
import com.oss.metadata.*;

public class Myproject extends ASN1Project {
     ...
}

Generated module class in the p/myproject/myprotocol subdirectory:

package p.myproject.myprotocol;

import com.oss.asn1.*;
import com.oss.metadata.*;
import p.myproject.*;

public abstract class MyProtocol extends ASN1Module {

    // Value references
    public static final com.oss.asn1.INTEGER bufferSize =
                          new com.oss.asn1.INTEGER(1024);
}

Classes generated for ASN.1 typereferences

The generated classes extend either a universal class or other generated class, as defined in the ASN.1 specification. Java classes that are generated for ASN.1 types use the name of their related ASN.1 type. In case of a name conflict, the ASN.1 compiler for Java changes the input type names.

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
  Person ::= SEQUENCE {
      name PrintableString,
      id   INTEGER
     }

  Female ::= Person
  Mother ::= Female
END
public class Person extends Sequence {
    ...
}

public class Female extends Person {
    ...
}

public class Mother extends Female {
     ...
}

Classes generated for ASN.1 type components

A top-level nested class is a Java class that represents a parent and the nested component relationship. Nested INTEGER with named numbers, ENUMERATED with named numbers, BIT STRING with named bits, SEQUENCE, SET, CHOICE, SEQUENCE OF and SET OF are generated as top-level nested classes when they are not explicitly defined as top-level types in the ASN.1 specification. The nested type is extracted from its parent type and has a top-level nested class name that converts it into a public Java class. Top-level nested class names are created for these types based on the component identifier with the first letter changed to uppercase or based on built-in type names for components with missing identifiers.

This strategy for handling nested types provides a granular, object-oriented API. The use of top-level nested classes provides a great deal of flexibility with respect to the construction and population of generated classes.

Example

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
  Person ::= SEQUENCE {
     address SET {},
     INTEGER {a(1), b(2)}
  }
END
public class Person extends Sequence {
    ...
    public static class Address extends Set {
        ...
    }
    public static class Integer extends INTEGER {
        ...
    }
}

The SET type of the address component is generated as a Java top-level nested class Address, becoming Person.Address. The INTEGER type with NamedNumbers of the unnamed component of the Person type is generated as a Java top-level nested class Integer, becoming Person.Integer.

NOTE: If you compile the above example with the -xer or -exer option, the compiler issues the following error:

A0832E: The SET, SEQUENCE or CHOICE value is impossible to represent in XML since one of the field identifiers is missing.

Member variables generated for ASN.1 Valuereferences

Value references defined in each module in an ASN.1 specification are generated by the OSS ASN.1 compiler for Java as member variables of the module's Java class. These variables are either Java primitives or objects that are initialized by the module class, and stored as public final members.

Example

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
     I ::= INTEGER
     myInt I ::= 23
     myBitStr BIT STRING ::= '1010101'B
END
public abstract class Mod extends ASN1Module {
    // Value references
    public static final I myInt = new I(23);
    public static final com.oss.asn1.BitString myBitStr =
                                      new com.oss.asn1.BitString (
        new byte[]
        {
             (byte)0xAA
        },
        7
    );
}

ASN.1 Protocol Data Units (PDUs)

A protocol data unit (PDU) is any ASN.1 type that is meant to be used in communication. The ASN.1 compiler for Java considers unreferenced types and types that are marked with the PDU directive to be PDUs.

Classes generated by the OSS ASN.1/Java compiler that represent ASN.1 PDUs may be encoded and decoded via coding services found in the OSS ASN.1/Java runtime.

Given the ASN.1 specification:

Example DEFINITIONS ::= BEGIN
   Person ::= SEQUENCE {
      name      PrintableString,
      address   SEQUENCE {
           street   PrintableString,
           city     PrintableString
      }
   }--<PDU>--

   Family ::= SEQUENCE OF Person
   Town   ::= SEQUENCE OF Family
END

Three ASN.1 types are defined:

  • Town is an unreferenced type, therefore it is considered a PDU by the compiler.
  • Family is referenced by Town, therefore it is not considered a PDU.
  • Person is referenced by Family, but has been marked with the PDU compiler directive, therefore it is considered a PDU.

ASN.1 Java Typereference Class Properties

Every ASN.1 Java typereference class is created by subclassing (extending) an ASN.1/Java runtime universal class or other typereference class. Universal classes inherit from the AbstractData class, therefore ASN.1 compilers for Java generated classes that represent ASN.1 types have a common ancestor: AbstractData.

For every ASN.1 Java typereference class, the compiler generates a default constructor (without arguments) and one or more constructors that are specific to the class.

For certain universal classes, the OSS ASN.1 compiler for Java generates two constructor and method parameter lists. In one of the lists, the parameters are represented by their universal class, and in the other, they are substituted by Java primitives. This improves the usability and performance of the ASN.1 Java API and runtime.

ASN.1 Java Universal Class Java Primitive
BOOLEAN boolean
INTEGER long
Real double

NOTE: Parameter substitution is not performed for user-defined types that extend the ASN.1 Java universal classes listed above. For example, the typereference VersionNumber will never be replaced by long in any method parameter lists, or as a method return type, thereby preserving the DefinedType defined in the ASN.1 specification:

VersionNumber ::= INTEGER

Example

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
   Person ::= SEQUENCE {
      id     INTEGER,
      status BOOLEAN,
      rate   REAL
   }
END
// Constructors

public Person(long id, boolean status, double rate)
public Person(INTEGER id, BOOLEAN status, REAL rate)

// Accessors

public long getId()
public boolean getStatus()
public double getRate()

// Mutators

public void setId(long id)
public void setStatus(boolean status)
public void setRate(double rate)

public void setId(INTEGER id)
public void setStatus(BOOLEAN status)
public void setRate(REAL rate)

Note that the compiler generates Java primitives instead of ASN.1 universal classes in the Person class. The order of the methods is not the actual order in the code.

Java constants generated for ASN.1 value references and for named items (INTEGER with NamedNumbers, BIT STRING with NamedBits, and ENUMERATED) have the same name as ASN.1 items from which they are derived.

Example

ASN.1 Java
realval REAL ::= {5, 10, 2}
public static final com.oss.asn1.Real realval =
new com.oss.asn1.Real(5.E2);

Names for local Java variables in Set, Sequence, and Choice classes are created based on the names of the identifiers.

Example

ASN.1 Java
S ::=  SEQUENCE {id INTEGER, status BOOLEAN }
public S(INTEGER id, BOOLEAN status)
{
    setId(id);
    setStatus(status);
}

Names for methods generated for each component of SET, SEQUENCE, and CHOICE types are created based on the names of the identifiers or, if an identifier is missing, on the ASN.1 type name of the component, converting the first letter to uppercase if necessary.

This example assumes that the component's identifier is id or that there was no identifier but that the type of the component is Id.

Accessor ("get" + Component_name):

public long getId() {...}

Mutator ("set" + Component_name):

public void setId(INTEGER id) {...}

Names

The ASN.1 compiler for Java performs checks to ensure output class and variable names conform to the Java naming rules and do not cause any Java name conflicts. If a conflict is detected, the compiler resolves it by changing the names (the process is called name mangling).

NOTE: Name mangling is performed only on types that constitute a working set (types that are PDUs or are referenced by PDUs). Informatory messages are issued if name mangling occurs.

Conflicts with Java reserved words

When assigning a project name, make sure it does not conflict with a Java reserved word, otherwise the ASN.1 compiler for Java issues an error.

Example

asn1pjav class.asn

"class.asn" (Class): C0538E: The Java project name class conflicts with a Java reserved word. Use the -output 
compiler option to change this name.

NOTE: Currently, no error is printed if a Java reserved name is assigned to be a project name as part of a package name that includes several nodes.

If an ASN.1/Java module name conflicts with a Java reserved word, an underscore is appended to the module class name and to the directory where the java file containing this class is created.

Example

ASN.1 Java
Long DEFINITIONS ::= BEGIN
A ::= INTEGER
END
public abstract class Long_ extends ASN1Module {

}

If an ASN.1/Java variable identifier conflicts with a Java reserved word, an underscore is prepended to the name. class is a Java reserved word, therefore it will be generated as _class in the value definition.

Example

ASN.1 Java
A ::= INTEGER { class(1) }
class A extends INTEGER {
     ...
     public static final A _class = new A(1);
     ...
}

Another example of a conflict between a variable identifier and a Java reserved word is when void is a Java reserved word, so it will be generated as _void in the definition of the Java class A.

Example

ASN.1 Java
void BOOLEAN ::= TRUE
// Value references
public static final com.oss.asn1.BOOLEAN _void =
     new com.oss.asn1.BOOLEAN(true);

Conflicts with java.lang

The classes in the java.lang package are implicitly imported into every Java class. If a class imports all the classes of a package with .*, the Java compiler filters out any user-defined classes that conflict with the class names in java.lang.

If a user-defined type in the ASN.1 notation that is generated as a Java class conflicts with one of the java.lang class names, use the fully qualified path name of the generated class to disambiguate the generated class name.

Example

ASN.1:

Mod DEFINITIONS ::= BEGIN
  Error    ::= INTEGER (1..32)
  Response ::= SEQUENCE {
      error Error
    }
END
Generated Error.java file Generated Response.java file
package test.mod;  // project name is "Test"

  public class Error extends INTEGER {
     ...
  }
package test.mod;

  public class Response extends Sequence {
  ...
  public Response(test.mod.Error error);
  ...
  }

Because Error conflicts with java.lang.Error, the reference to the user-defined class is fully qualified.

If an ASN.1/Java module name conflicts with a java.lang class name, an underscore is appended to the module class name and to the directory where the java file containing this class is created.

Example

ASN.1 Java
System DEFINITIONS ::= BEGIN
     S ::= IA5String
END
Emitted Java class in system_ subdirectory:

public abstract class System_ extends ASN1Module {
}

If an ASN.1 type name conflicts with a java.lang class name, an underscore is always appended. In this example, the ASN.1 type name is String.

Example

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
     String ::= PrintableString
END
public class String_ extends PrintableString {

    public String_() {...}
    public String_(String value) {...}
    public String_(char []value) {...}
    ...
}

Conflicts with OSS class names

If a project name conflicts with an OSS built-in class name, the ASN.1 compiler for Java does not issue an error, however Java compiling will fail. For example, no warning or errors are printed in the following case:

asn1pjav external.asn

When a generated class name (created for an ASN.1 module, type, or field) conflicts with a class name from an ASN.1/Java runtime package, the rule is to append an underscore to the generated class name.

Example

ASN.1:

ASN1Module DEFINITIONS ::= BEGIN
     Choice ::= SET { coder SET OF BOOLEAN }
END
Generated asn1module_.java in the asn1module_ directory Generated Choice_.java: in the asn1module_ directory
public abstract class ASN1Module_ extends ASN1Module {

}
        
public class Choice_ extends Set {
     ...

	public static class Coder_ extends SetOf {
    ...
	}
}

When module names, type names, or field names conflict with a predefined OSS built-in name:

  • An underscore is appended to the type class name.
  • Two underscores are appended to the module class name.
  • A number is appended to the field name.

Example

ASN.1 Generated names
AbstractData DEFINITIONS ::= BEGIN
AbstractData ::= SET {
  abstractData SEQUENCE { a BOOLEAN}
}
END
	abstractdata__	directory in the project package
	AbstractData__	module class
	AbstractData_	class for the SET type
	AbstractData1	inner class name for the nested SEQUENCE type

Conflicts between ASN.1 names

All previously described name conflicts are ASN.1 definitions that conflict with a Java name either used by the Java language or by the Java libraries provided for the encoder and decoder. The name conflicts listed in this section are strictly conflicts between ASN.1 definitions.

Conflicts with Project Names

The name of a static variable is mangled by appending an underscore if a project name conflicts with the name of a Java constant that is generated for the following:

  • A named bit specified in a BIT STRING with NamedBits.
  • A named number specified in an INTEGER with NamedNumbers.
  • An enumerator in an ENUMERATED type.

Example

ASN.1 Generated Java classes
Mod DEFINITIONS ::= BEGIN
    A ::= INTEGER {num(3)}
END
public class A extends INTEGER {
          ...

    // Named list definitions.
    public static final A num_ = new A(3)
    private final static A cNamedNumbers[] = { num_};
     ...
}

NOTE: To avoid Java compiling errors, you can use num.mod.A.num_ instead of num.mod.A.num (a fully qualified name).

Conflicts with module names

If two modules have names that differ only in case, such as ABC and Abc, an underscore with a sequence number is appended. The number is incremented by one until a unique name is found.

Example

ASN.1 Generated Java classes
--<ROOT>--
Spec DEFINITIONS ::= BEGIN
     D ::= BOOLEAN
END

SPEC DEFINITIONS ::= BEGIN
     A ::= REAL
END
myproj.spec_1.D
myproj.spec_2.A

NOTE: The numbers appended to module names are not necessarily in sequential order.

If modules contain ASN.1 types with the same names, then numbering includes those class names that are generated for such ASN.1 types.

Example

ASN.1 Java
--<ROOT>--

Abc DEFINITIONS AUTOMATIC TAGS  ::= BEGIN
     Abc ::= REAL
     AbC ::= BIT STRING
END

ABc DEFINITIONS AUTOMATIC TAGS  ::= BEGIN
     ABc ::= INTEGER
     ABC ::= BOOLEAN
END
myproj.abc_3.Abc_3 - class name for module Abc
myproj.abc_3.AbC_2 - class name for BIT STRING type AbC
myproj.abc_3.Abc_1 - class name for REAL type Abc

myproj.abc_6.ABc_6 - class name for module ABc
myproj.abc_6.ABC_5 - class name for BOOLEAN type ABC
myproj.abc_6.ABc_4 - class name for INTEGER type ABc

If an ASN.1 module name and a type name within a module are the same, in the generated Java code, the module name is in conflict with the type name. The rule is to append an underscore to the module name.

Example

ASN.1 Java
Abc DEFINITIONS ::= BEGIN
     Abc ::= INTEGER
END
spec.abc_	module package name
spec.abc_.Abc_	module class name
spec.abc_.Abc	typereference class name

If an ASN.1 module name conflicts with the name of a component and the ASN.1 type is a PDU, an underscore is appended to the module name.

Example

ASN.1:

Defn DEFINITIONS ::= BEGIN
     S ::= SEQUENCE {defn SEQUENCE OF INTEGER} --<PDU>--
END
Generated Defn_.java file Generated S.java file
public abstract class Defn_ extends ASN1Module {

}
public class S extends Sequence {
      ...

	public static class Defn extends SequenceOf {
      ...
	}
}

NOTE: If the Java class (that represents the module) and the nested inner class (that represents the component) had the same name, there would be Java compiling errors.

Conflicts with class names

If two ASN.1 types have names that differ only in case, such as ABC and Abc, an underscore with a sequence number is appended. The number is incremented by one until a unique name is found.

Example

ASN.1 Java
Spec DEFINITIONS ::= BEGIN
     Abc ::= INTEGER
     ABC ::= BOOLEAN
END
myproj.spec.Abc_1
myproj.spec.ABC_2

If an ASN.1 type conflicts with a component identifier, then a sequence number is appended to the name of the class that represents the component. This number is incremented by one until a unique name is found.

Example

ASN.1 Java
Mod DEFINITIONS ::= BEGIN
     Type ::= SEQUENCE {type SEQUENCE OF INTEGER}
END
public class Type extends Sequence {
      ...
	public static class Type1 extends SequenceOf {
      ...
	}
}

Conflicts with component names

If an ASN.1 type contains nested types, for example, SET, SEQUENCE, CHOICE, SEQUENCE OF, SET OF, BIT STRING with named bits, ENUMERATED, or INTEGER with named numbers, an identifier of the nested component will be used to create a Java nested top-level class name according to the following rules:

  • The first letter is changed to uppercase to create a nested class name.
  • If this name conflicts with the name of any of its enclosing classes (including enclosing nested class names), it is mangled with a sequence number appended.
  • The numbering is local to the enclosing top-level class. Changes to other types in the ASN.1 module do not affect the numbers used for this type.

Example

ASN.1

A ::= SEQUENCE {
     a  SEQUENCE {
          b  SEQUENCE {
               b  SEQUENCE {
                    a  SEQUENCE {
                    }
               }
          }
     }
}
Java class names Java classes
A
A.A1
A.A1.B
A.A1.B.B1
A.A1.B.B1.A2
public class A extends Sequence {
      ...
     public static class A1 extends Sequence {
           ...
          public static class B extends Sequence {
                ...
               public static class B1 extends Sequence {
                     ...
                    public static class A2 extends Sequence {
                          ...
                    }
               }
          }
     }
}

When components do not have identifiers, the following name mangling rules apply:

  • First level nested classes generated for unidentified ASN.1 components get the name derived from the appropriate built-in type of the component appended with an underscore.
  • Nested components that are derived from the same built-in type, get names appended with an underscore and a number.

Example

ASN.1 Java
S ::= SET OF SET OF SET OF SET OF SET OF INTEGER
public class S extends SetOf {
     ...
    public static class SetOf_ extends SetOf {
         ...
        public static class SetOf_1 extends SetOf {
             ...
            public static class SetOf_2 extends SetOf {
                 ...
                public static class SetOf_3 extends SetOf {
                     ...
                }
            }
        }
    }
}

When a component's identifier and a type referenced by the component have the same name (the case of the first letter of the name being irrelevant), the name of the referenced type is fully-qualified for all occurrences.

Example

Only pertinent parts of the code are shown:

ASN.1 Java
Module DEFINITIONS ::= BEGIN
 A ::= SEQUENCE { func SetFunction }
 B ::= SEQUENCE { setFunction  SET OF SetFunction }
 SetFunction ::= SET {} -- referenced type used in SET OF
END
public class A extends Sequence {
  ...

  public A(jt.module.SetFunction func){...}
  ...
}

public class B extends Sequence {
  ...
  public B(SetFunction setFunction){...}
  ...

 // Methods for field "setFunction"
 public SetFunction getSetFunction(){...}
   ...
 public static class SetFunction extends SetOf {

  public SetFunction() {...}
  ...

  public synchronized void add(jt.module.SetFunction element){...}

  public synchronized void set(jt.module.SetFunction element,
                                                 int atIndex){...}
 ...
 }
}

If an ASN.1 class has the same field names that differ only by the first letter, capital or lowercase, then both names are mangled by appending a number, thus avoiding conflicts in the names of generated methods.

Example

ASN.1 Java
COOKIE ::= CLASS {
     &Oatmeal,
     &oatmeal INTEGER
}
public class Cookie extends InfoObject {

    // Methods for field "Oatmeal_1"

    public ASN1Type getOatmeal_1(){...}
    public void setOatmeal_1(ASN1Type Oatmeal_1) {...}

    // Methods for field "oatmeal_2"

    public long getOatmeal_2(){...}
    public void setOatmeal_2(long oatmeal_2) {...}
    public void setOatmeal_2(INTEGER oatmeal_2) {...}
}

Parameterized Types

Parameterized types are present in the generated Java code only through their instances after actual parameter substitution.

Example

Mod DEFINITIONS ::= BEGIN
     DesiredType ::= INTEGER

     Record {TypeForSubstitution} ::= SET {
          myTypeVar TypeForSubstitution,
          filled BOOLEAN
     }

     MyRec ::= Record {DesiredType}
END

The Java class for MyRec is generated is the same way as for the following ASN.1 notation:

MyRec ::= SET {
     myTypeVar DesiredType,
     filled BOOLEAN
}

Parts of generated Java class:

public class MyRec extends Set {

    public MyRec() {...}
    public MyRec(DesiredType myTypeVar, boolean filled) {...}
    public MyRec(DesiredType myTypeVar, BOOLEAN filled) {...}

    // Methods for field "filled"
    public boolean getFilled(){...}
    public void setFilled(boolean filled) {...}
    public void setFilled(BOOLEAN filled) {...}

    // Methods for field "myTypeVar"
    public DesiredType getMyTypeVar(){...}
    public void setMyTypeVar(DesiredType myTypeVar) {...}

} // End class definition for MyRec

See Also

-paramTypeSuperClass | -noParamTypeSuperClass


Values

When a generated class is constructed with a value, a reference to the value (as opposed to a copy of the value) is kept. All changes made to the class value are immediately reflected in the calling value, and vice versa. The value passed can be a Java array or a Java object. Also, accessors usually return a reference to this object, and not a copy to it. The clone() method performs a true deep copy (no internal objects are shared between the original and the clone).


XML Values

The ASN.1 compiler can process ASN.1 value references defined using the XML value notation as stated in the ASN.1:2015 standard. This enables you to take advantage of the flexibility of XML in displaying ASN.1 values.

The Java representations for equivalent ASN.1 and XML value notations are identical. XML value notation can appear in the same input ASN.1 file as other ASN.1 components in your specification.

Example

The following notations are equivalent:

ASN.1 XML
AModule DEFINITIONS ::= BEGIN
StringType ::= UTF8String
IntType ::= INTEGER
studentName StringType ::= "John H. Doe"
studentAge IntType ::= 23
END
XModule DEFINITIONS ::= BEGIN
StringType ::= UTF8String
IntType ::= INTEGER
studentName ::= <StringType>John H. Doe</StringType>
studentAge ::= <IntType>23</IntType>
END

For a detailed explanation of the mapping rules from ASN.1 to XML and vice versa, refer to the ASN.1:2015 standards document.


Examples

ANY / ANY DEFINED BY

ANY and ANY DEFINED BY are represented by the com.oss.asn1.OpenType built-in universal class.

BIT STRING

BIT STRING is represented by the com.oss.asn1.BitString built-in class. The NamedBitList specification affects the contents of the classes generated by the OSS ASN.1 compiler for Java for ASN.1 BIT STRING types.

Default Representation

The default representation is generated in the absence of NamedBitList subtype specifications. Methods that are not defined in the class are automatically inherited from the BitString superclass.

ASN.1 Java
Bit ::=  BIT STRING
public class Bit extends BitString {
    public Bit(){...}
    public Bit(byte[] value){...}
    public Bit(byte[] value, int sigBits){...}
} // End class definition for Bit

BIT STRING with NamedBitList

For a NamedBitList, the default constructor reflects the constraints that are implied.

ASN.1 Java
Bit ::=  BIT STRING {a(10), b(20), c(50)}
public class Bit extends BitString {
    public Bit(){...}
    public Bit(byte[] value){...}
    public Bit(byte[] value, int sigBits){...}
    // Named list definitions.
    public static final int a = 10;
    public static final int b = 20;
    public static final int c = 50;
} // End class definition for Bit

BIT STRING with CONTAINING clause

For a CONTAINING clause, an inner class is additionally generated. The name of the inner class is ContainedType. The compiler generates an additional constructor.

ASN.1 Java
Bit ::= BIT STRING ( CONTAINING INTEGER {one(1)} )
     public class Bit extends ContainingBitString {
 
         ...
         public Bit(ContainedType decoded) { ... }
         ...
         public ContainedType getContainedValue() {
             return (ContainedType)getDecodedValue();
         }
 
         public void setContainedValue(ContainedType value) {
             setDecodedValue(value);
         }
 
         static public class ContainedType extends INTEGER {
             ...
         }
         ...

     }

To generalize, the compiler generates an additional constructor:

public ClassName(ContainedTypeName decodedValue) { ... };

and accessor and mutator methods for the decoded contained value:

       public ContainedTypeName getContainedValue() {
           return (ContainedTypeName)getDecodedValue();
       }
 
       public void setContainedValue(ContainedTypeName value) {
           setDecodedValue(value);
       }

ContainedTypeName is a class name that corresponds to a Type from the CONTAINING clause or AbstractData if there is no CONTAINING clause.

BOOLEAN

BOOLEAN is represented by the com.oss.asn1.BOOLEAN built-in class. There are no variations of the generated code for BOOLEAN types.

ASN.1 Java
A ::= [10] BOOLEAN
public class A extends BOOLEAN {
     public A(){...}
     public A(boolean value){...}
} // End class definition for A

Restricted CharacterStrings

The following ASN.1 string types are represented by a different com.oss.asn1 built-in class. Each is represented by a Java class (with the same name as its ASN.1 counterpart) that is a subclass of a Universal class.

  • BMPString
  • GeneralString
  • GraphicString
  • IA5String
  • NumericString
  • ObjectDescriptor
  • PrintableString
  • TeletexString
  • UniversalString
  • UTF8String
  • VideotexString
  • VisibleString

Default Representation

By default, the Java representation is the same for each of the restricted character string types, except for UniversalString, which has an extra constructor.

ASN.1 Java
B ::= BMPString
public class B extends BMPString {
    public B(){...}
    public B(String value){...}
    public B(char[] value){...}
} // End class definition for B

UniversalString

UniversalString is represented by the com.oss.asn1.UniversalString built-in class. This class differs from other Java string classes; one of the constructors takes an int[] as a parameter. There are no variations of the generated methods for UniversalString types.

ASN.1 Java
U ::= UniversalString
public class U extends UniversalString {
public U(){...}
public U(String value){...}
public U(char[] value){...}
public U(int[] value){...}
} // End class definition for U

CHOICE

Default Representation

Classes representing CHOICE types are derived from the Choice class. The following are generated for each CHOICE type:

  • A static final int value starting at 1 and incremented by 1 is generated for each alternate of a CHOICE type. The names of the values take the form:
    component-name + "_chosen".
  • A method is generated for each alternate of a CHOICE where the name of the method is:
    "create" + Class name + "With" + Component name.
  • A mutator with the name "set"+Component name where the first character of the component name is in uppercase. The single parameter to the mutator is the type of the component followed by a variable named component name.
  • An accessor that returns TRUE if the chosen component of a CHOICE is the one being queried. The name of the method is:
    "has"+Component name.
ASN.1 Java
ProductDesignator ::= CHOICE {
  departmentNo    INTEGER,
  description  [0] IMPLICIT VisibleString,
  inventoryNo  [1] IMPLICIT INTEGER
}
public class ProductDesignator extends Choice {

   public ProductDesignator(){...}

   public static final  int  departmentNo_chosen = 1;
   public static final  int  description_chosen = 2;
   public static final  int  inventoryNo_chosen = 3;

   // Methods for field "departmentNo"
   public static ProductDesignator 
     createProductDesignatorWithDepartmentNo (long departmentNo){...}
   public static ProductDesignator 
      createProductDesignatorWithDepartmentNo
                               (INTEGER departmentNo){...}
   public boolean hasDepartmentNo(){...}
   public INTEGER getDepartmentNo(){...}
   public void setDepartmentNo (long departmentNo){...} 
   public void setDepartmentNo (INTEGER departmentNo){...} 

   // Methods for field "description"
   public static ProductDesignator
     createProductDesignatorWithDescription 
                               (VisibleString description){...}
   public boolean hasDescription(){...}
   public VisibleString getDescription(){...} 
   public void setDescription  (VisibleString description){...} 

   // Methods for field "inventoryNo"
   public static ProductDesignator 
      createProductDesignatorWithInventoryNo (long inventoryNo){...}
   public static ProductDesignator 
     createProductDesignatorWithInventoryNo (INTEGER inventoryNo){...}
   public boolean hasInventoryNo(){...}
   public INTEGER getInventoryNo(){...} 
   public void setInventoryNo (long inventoryNo){...} 
   public void setInventoryNo (INTEGER inventoryNo){...}

} // End class definition for ProductDesignator

Extensible Choice

The extensible CHOICE generates all the methods described above. In addition, hasUnknownExtension() is generated by the compiler to check whether the current selection is an unknown extension.

ASN.1 Java
ProductDesignator ::= CHOICE {
  departmentNo    INTEGER,
  description   [0] IMPLICIT VisibleString,
  inventoryNo   [1] IMPLICIT INTEGER,
  ...
}
public class ProductDesignator extends Choice {

 public ProductDesignator(){…}

 public static final  int  departmentNo_chosen = 1;
 public static final  int  description_chosen = 2;
 public static final  int  inventoryNo_chosen = 3;

 // Methods for field "departmentNo"
 public static ProductDesignator 
  createProductDesignatorWithDepartmentNo (long departmentNo){...}
 public static ProductDesignator 
  createProductDesignatorWithDepartmentNo (INTEGER departmentNo){...}
 public boolean hasDepartmentNo(){...}
 public INTEGER getDepartmentNo(){...}
 public void setDepartmentNo (long departmentNo){...}
 public void setDepartmentNo (INTEGER departmentNo){...}

 // Methods for field "description"
 public static ProductDesignator 
  createProductDesignatorWithDescription 
                           (VisibleString description){...}
 public boolean hasDescription(){...}
 public VisibleString getDescription(){...}
 public void setDescription  (VisibleString description){...}

 // Methods for field "inventoryNo"
 public static ProductDesignator 
  createProductDesignatorWithInventoryNo (long inventoryNo){...}
 public static ProductDesignator 
 createProductDesignatorWithInventoryNo (INTEGER inventoryNo){...}
 public boolean hasInventoryNo(){...}
 public INTEGER getInventoryNo(){...}
 public void setInventoryNo (long inventoryNo){...}
 public void setInventoryNo (INTEGER inventoryNo){...}
 /**
   * Check the current selection on unknown extension
   */
 public boolean hasUnknownExtension() {...}

} // End class definition for ProductDesignator

DATE

DATE is represented by the com.oss.asn1.ISO8601Date built-in class. No directive or constraint specification affects the methods generated by the OSS ASN.1 compiler for Java for DATE types. Methods that are not defined in the generated class are automatically inherited from the ISO8601Date superclass.

ASN.1 Java
Date ::= DATE
public class Date extends ISO8601Date {
    public Date(){...}
    public Date(int year, int month, int day){...}
    public Date(String value){...}
} // End class definition for Date

DATE-TIME

DATE-TIME is represented by the com.oss.asn1.ISO8601DateTime built-in class. No directive or constraint specification affects the methods generated by the compiler for DATE-TIME types. Methods that are not defined in the generated class are automatically inherited from the ISO8601DateTIME superclass.

ASN.1 Java
DateTime ::= DATE-TIME
public class DateTime extends ISO8601DateTime {
    public DateTime(){...}
    public DateTime(int year, int month, int day, 
                    int hour, int minute, int second){...}
    public DateTime(String value){...}
} // End class definition for DateTime

DURATION

DURATION is represented by the com.oss.asn1.ISO8601Duration built-in class. No directive or constraint specification affects the methods generated by the compiler for DURATION types. Methods that are not defined in the generated class are automatically inherited from the ISO8601Duration superclass.

ASN.1 Java
Duration ::= DURATION
public class Duration extends ISO8601Duration {
    public Duration(){...}
    public Duration(int years, int months, int days,
                    int hours, int minutes, int seconds, 
                    Fractional_part fractional_part){...} 
    public Duration(int weeks, Fractional_part fractional_part){...}
    public Duration(String value){...}
} // End class definition for Duration

EMBEDDED PDV

EMBEDDED PDV is represented by the com.oss.asn1.EmbeddedPDV built-in class. No specifications affect the representation of the ASN.1 EMBEDDED PDV type.

ASN.1 Java
EPDV ::= EMBEDDED PDV
public class EPDV extends EmbeddedPDV {

     public EPDV() {...}
     public EPDV(EmbeddedPDV.Identification identification,
                 OctetString data_value){...}

} // End class definition for EPDV

ENUMERATED

The Enumerated class is an abstract class from which classes representing ENUMERATED types are derived. An extensible specification affects the contents of the classes generated by the OSS ASN.1 compiler for Java for ENUMERATED types.

Default Representation

ASN.1 Java
Sample DEFINITIONS ::= BEGIN
     A ::= [10] ENUMERATED {a(10), b(20), c(30)}
END
public class A extends Enumerated {
    private A(){...}
    ...
public static class Value {
  public static final long a = 10;
  public static final long b = 20;
  public static final long c = 20;
}

    /* Named list definitions. */
    public static final A a = new A(10);
    public static final A b = new A(20);
    public static final A c = new A(30);
    private final static Enumerated cNamedNumbers[] = {a, b, c};

    public Enumerated[] getNamedNumbers(){...}
    public boolean hasLinearNumbers(){...}
    public long getFirstNumber(){...}
    public A valueOf(long value) {...}
    ...
} // End class definition for A

The valueOf(long) method provides mapping from integers to class objects that represent individual enumerated values. For example:

Color ::= ENUMERATED { red(1), green(2), blue(3) }

The following assertions will be true for the Color class:

    Color.valueOf(Color.red.longValue()) == Color.red
    Color.valueOf(Color.green.longValue()) == Color.green
    Color.valueOf(Color.blue.longValue()) == Color.blue
    Color.valueOf(integers other than 1, 2 or 3) == null

Extensible Enumerated Representation

ASN.1 Java
Sample DEFINITIONS ::= BEGIN
     E ::= ENUMERATED {a(1), ..., b(2)}
END
public final class E extends Enumerated {

    private E(){...}

    // Named list definitions.
    public static final E a = new E(1);
    public static final E b = new E(2);

    public Enumerated[] getNamedNumbers(){...}
    public boolean hasLinearNumbers(){...}
    public long getFirstNumber(){...}
    public E valueOf(long value) {...}

    /**
     * Methods for "unknownEnumerator"
     */
    public boolean isUnknownEnumerator(){...}
    public Enumerated getUnknownEnumerator(){...}

} // End class definition for E

Enumerated Values in Switch/Case Statements

Enumerated values can be used in switch/case statements as follows, assuming that myDecodedValue is an instance of class A:

switch (myDecodedValue.longValue()) {
    case A.Value.one:
    ...
    case A.Value.two:
    ...
    case A.Value.three:
    ...
    default:
       // Handle unknown enumerations of extensible
       // enumerated types
}

EXTERNAL

EXTERNAL is represented by the com.oss.asn1.EXTERNAL built-in class. No specifications affect the representation of the EXTERNAL type.

ASN.1 Java
MyExternal    ::= EXTERNAL
public class MyExternal extends External {
    public MyExternal(){...}
    public MyExternal(ObjectIdentifier direct_reference,
                      INTEGER indirect_reference,ObjectDescriptor
                      data_value_descriptor,
                      External.Encoding encoding){...}
    public MyExternal(ObjectIdentifier direct_reference,
                      long indirect_reference,
                      ObjectDescriptor data_value_descriptor, 
                      External.Encoding encoding){...}
    public MyExternal(External.Encoding encoding){...} 
                                        // required components
} // End class definition for MyExternal

GeneralizedTime

GeneralizedTime is represented by the com.oss.asn1.GeneralizedTime built-in class. No directive or constraint specification affects the methods generated by the OSS ASN.1 compiler for Java for GeneralizedTime types. Methods that are not defined in the generated class are automatically inherited from the GeneralizedTime superclass.

ASN.1 Java
Generaltime ::= GeneralizedTime
public class Generaltime extends GeneralizedTime {
    public Generaltime(){...}
    public Generaltime(int year, int month, int day,
                    int hour, int minute, int second, int minDiff,
                    int millisecond, boolean isUTCTime){...}
    public Generaltime(int[] components, boolean isUTCTime){...}
    public Generaltime(String value){...}
} // End class definition for Generaltime

Information Object Classes and Information Object Sets

Information object sets and component relation constraints are used in ASN.1 specifications to determine the type of an open type value from another message field. For example:

PARAMETER ::= CLASS {
    &id ParameterID UNIQUE,
    &Type
}

KNOWN-PARAMETERS PARAMETER ::= {
    {&id 1, &Type INTEGER} |
    {&id 2, &Type UTF8String},
    ...
}

Procedure ::= SEQUENCE { 
    opcode INTEGER,
    parameter SEQUENCE {
	parameterId PARAMETER.&id ({KNOWN-PARAMETERS}),
	value PARAMETER.&Type ({KNOWN-PARAMETERS}{@parameterId})
    }
}

With the definition of Procedure, once you receive the Procedure message you can determine the type of the value (of the field with the identifier named value) by searching the KNOWN-PARAMETERS information object set for the information object with the &id equal to the value of the field with the field parameterId in the Procedure message. For example, if the parameterId field is equal to 2, value is of type UTF8String.

The runtime performs automatic decoding with the help of component relation constraints; it detects which field of the message identifies the type of the open type (the value field), and then it searches the information object set to determine the type of the value.

By default, the runtime searches the information object set for the information object with the &id equal to parameterId using linear lookup. You can change this default behavior to a faster lookup method by indexing the information object set. For more information on indexing, see the -indexInfoObjectSets subsection.

For all information object sets defined in the ASN.1 file, the ASN.1 Java compiler generates the following:

  • A subclass of the InfoObject class
  • A subclass of the InfoObjectSet class named <ClassName>_OSET
  • Associated member variables

The member variables are generated in the module class that represents the ASN.1 module in which the info object sets were defined. The member variables have the same names as the original names of info object sets with the first letter lowercase.

Note that when multiple InfoObjectSets reference the InfoObject class, only one subclass of the InfoObject class is generated.

The generated classes are used by the runtime to perform the searching described above. Unless you change the default behavior, there is nothing your application will need to do with this generated information.

Example

ASN.1 Java
ERROR-CLASS ::= CLASS {
       &category       PrintableString,
       &Type
}
WITH SYNTAX {&category &Type}

ErrorSet ERROR-CLASS ::= {
       {"A" INTEGER}
}
public class ERROR_CLASS extends InfoObject {

    public ERROR_CLASS() {...}
    public ERROR_CLASS(PrintableString category, ASN1Type Type,
                       INTEGER _oss_unique_index) {...}
    public ERROR_CLASS(PrintableString category, ASN1Type Type,
                       long _oss_unique_index) {...}
    public void initComponents(){...}

    // Methods for field "category"
    public PrintableString getCategory(){...}
    public void setCategory(PrintableString category) {...}

    // Methods for field "Type"
    public ASN1Type getType(){...}
    public void setType(ASN1Type Type) {...}

    // Methods for field "_oss_unique_index"
    public long get_oss_unique_index(){...}
    public void set_oss_unique_index(long _oss_unique_index) {...}
    public void set_oss_unique_index(INTEGER _oss_unique_index) {...}
     …
}

public class ERROR_CLASS_OSET extends InfoObjectSet {

    public ERROR_CLASS_OSET(){...}
    public ERROR_CLASS_OSET(ERROR_CLASS[] objects, int flags,
                       String modname, String osetname) {...}
     ...
}

public abstract class Module extends ASN1Module {

    // Information object sets
    public static ERROR_CLASS_OSET errorSet = new ERROR_CLASS_OSET (
         new ERROR_CLASS[] {
              new ERROR_CLASS (
                    new com.oss.asn1.PrintableString (
                    "A"
             ),
            new com.oss.asn1.ASN1Type (
                  "com.oss.asn1",
                  "INTEGER"
            ),
           new com.oss.asn1.INTEGER(1)
       )
       },
         0,
         "Module",
         "ErrorSet"
         );

}

INTEGER

INTEGER is represented by the com.oss.asn1.INTEGER, HugeInteger, and UNSIGNED built-in classes, depending on constraint specifications and the absence or presence of the HUGE directive. The NamedBitList specifications also affect the contents of the methods generated by the OSS ASN.1 compiler for Java for INTEGER types.

Default Representation

The default representation is generated in the absence of constraint specifications, NamedBitList specifications, or the HUGE directive. The methods not defined in the class are automatically inherited from the INTEGER superclass.

ASN.1 Java
Int ::=  INTEGER
public class Int extends INTEGER {
    public Int(){...}
    public Int(short value){...}
    public Int(int value){...}
    public Int(long value){...}
} // End class definition for Int

INTEGER with NamedNumberList

For a named number list, definitions representing the values of each named number are generated in the Java class that represents the type. Additionally, the class contains an inner public static class Value that includes a public static final long constant for each named number. This feature is useful when named numbers are present in the Java switch statement.

ASN.1 Java
Int ::= [21] INTEGER {a(10), b(20), c(30)}
public class Int extends INTEGER {

    public Int(){...}
    public Int(short value){...}
    public Int(int value){...}
    public Int(long value){...}

    public static final class Value {
       public static final long a = 10;
       public static final long b = 20;
       public static final long c = 30;
     }

    // Named list definitions.
    public static final Int a = new Int(10);
    public static final Int b = new Int(20);
    public static final Int c = new Int(30);

    public INTEGER[] getNamedNumbers(){...}
    public boolean hasLinearNumbers(){...}
    public long getFirstNumber(){...}

} // End class definition for Int

Using the HUGE directive

An ASN.1 Integer with the HUGE directive is represented by the com.oss.asn1.HugeInteger built-in class.

ASN.1 Java
Int ::=  INTEGER --
<HUGE>--
public class Int extends HugeInteger {
    public Int(){...}
    public Int(java.math.BigInteger value){...}
} // End class definition for Int

Huge bounds with SOED

If an ASN.1 INTEGER's constraint bounds fall outside the value-range of Java long and is compiled for the SOED runtime (using the -soed command-line option or by default), then the HUGE directive is implied, and the com.oss.asn1.HugeInteger representation is automatically selected.

ASN.1 Java
Int ::=  INTEGER (-18446744073709551615..18446744073709551615)
public class Int extends HugeInteger {
    public Int(){...}
    public Int(java.math.BigInteger value){...}
} // End class definition for Int

Huge bounds with TOED

If an ASN.1 INTEGER's constraint bounds fall outside the value-range of Java long and is compiled for the TOED runtime (using the -toed command-line option), then the HUGE directive is implied, if negative values are possible. The com.oss.asn1.HugeInteger representation is selected in that case. If the type is constrained to have non-negative values, then it can be represented by an unsigned 64-bit integer and the com.oss.asn1.UNSIGNED representation is used.

ASN.1 Java
Int ::=  INTEGER (0..18446744073709551615)
public class Int extends UNSIGNED {
    public Int(){...}
    public Int(short value){...}
    public Int(int value){...}
    public Int(long value){...}
} // End class definition for Int

INSTANCE OF

INSTANCE OF is represented by a Java class that extends the com.oss.asn1.InstanceOf class. The com.oss.asn1.InstanceOf class contains methods that are inherited by the generated Java class. No specifications affect the representation of the INSTANCE OF type. TYPE-IDENTIFIER is required to be the definition of the type within INSTANCE OF.

ASN.1:

Module DEFINITIONS ::= BEGIN
     MHS-BODY  ::=  TYPE-IDENTIFIER
     InstanceOfMHS  ::= INSTANCE OF MHS-BODY
END

The TYPE-IDENTIFIER information object class is predefined in ASN.1 as:

TYPE-IDENTIFIER ::= CLASS
     {
      &id OBJECT IDENTIFIER UNIQUE,
      &Type
      }

InstanceOfMHS has the following associated SEQUENCE type with the UNIVERSAL tag 8:

InstanceOfMHS ::= SEQUENCE{
             type-id        MHS-BODY.&id,
             value      [0] MHS-BODY.&Type
}

The SEQUENCE type has two fields:

  • The type id field, which is an OBJECT IDENTIFIER type.
  • The value field, which is an open type.

Java representation:

public class InstanceOfMHS extends InstanceOf {

    public InstanceOfMHS(){...}
    public InstanceOfMHS(ObjectIdentifier type_id, 
                         OpenType value){...}

} // End class definition for InstanceOfMHS

NULL

NULL is represented by the com.oss.asn1.NULL built-in class. There is no representation other than the default representation.

ASN.1 Java
N ::= [10] NULL
public class N extends Null {
public N(){...}
} // End class definition for N

OBJECT IDENTIFIER

OBJECT IDENTIFIER is represented by the com.oss.asn1.ObjectIdentifier built-in class. No directives affect the default representation.

ASN.1 Java
Sample DEFINITIONS ::= BEGIN
    DefaultOID ::= OBJECT IDENTIFIER
END
public class DefaultOID extends ObjectIdentifier {

    public DefaultOID(){...}
    public DefaultOID(String value) throws
                                BadObjectIdentifierException {...}
    public DefaultOID(byte[] value){...}

} // End class definition for DefaultOID

OID-IRI

OID-IRI is represented by the com.oss.asn1.ObjectIdentifierIri built-in class. No directives affect the default representation.

ASN.1 Java
Sample DEFINITIONS ::= BEGIN
    DefaultOID-IRI ::= OID-IRI
END
public class DefaultOID_IRI extends ObjectIdentifierIRI {

    public DefaultOID_IRI(){…}
    public DefaultOID_IRI(String value) 
    public DefaultOID_IRI(char[] value){…}

} // End class definition for DefaultOID_IRI

OCTET STRING

OCTET STRING is represented by the com.oss.asn1.OctetString built-in class. There is no representation other than the default representation. No directives affect the Java representation. Methods that are not defined in the class are automatically inherited from the OctetString superclass.

Default Representation

ASN.1 Java
Sample DEFINITIONS ::= BEGIN
     C ::= [10] OCTET STRING
END
public class C extends OctetString {
   public C(){...}
   public C(byte[] value){...}
} // End class definition for C

OCTET STRING with CONTAINING clause

For a CONTAINING clause, an inner class is additionally generated. The name of the inner class is ContainedType. The compiler generates an additional constructor.

ASN.1 Java
Octet ::= OCTET STRING ( CONTAINING INTEGER {one(1)} )
  public class Octet extends ContainingOctetString {
 
      ...
      public Octet (ContainedType decoded) { ... }
      ...
      public ContainedType getContainedValue() {
          return (ContainedType)getDecodedValue();
      }
 
      public void setContainedValue(ContainedType value) {
          setDecodedValue(value);
      }
 
      public static class ContainedType extends INTEGER {
          ...
      }
      ...

  }

To generalize, the compiler generates an additional constructor:

public ClassName(ContainedTypeName decodedValue) { ... };

Also, accessor and mutator methods for the decoded contained value are generated:

       public ContainedTypeName getContainedValue() {
           return (ContainedTypeName)getDecodedValue();
       }
 
       public void setContainedValue(ContainedTypeName value) {
           setDecodedValue(value);
       }

ContainedTypeName is a class name that corresponds to a Type from the CONTAINING clause, or AbstractData if there is no CONTAINING clause.

NOTE: OpenType is particularly useful for embedding a separately encoded ASN.1 type within other ASN.1 types.

OpenType Notation

Open types in ASN.1:2015 are the equivalent of ANY and ANY DEFINED BY in ASN.1:1990. By default, an open type is represented by the com.oss.asn1.OpenType class or extends the OpenType class. The --<ASN1.ValueInFile>-- directive causes an open type to be represented by the com.oss.asn1.HugeOpenType class or a class that extends the HugeOpenType class. If an open type is constrained by a component relation constraint then the -helperAPI opentype command-line option instructs the compiler to represent the type with a class that defines extra methods to access the open type value using type-safe methods. Methods that are not defined in the class are automatically inherited from the superclass.

ASN.1 Java
Module DEFINITIONS ::= BEGIN
     Open ::= TYPE-IDENTIFIER.&Type
END
public class Open extends OpenType {
    public Open(){...}
    public Open(byte[] encodedValue){...}
    public Open(AbstractData pdu, com.oss.asn1.Coder coder)
                  throws EncodeNotSupportedException, 
                         EncodeFailedException {...}
    public Open(AbstractData pdu) {...}

} // End class definition for Open

TYPE-IDENTIFIER is defined as:

TYPE-IDENTIFIER ::= CLASS
{
           &id   OBJECT IDENTIFIER UNIQUE,
           &Type
}

Constrained open type helper API

The -helperAPI opentype command-line option affects the representation of open type fields that are constrained by a component relation constraint.

By default, an open type field is generated to reference an instance of the com.oss.asn1.OpenType class.

Example

Mod DEFINITIONS ::= BEGIN

    I TYPE-IDENTIFIER ::= {
       a | b | c
    }

    a TYPE-IDENTIFIER ::= { INTEGER   IDENTIFIED BY {1 2 3 4} }
    b TYPE-IDENTIFIER ::= { BOOLEAN   IDENTIFIED BY {1 2 3 5} }
    c TYPE-IDENTIFIER ::= { IA5String IDENTIFIED BY {1 2 3 6} }

    S ::= SEQUENCE {
            id       TYPE-IDENTIFIER.&id ({I}),
            value    TYPE-IDENTIFIER.&Type ({I}{@id})
    }

END

In the above example, SEQUENCE S has two fields: the id field, which contains an OBJECT IDENTIFIER value, and value, which is an open type field. A component relation constraint links the id field with the value field, so the id field is used to identify the value field type.

By default, the value field of SEQUENCE S is represented by the OpenType class.

// Methods for field "value"
public OpenType getValue()
public void setValue(OpenType value)

To handle the open type value, determine the value's type, which is identified by the id field value. The -helperAPI opentype option is especially useful when you need to find a matching id value when there are numerous type alternatives or complex identifier fields, (e.g., CHOICE identifier fields).

When the -helperAPI opentype option is specified and an open type field is constrained by a component relation constraint, the compiler generates an additional inner class that represents the field's type. The name of the inner class is derived from the name of the field and is located within the class that represents the parent constructed type.

The getter and setter methods of the SEQUENCE S value field class will change as follows:

// Methods for field "value"
public Value getValue()
public void setValue(Value value)
public static class Value extends ConstrainedOpenType {
...
}

The additional Value class that is generated differs from the default open type representation as follows:

  1. The additional class contains an inner Java enum class that enumerates all type alternatives of the open type field and an _unknown type alternative. The name of the enum class is derived from the constraining information object set. For example:
    public enum _i {
        INTEGER,
        BOOLEAN,
        IA5String,
        _unknown
    }
  2. The additional class defines the getter method for the type identifier field:
    public _i getTypeID();
  3. For each type alternative (designated as TypeAlternative below) the additional class defines three CHOICE-like methods:
    public boolean hasTypeAlternative();
    public TypeAlternative getTypeAlternative();
    public void setTypeAlternative(TypeAlternative decoded);
    For example, the S.Value class has the following methods:
    public boolean hasINTEGER();
    public INTEGER getINTEGER();
    public void setINTEGER(INTEGER decoded);
    
    public boolean hasBOOLEAN();
    public BOOLEAN getBOOLEAN();
    public void setBOOLEAN(BOOLEAN decoded);
    
    public boolean hasIA5String();
    public IA5String getIA5String();
    public void setIA5String(IA5String decoded);

The open type helper API provides the following benefits to an application developer:

  1. All type alternatives of a constrained open type are present in the constrained open type class definition. You don't need to consult ASN.1 specifications or other class definitions to find possible type alternatives. When used within an IDE, the additional class definition provides useful hints for code completion.
  2. Code readability is improved: type alternatives are accessed with specific methods and type casts are eliminated.
  3. The Java "switch" statement can be used to process type alternatives.

Version Information

The -helperAPI opentype option is available in version 7.0 and later.

REAL

REAL is represented by the com.oss.asn1.REAL built-in class.

Default Representation

When no directives are applied, the superclass of the generated class is com.oss.asn1.Real.

ASN.1 Java
R ::= [10] REAL
public class R extends Real {

    public R(){...}
    public R(float value){  ...}
    public R(double value){  ...}
} // End class definition for R

Using the DECIMAL Directive

When the DECIMAL directive or the ASN1.RealRepresentation with the decimal argument is applied, the DecimalReal class (and not the default superclass Real) becomes the superclass of the generated class. The difference between the two classes is the internal representation of the Real number.

ASN.1 Java
DR ::= [10] REAL --<DECIMAL>--
public class DR extends DecimalReal {

    public DR() { }
    public DR(String value) {...}
    public DR(double value) {...}
    public DR(float value) {...}

} // End class definition for DR

Using the MIXED Directive

When the MIXED directive or the ASN1.RealRepresentation with the mixed argument is applied, the MixedReal class (and not the default superclass Real) becomes the superclass of the generated class.

ASN.1 Java
MR ::= [10] REAL --<MIXED>--
public class MR extends MixedReal {

    public MR() { }
    public MR(float value) {...}
    public MR(double value) {...}
    public MR(String value) {...}

} // End class definition for MR

RELATIVE-OID

RELATIVE-OID is represented by the com.oss.asn1.RelativeObjectIdentifier built-in class. No directives affect the default representation.

ASN.1 Java
DefaultOID   ::= RELATIVE-OID
public class DefaultOID extends RelativeObjectIdentifier {

    public DefaultOID(){...}
    public DefaultOID(String value) throws
                               BadObjectIdentifierException {...}
    public DefaultOID(byte[] value){...}

} // End class definition for DefaultOID

RELATIVE-OID-IRI

RELATIVE-OID-IRI is represented by the com.oss.asn1.RelativeObjectIdentifierIri built-in class. No directives affect the default representation.

ASN.1 Java
DefaultRelOIDIRI   ::= RELATIVE-OID-IRI
public class DefaultRelOIDIRI extends RelativeObjectIdentifierIri {

    public DefaultRelOIDIRI (){...}
    public DefaultRelOIDIRI (String value) 
    public DefaultRelOIDIRI (char[] value){...}

} // End class definition for DefaultRelOIDIRI

SEQUENCE

Classes representing the SEQUENCE type are derived from the SEQUENCE class. The following ASN.1 specifications affect the contents of the classes generated by the OSS ASN.1 compiler for Java for SEQUENCE types:

  • DEFAULT keyword
  • OPTIONAL keyword
  • COMPONENTS OF notation

Default Representation

The default representation is generated in the absence of ASN.1 keywords (listed above). Methods not defined in the class are automatically inherited from the Sequence superclass. For each element, the following methods are generated:

  • A mutator with the name "set"+Component name, where the first character of the component name is uppercase. The single parameter to the mutator is the type of the component followed by a variable named component name.
  • An accessor is generated for each element where the name of the method is "get"+Component name and the first character of component name is uppercase.

The following example contains an element without an identifier. The compiler generates a name to represent that element.

ASN.1 Java
NamesOfOfficers ::= SEQUENCE {
   president      VisibleString (SIZE(1..32)),
   vicePresident  VisibleString (SIZE(1..32)),
   secretary      VisibleString (SIZE(1..32)),
                  VisibleString (SIZE(1..32))
}
public class NamesOfOfficers extends Sequence {

    public NamesOfOfficers(){...}
    public NamesOfOfficers(VisibleString president,
                           VisibleString vicePresident,
                           VisibleString secretary,
                           VisibleString visibleString){...}

    // Methods for field "president"
    public VisibleString getPresident(){...}
    public void setPresident(VisibleString president){...}

    // Methods for field "vicePresident"
    public VisibleString getVicePresident(){...}
    public void setVicePresident(VisibleString vicePresident){...}

    // Methods for field "secretary"
    public VisibleString getSecretary(){...}
    public void setSecretary(VisibleString secretary){...}

    // Methods for field "visibleString"
    public VisibleString getVisibleString(){...}
    public void setVisibleString(VisibleString visibleString){...}
} // End class definition for NamesOfOfficers

Effect of OPTIONAL and DEFAULT within the SEQUENCE type

For each OPTIONAL element, the following methods are generated:

  • A mutator with the name "delete"+Component name, where the first character of component name is uppercase.
  • An accessor that returns TRUE if the component has a value. The name of the method is "has"+Component name.

For each element with a DEFAULT value, the following method is generated:

  • An accessor that returns TRUE if the component has been defined with a DEFAULT value. The name of the method is "hasDefault"+Component name.
  • A mutator that sets the component value to the default value. The name of the method is "set"+Component-name+"ToDefault"

Currently no information about default values is present in the generated classes.

ASN.1 Java
NamesOfOfficers2 ::= SEQUENCE {
   president          VisibleString (SIZE(1..32)) OPTIONAL,
   vicePresident [1]  VisibleString (SIZE(1..32)),
   treasurer     [2]  VisibleString DEFAULT "",
   secretary          VisibleString (SIZE(1..32)) OPTIONAL
}
public class NamesOfOfficers2 extends Sequence {

 public NamesOfOfficers2(){...}
 public NamesOfOfficers2(VisibleString president,
                         VisibleString vicePresident,
                         VisibleString treasurer,
                         VisibleString secretary){...}
 public NamesOfOfficers2(VisibleString vicePresident){...}

 // Methods for field "president"
 public VisibleString getPresident(){...}
 public void          setPresident(VisibleString president){...}
 public boolean       hasPresident(){...}
 public void          deletePresident(){...}

 // Methods for field "vicePresident"
 public VisibleString getVicePresident(){...}
 public void          setVicePresident(VisibleString 
                                             vicePresident){...}

 // Methods for field "treasurer"
 public VisibleString getTreasurer(){…}
 public void          setTreasurer(VisibleString treasurer){...}
 public void          setTreasurerToDefault() {...}
 public boolean       hasDefaultTreasurer(){...}
 public boolean       hasTreasurer(){...}
 public void          deleteTreasurer(){...}

 // Methods for field "secretary"
 public VisibleString getSecretary(){...}
 public void          setSecretary(VisibleString secretary){...}
 public boolean       hasSecretary(){...}
 public void          deleteSecretary(){...}
} // End class definition for NamesOfOfficers2

Effect of COMPONENTS OF notation within SET/SEQUENCE type

When the COMPONENTS OF notation is used in a SEQUENCE or a SET, the elements of the referenced SEQUENCE or SET are copied inline unless COMPONENTS OF a particular type occurs in several SEQUENCE or SET types or unless the type to which COMPONENTS OF is applied is marked as a PDU.

The first example shows the elements of the COMPONENTS OF SEQUENCE copied inline.

ASN.1 Java
NamesOfOfficers3 ::= SEQUENCE {
   president       VisibleString,
   vicePresident   PrintableString,
   COMPONENTS OF MoreOfficers
}

MoreOfficers ::= [1] SEQUENCE {
   secretary     IA5String,
                 NumericString
}
public class NamesOfOfficers3 extends Sequence {

  public NamesOfOfficers3(){...}
  public NamesOfOfficers3(VisibleString president,
                          PrintableString vicePresident,
                          IA5String secretary,
                          NumericString numericString){...}

  // Methods for field "president"
  public VisibleString   getPresident(){...}
  public void            setPresident(VisibleString president){...}

  // Methods for field "vicePresident"
  public PrintableString getVicePresident(){...}
  public void setVicePresident(PrintableString vicePresident){...}

  // Methods for field "secretary"
  public IA5String       getSecretary(){...}
  public void            setSecretary(IA5String secretary){...}

  // Methods for field "numericString"
  public NumericString   getNumericString(){...}
  public void            setNumericString(NumericString numericString){...}
} // End class definition for NamesOfOfficers3

The second example shows the COMPONENTS OF SEQUENCE represented as a nested static class so that the COMPONENTS OF are shared from each place of reference.

ASN.1 Java
Mod DEFINITIONS  ::= BEGIN
   Trainers ::= SEQUENCE {count INTEGER, COMPONENTS OF Pokemon}
   Energy ::=   SEQUENCE {COMPONENTS OF Pokemon }
   Pokemon ::=  SEQUENCE {which SET OF BOOLEAN}
END
public class Trainers extends Sequence {

    public Trainers(){...}
    public Trainers(INTEGER count, Which which){...}
    public Trainers(long count, Which which){...}

    // Methods for field "count"
    public long getCount(){...}
    public void setCount(long count){...}
    public void setCount(INTEGER count){...}

    // Methods for field "which"
    public Which getWhich(){...}
    public void  setWhich (Which which){...}

    public static class Which extends SetOf {

        public Which(){...}
        public Which(BOOLEAN[] elements){...}
        public void synchronized add(BOOLEAN element){...}
        public void synchronized set(
                                 BOOLEAN element, int atIndex){...}
        public synchronized BOOLEAN get(int atIndex){...}
        public synchronized void insert(
                                 BOOLEAN element, int atIndex){...}
        public synchronized void remove(BOOLEAN element){...}
    } // End class definition for Pokemon
} // End class definition for Trainers

public class Energy extends Sequence {

    public Energy(){...}
    public Energy(Trainers.Which which){...}

    // Methods for field "which"
    public Trainers.Which getWhich(){...}
    public void setWhich(Trainers.Which which){...}
} // End class definition for Energy

NOTE: The inner class Which is generated only once in the Trainers class. Energy contains qualified names for types from Trainers.Which. If the type Pokemon is explicitly marked as a PDU, the inner class Which is generated in the class Pokemon. Classes Trainers and Energy contains qualified names to reference types from Which.

Representation of SEQUENCE components in SOED vs. TOED

When compiled for SOED, the components' storage is allocated in an instance variable of the Sequence superclass. When compiled for TOED, components are represented by public instance variables of the compiler-generated class. With SOED, the components are accessible only via getter and setter methods. With TOED, it is also possible to access the components directly, which avoids method calls and provides faster component access. Note, however, that using getter/setter methods is a compatible way to access components with both SOED and TOED.

The examples in the previous sections follow the SOED-style: there are no instance variables for components in the generated class. Below is an example of TOED-style code.

ASN.1 Java
NamesOfOfficers ::= SEQUENCE {
   president      VisibleString (SIZE(1..32)),
   vicePresident  VisibleString (SIZE(1..32)),
   secretary      VisibleString (SIZE(1..32)),
                  VisibleString (SIZE(1..32))
}
public class NamesOfOfficers extends Sequence {
    public VisibleString president;
    public VisibleString vicePresident;
    public VisibleString secretary;
    public VisibleString visibleString;

    public NamesOfOfficers(){...}
    public NamesOfOfficers(VisibleString president,
                           VisibleString vicePresident,
                           VisibleString secretary,
                           VisibleString visibleString){...}

    // Methods for field "president"
    public VisibleString getPresident(){...}
    public void setPresident(VisibleString president){...}

    // Methods for field "vicePresident"
    public VisibleString getVicePresident(){...}
    public void setVicePresident(VisibleString vicePresident){...}

    // Methods for field "secretary"
    public VisibleString getSecretary(){...}
    public void setSecretary(VisibleString secretary){...}

    // Methods for field "visibleString"
    public VisibleString getVisibleString(){...}
    public void setVisibleString(VisibleString visibleString){...}
} // End class definition for NamesOfOfficers

SEQUENCE OF

Classes representing SEQUENCE OF types are derived from the SequenceOf class. No specifications affect the contents of the methods generated by the OSS ASN.1 compiler for Java for SEQUENCE OF types. The generated code includes the following methods: add, set, get, insert, and remove. These methods are synchronized. There are other methods that are not generated because they are inherited from a superclass, such as AbstractContainer.

ASN.1 Java
SeqOfInt   ::= SEQUENCE OF INTEGER
public class SeqOfInt extends SequenceOf {

    public SeqOfInt(){...}
    public SeqOfInt(INTEGER[] elements){...}
    public synchronized void add(INTEGER element){...}
    public synchronized void set(INTEGER element, int atIndex){...}
    public synchronized INTEGER get(int atIndex){...}
    public synchronized void insert(INTEGER element, int atIndex){...}
    public synchronized void remove(INTEGER element){...}
} // End class definition for SeqOfInt

Effect of field identifier on SET OF/SEQUENCE OF type

When a field identifier is present in a SEQUENCE OF or a SET OF, the elements of the referenced SEQUENCE or SET can use that field identifier. This is useful when you use the XML encoding rules (XER) or extended XML encoding rules (E-XER).

The following example shows myInt as the field identifier. The generated Java code is the same whether or not a field identifier is present.

A ::= SET OF myInt INTEGER

a A ::= { myInt 123, myInt 123 }

Representation of SEQUENCE OF components in SOED vs. TOED

When compiled for SOED, the components' storage is allocated in an instance variable of the SequenceOf superclass. When compiled for TOED, the components are represented by the public instance variable elements of the java.util.ArrayList type of the compiler-generated class. With SOED, the components are accessible only via getter and setter methods. With TOED, it is also possible to access the components directly using call methods of the elements variable, which provides faster component access. It should be noted, however, that using getter/setter methods is a compatible way to access components with both SOED and TOED.

Below is an example of a TOED-style class for SEQUENCE-OF.

ASN.1 Java
SeqOfInt   ::= SEQUENCE OF INTEGER
public class SeqOfInt extends SequenceOf {
    public java.util.ArrayList
    <INTEGER> elements;

    public SeqOfInt(){...}
    public SeqOfInt(INTEGER[] elements){...}
    public synchronized void add(INTEGER element){...}
    public synchronized void set(INTEGER element, int atIndex){...}
    public synchronized INTEGER get(int atIndex){...}
    public synchronized void insert(INTEGER element, int atIndex){...}
    public synchronized void remove(INTEGER element){...}
} // End class definition for SeqOfInt

SET

SET generates code similar to the SEQUENCE type. The difference is that the generated Java class extends com.oss.asn1.Set.

SET OF

SET OF generates code similar to the SEQUENCE OF type. The difference is that the generated Java class extends com.oss.asn1.SetOf.

TIME

TIME is represented by the com.oss.asn1.ISO8601String built-in class. No directive or constraint specifications affect the methods generated by the OSS ASN.1 compiler for Java for TIME types. Methods that are not defined in the generated class are automatically inherited from the ISO8601String superclass.

ASN.1 Java
Time ::= TIME
public class Time extends ISO8601String {
    public Time(){...}
    public Time(String value){...}
    public Time(Char[] value){...}
} // End class definition for Time

TIME-OF-DAY

TIME-OF-DAY is represented by the com.oss.asn1.ISO8601TimeOfDay built-in class. No directive or constraint specifications affect the methods generated by the OSS ASN.1 compiler for Java for TIME-OF-DAY types. Methods that are not defined in the generated class are automatically inherited from the ISO8601TimeOfDay superclass.

ASN.1 Java
TimeOfDay ::= TIME-OF-DAY
public class TimeOfDay extends ISO8601TimeOfDay {
    public TimeOfDay(){...}
    public TimeOfDay(int hour, int minute, int second){...}
    public TimeOfDay(String value){...}
} // End class definition for TimeOfDay

UTCTime

UTCTime is represented by the com.oss.asn1.UTCTime built-in class. No directive or constraint specifications affect the methods generated by the OSS ASN.1 compiler for Java for UTCTime types. Methods that are not defined in the class are automatically inherited from the UTCTime superclass.

Unlike the GeneralizedTime class, the UTCTime class does not have a millisecond value nor a boolean flag called isUTCTime. These are only needed in GeneralizedTime's constructors.

NOTE: The year in UTCTime is two-digit. GeneralizedTime should be used for all dates that require a four-digit year setting.

ASN.1 Java
Ttime ::= UTCTime
public class Ttime extends UTCTime {

    public Ttime(){...}
    public Ttime(int year, int month, int day, int hour, int minute,
                 int second, int minDiff){...}
    public Ttime(int[] components){...}
    public Ttime(String value) throws
                               com.oss.util.BadTimeFormatException {...}
} // End class definition for Utime

UTF8String

UTF8String is represented by the com.oss.asn1.UTF8String, com.oss.asn1.UTF8String16, and com.oss.asn1.UTF8String32 built-in classes. The default representation, com.oss.asn1.UTF8String16 class, is generated in the absence of directives for the UTF8String type or if the BMPSTRING directive is used. Below is a table showing which classes are generated when the UNBOUNDED, BMPSTRING, or UNIVERSALSTRING directives are applied to the UTF8String type.

UTF8String UTF8String --<UNBOUNDED>--
UTF8String16 UTF8String --<BMPSTRING>--
UTF8String32 UTF8String --<UNIVERSALSTRING>--

Default Representation

The default representation is generated in the absence of ASN.1 keywords (listed above).

ASN.1 Java
UT ::= UTF8String
public class UT extends UTF8String16 {

    public UT() { }
    public UT(String value) {...}
    public UT (char[] value) {...}
} // End class definition for UT

Using the UNBOUNDED Directive

The UTF8String type with the UNBOUNDED directive is represented by the com.oss.asn1.UTF8String built-in class.

ASN.1 Java
UnB ::= UTF8String --<UNBOUNDED>--
public class UnB extends UTF8String {

    public UnB() { }
    public UnB (String value) {...}
    public UnB (char[] value) {...}

} // End class definition for UnB

Using the BMPSTRING Directive

The UTF8String type with the BMPSTRING directive is represented by the com.oss.asn1.UTF8String16 built-in class.

Using the UNIVERSALSTRING Directive

The UTF8String type with the UNIVERSALSTRING directive is represented by the com.oss.asn1.UTF8String32 built-in class. This class differs from other Java string classes (including the other UTF8String classes) in that one of the constructors takes an int[] as a parameter).

ASN.1 Java
UniB ::= UTF8String --<UNIVERSALSTRING>--
public class UniB extends UTF8String32 {

    public UniB() { }
    public UniB (String value) {...}
    public UniB (char[] value) {...}
    public UniB (int[] value) {...}

} // End class definition for UniB

Unrestricted CharacterStrings

CHARACTER STRING

The CHARACTER STRING type is represented by the com.oss.asn1.UnrestrCharacterString built-in class. No specifications affect the representation of the CHARACTER STRING type.

ASN.1 Java
Characterstring ::= CHARACTER  STRING
public class Characterstring extends UnrestrCharacterString {

public Characterstring() { }

public Characterstring(EmbeddedPDV.Identification identification,
                       OctetString string_value) {...}

} // End class definition for Characterstring

See Also

SOED versus TOED


This documentation applies to the OSS® ASN.1 Tools for Java release 7.1 and later.

Copyright © 2017 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for Java is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for Java are available to you.