## JSDAI Introduction

# Example Read Application

Assume we have an AP203-p21 file like this:

> `ISO-10303-21;`
> `HEADER;`
> `... // AP 203 example`
> `ENDSEC;`
> `DATA;`
> `...`
> `#1104=MECHANICAL_CONTEXT('CONFIGURATION MANAGEMENT',#1102,'mechanical',`
> `('aic_mech_dsgn_ctxt',`
> `'product identification and relation for the definition of mechanical`
> `product within the design phase of the product life cycle'));`
> `#1106=PRODUCT('2865000-1','REAR PANEL','REAR PANEL FOR BOX',(#1104));`
> `#1107=PRODUCT_RELATED_PRODUCT_CATEGORY('detail','DETAIL PART',(#1106));`
> `#1109=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('-',`
> `'INITIAL RELEASE',#1106,.MADE.);`
> `...`
> `ENDSEC;`
> `END-ISO-10303-21;`

The task is to find all products and list the attributes id, name and description, list all the discipline_types the product belongs to and the available versions. For each version specify the source, make or buy, if available.

## Step by Step

### SDAI-Session

The example application is completly within the main() method with opening and closing the SDAI-session. SdaiExceptions are thrown, so that all errors in the SDAI are reported at the standard output.

> `public static final void main(String argv[]) throws SdaiException {`

> > `SdaiSession session = SdaiSession.openSession();`
> > `...`
> > `session.closeSession();`

> `}`

### SDAI-Transaction

Before we can do any manipulation it is needed to start a read/Write transaction. At the end of this example we abort the transaction so that nothing of our actions is stored persistently.

> `SdaiTransaction transaction = seesion.startTransactionReadWriteAccess();`
> `...`
> `transaction.endTransactionAccessAbort();`

Please note that the transaction mechansim works only on the contents of repositories, but it not on creation and deletion of repositories.

### SDAI-Repository

Having opened the session and started a transaction we can access SDAI-repositories. In this case we want to import a p21 file which is specified on the command-line into a new repository. Alternatively we can open already exisiting and known repository or find one, e.g. on a network.

ImportClearTextEncoding creates a new repository and returns it. The repository is already opened and includes 1 or several SdaiModels in ReadWrite access mode.

When the repository is no longer needed we end and abort the transaction so that the contents of the model and repository are not made persistent. Then we close the repository which also ends the read/write (or read-only) access to it's models. Finally deleteRepository removes the repository as a persistent data storage.

> `SdaiRepository repo = session.importClearTextEncoding(null, argv[0], null);`
> `...`
> `repo.closeRepository();`
> `repo.deleteRepository();`

### Aggregates and Iterator

The next step is to find the SDAI-model inside the repository. The repository method getModels() returns an Aggregate, containing all the models of the repository. Aggregates are grouping objects in SDAI with a specific behaviour which is different from the usual Java grouping objects like the Java array or some of the container classes (e.g. Vector). Aggregates are used to represent the EXPRESS types bag, list, set and array. In this case the Aggregate is the specific sub-type of "ASdaiModel", it contains only SdaiModels. The prefix "A" indicate that it is an aggregate of "SdaiModel".

To scan through the members of an Aggregate the SdaiIterator object is used. SdaiIterators are created on an aggregate on which they should work. In the case that an aggregate represents an EXPRESS list or array the members of an aggregate can also be accessed by an index.

In the following code the first (and only one) SdaiModel is found and it's name is printed.

> `ASdaiModel models = repo.getModels();`
> `SdaiIterator it_models = models.createIterator();`
> `if (it_models.next()) {`

> > `SdaiModel model = models.getCurrentMember(it_models);`
> > `System.out.println("Model <" + model.getName() + "> found");`
> > `...`

> `} else {`

> > `System.out.println("error: No SdaiModel found");`

> `}`

### SDAI-Model

The SDAI-model is the basic container of entity-instances. Every entity-instance is contained in exactly one SDAI-model. Before we can access any entity-instances of the model, we have to open the model in READ-ONLY (or READ-WRITE) mode and close the mode when we have done.

> `model.startReadOnlyAccess();`
> `...`
> `model.endReadOnlyAccess();`

### Entity-Instance

There are several ways to find the desired entity-instance within an SDAI-model. First we have to decide in which way we want to work with Entity-instances, either early-binding or late-binding based method. In early-binding operations the name of an entity-attribute is part of the access method. In late binding however the attribute is specified as an additional method parameter. In this example we are using the early-binding approach because we know exactly the entities and attributes we are interested. Furthermore eraly binding enables the Java-compiler to do many consistency checks which are not possible with early binding.

With getInstances() we get all instances of a specific type or subtype. In this example we are interested in all instances of entity type product. There are three Java-class respectivly interfaces representing Product, all having a different prefix.

- The prefix "C" is used for the Java-Classes, impementing the EXPRESS-entities. The Java-class object can simply be found by accessing the ".class" data field.
- The prefix "E" is used to represent the Java-Interfaces, representing the EXPRESS-entiies. Java interfaces support multiple inheritance which is needed to work with EXPRESS. However Java-classes support only single inheritance. Because of this an application will access an entity-instance always with its "E"-interface. So an instance may be exactly of the specified type or of a subtype or a complex instance containing this specified type. This is not possible with the "C"-classes.
- last but not least for every entity-type there is also a corresponding aggregate with the "A" prefix.

To get all instances of a for a specify entity data type and subtypes we use `getInstances()` and pass the Entity class as parameter: `EProduct.class`.
A product aggregate `AProduct` is returned, containing all products (and subtypes) within the model. We iterate through all product instances and write out their persistend label.

> `AProduct products = (AProduct) model.getEntityExtentInstances(CProduct.class);`
> `SdaiIterator it_products = products.createIterator();`
> `while (it_products.next()) {`

> > `EProduct product = products.getCurrentMember(it_products);`
> > `System.out.println("");`
> > `System.out.println("INSTANCE: " + product.getPersistentLabel());`

> `}`

### Explicit Attributes

The entity-type product has the string attributes id, name and description. The forth attribute frame_of_reference is an aggregate of entity-type product_context to specify the discipline types the product belongs to.

Entity attributes are never accessed direcly. Instead there are access methods to get, set, create and unset the attributes. The method names are constructed by one of the prefixes "get", "set", "create" or "unset" followed by the name of the attribute. All entity-attributes can be accessed with get and unset. The create operation is only available for attributes of an aggregate type, while the set method is only available for non-aggregate types.

In EXPRESS it can happen, that an entity which is a supertype of several other entities inherit different attributes with the same name. In the case that these attributes are originally inherited from a common super-supertype it is the same attribute. But otherwise they are different attribute what we call a name-conflict. This situation really happens e.g. within AP203. To solve this problem each attribute-access method has at it's first position a parameter to specify the super-type where the attribute is originally defined. In almost all cases it is sufficent to pass the null-value to this parameter. But when null is used in the case of name-conflicts the Java-Compiler will generate errors indication that he cannot decide which one of several overladed methods to use. Then the user will cast the null to a specific type, e.g. "(EProduct) null".

Below we print out the string attributes id, name and description of entity product. Then we iterate through the product_context aggregate, specified by the attribute frame_of_reference and print out the name and discipline_type of every context found.

> `System.out.print("id: " + product.getId(null));`
> `System.out.print(", name: " + product.getName(null));`
> `System.out.println(", description: " + product.getDescription(null));`
> `// List the discipline types the product belongs to`
> `AProduct_context pc_set = product.getFrame_of_reference(null);`
> `System.out.println("\tframe_of_reference - SET of " + pc_set.getMemberCount() + ":");`
> `SdaiIterator it_pc = pc_set.createIterator();`
> `while (it_pc.next()) {`

> > `EProduct_context pc = pc_set.getCurrentMember(it_pc);`
> > `System.out.print("\tname: " + pc.getName(null));`
> > `System.out.println(", discipline_type: " + pc.getDiscipline_type(null));`

> `}`

### Inverse Relations

Relations between entity-instances are in general bi-directional, but they are only specified in one direction by an explicit attributes. To access an attribute in the reverse direction SDAI offers several possibilities.

- If also an inverse attribute is specified, this can be accessed like an explicit attribute (get and test only). The user may add himself missing inverse attributes if needed, but this would result into non-compatible schemas.
- Getting all the entities where the attributes are specified from the SDAI-model(s) and scanning through them, testing whether they are accessing the instance under test or not. This is slow and cannot be optimized by an implementation.
- Use of the query operation, but this only avaiable in higher implementation classes.
- Using the find entity instance usedin operation.

Here we will show how to use an early binding find entity instance usedin operation or shorter only usedin. Let us look to the four parameters of this function:
As with all the attribute access methods the first parameter is here to solve possible name conflicts.
The second parameter specifies the entity-instance onto which references from other entities are searched for.
The third parameter specified the domain, where to look for referencing entities. It is of type Aggregate of SdaiModel. In the case that this parameter is null this function searched only in the SdaiModel, the entity-instance belongs to.
The last parameter is a predefined Aggregate to hold the result.

> `AProduct_definition_formation formations = new AProduct_definition_formation();`
> `CProduct_definition_formation.usedinOf_product(null, product, null, formations);`
> `// List all product_definition_formations of the product`
> `SdaiIterator iter_formations = formations.createIterator();`
> `while (iter_formations.next()) {`

> > `EProduct_definition_formation formation = formations.getCurrentMember(iter_formations);`
> > `System.out.println("product user: product_definition_formation instance " + formation.getPersistentLabel());`
> > `System.out.print("\tID: " + formation.getId(null));`
> > `System.out.print(", description: " + formation.getDescription(null));`

> `}`

### Subtypes

The entity product_definition_formation has a subtype product_definition_formation_with_specified_source which contains additional information about the source of this product-version: make or buy. To check whether or not the actual instance formation is of the right type we use the isKindOf() method. If yes we can use casting to access the same instance as a product_definition_formation_with_specified_source and access its attribute make_or_buy.

> `// mention the specified_source if available`
> `if (formation.isKindOf(CProduct_definition_formation_with_specified_source.class)) {`

> > `EProduct_definition_formation_with_specified_source fwss =`
> > `(EProduct_definition_formation_with_specified_source) formation;`
> > `System.out.println(", make_or_buy: " + fwss.getMake_or_buy(null));`

> `} else {`

> > `System.out.println(", no specified_source available");`

> `}`

## Complete Example

We use the following font and color schem:

- Java kewyords
- Objects from package java.lang
- Comments
- "Strings"
- JSDAI session keywords and late binding
- JSDAI early binding

// Example10.java
// Copyright (c) LKSoft
// Inc. All Rights Reserved.
//
// This software is provided "AS IS," without a warranty of any kind.

// Simple SDAI application program.
// Reads an ap203 physical file,
// prints instances of product entity, finds and prints their users
// product_definition_formation_with_specified_source entity instances

import jsdai.lang.*;
import jsdai.SConfig_control_design.*;
import jsdai.SProduct_definition_schema.*;
import jsdai.SApplication_context_schema.*;

public class Example10 {
public static final void main(String argv[]) throws SdaiException {

> // first open a session and specify the desired AP
> SdaiSession session = SdaiSession.openSession();

> // start a read/write transaction to allow importClearTextEncoding
> SdaiTransaction transaction = session.startTransactionReadWriteAccess();

> // import a physical file into a new repository
> SdaiRepository repo = session.importClearTextEncoding(null, argv[0], null);

> // SdaiRepository is already open after importClearTextEncoding
> // repo.openRepository();

> // find the only one SdaiModel in it (data_section)
> ASdaiModel models = repo.getModels();
> SdaiIterator it_models = models.createIterator();
> if (it_models.next()) {

> > SdaiModel model = models.getCurrentMember(it_models);

> > // SdaiModel is already in read/write access after importClearTextEncoding
> > // model.startReadOnlyAccess();

> > System.out.println("Model <" + model.getName() + "> found");

> > // find all instances of entity type "product"
> > AProduct products = (AProduct) model.getInstances(EProduct.class);

> > // List all products(id, name, description)
> > System.out.println("");
> > System.out.println("Instances of entity \"product\": ");
> > SdaiIterator it_products = products.createIterator();
> > while (it_products.next()) {

> > > EProduct product = products.getCurrentMember(it_products);
> > > System.out.println("");
> > > System.out.println("INSTANCE: " + product.getPersistentLabel());
> > > System.out.print("id: " + product.getId(null));
> > > System.out.print(", name: " + product.getName(null));
> > > System.out.println(", description: " + product.getDescription(null));

> > > // List the discipline types the product belongs to
> > > AProduct_context pc_set = product.getFrame_of_reference(null);
> > > System.out.println("\tframe_of_reference - SET of " + pc_set.getMemberCount() + ":");
> > > SdaiIterator it_pc = pc_set.createIterator();
> > > while (it_pc.next()) {

> > > > EProduct_context pc = pc_set.getCurrentMember(it_pc);
> > > > System.out.print("\tname: " + pc.getName(null));
> > > > System.out.println(", discipline_type: " + pc.getDiscipline_type(null));

> > > }
> > > // follow the implicit inverse relation "of_product" to get
> > > // all product_definition_formations of the product
> > > AProduct_definition_formation formations = new AProduct_definition_formation();
> > > CProduct_definition_formation.usedinOf_product(null, product, null, formations);

> > > // List all product_definition_formations of the product
> > > SdaiIterator iter_formations = formations.createIterator();
> > > while (iter_formations.next()) {

> > > > EProduct_definition_formation formation = (EProduct_definition_formation)formations.getCurrentMember(iter_formations);
> > > > System.out.println("product user: product_definition_formation instance " + formation.getPersistentLabel());
> > > > System.out.print("\tID: " + formation.getId(null));
> > > > System.out.print(", description: " + formation.getDescription(null));

> > > > // mention the specified_source if available
> > > > if (formation.isKindOf(CProduct_definition_formation_with_specified_source.class)) {

> > > > > EProduct_definition_formation_with_specified_source fwss = (EProduct_definition_formation_with_specified_source) formation;
> > > > > System.out.println(", make_or_buy: " + fwss.getMake_or_buy(null));

> > > > } else {

> > > > > System.out.println(", no specified_source available");

> > > > }

> > > }

> > }
> > // read/write access or read-only access to SdaiModel is ended with closeRepository()
> > // model.endReadWriteAccess();
> > // model.endReadOnlyAccess();

> } else {

> > System.out.println("error: No SdaiModel found");

> }
> transaction.endTransactionAccessCommit();
> repo.closeRepository();
> repo.deleteRepository();

> System.out.println();
> System.out.println("Done");
> session.closeSession();

}
}

## Running the program

> `C:\LKSoft\tutorial>javac Example10.java`

> `C:\LKSoft\tutorial>java Example10 ap203w.pf`

> `Model <model1> found`

> `Instances of entity "product":`

> `INSTANCE: #1106`
> `id: 2865000-1, name: REAR PANEL, description: REAR PANEL FOR BOX`
> `frame_of_reference - SET of 1:`
> `name: CONFIGURATION MANAGEMENT, discipline_type: mechanical`
> `...`

Download Example10.java

Copyright 1998-2000, LKSoftWare GmbH