Components:
Selector

Selector

Product line architectures (PLAs) are used to describe a family of closely related products. A PLA describes a set of common core components as well as the variation points across the specific product architectures. The variation points modeled by xADL 2.0 are optional elements and variant types (in the Options and Variants schemas).

Optional elements may or may not be included in the selected product architecture and a variant type will always be included, but may take on different alternative forms for different product architectures. Optionality is specified by a boolean guard (if the guard condition is met, the element is included) and variants are specified by mutually exclusive boolean guards (the variant whose guard condition is met is selected).

The selector component is able to automatically select a product architecture (or a smaller PLA) from a PLA based on user specified constraints. These constraints are simply name-value pairs in a symbol table.

The selector will remove any optional element whose guard conditions are not met, or remove the optional tag (which includes the guard) if its conditions are met (thus making it mandantory).

For example, an optional component before selection might look like this. Here is Comp2 shown with its optional field which contains the boolean guard: x @[0, 50] || y > 0 (Note: x@[0, 50] is the notation for in range, i.e. 0 <= x <= 50).

That same component in abbreviated non-XML notation looks like this:

component{
  (attr) id = "Comp2"

  //Description and other properties elided for
  //simplicity

  optional{
    guard{
      booleanExp{
        or{

          booleanExp1{
            inRange{
              symbol = x
              value = 0
              value = 50
            }
          }

          booleanExp2{
            greaterThan{
              symbol = y
              value = 0
            }
          }
        }
      }
    }
  }

  (xlink) type = "#Type_1"
}

If the guard condition is met, its optional field is removed. So for our example if in the symbol table we define x = 10 (regardless of what y is deinfed as), after selection the optional component will look like this:


And now, that same component in abbreviated non-XML notation will look like this:

component{
  (attr) id = "Comp2"
  (xlink) type = "#Type_1"
}

Please note that optional field has been removed; this component is now part of the architecture. However, if the guard were evaluated to false, the component would be removed from the architecture. If parts of the guard could not be evaluated, the boolean expression will be simplified as much as possible. And the new boolean guard will only be the conditions that were not specified.

The selector will also select the appropriate variant type. Each variant type contains a number of variants, each one with its own guard condition and a type. The guard conditions for the set of variants in a variant type are assumed to be mutually exclusive. The selector evaluates the guard condition for each variant. If a guard condition evaluated to 'false,' the variant is removed from the type. If one of the guards evaluates to 'true,' all elements (components, connectors, etc.) of the variant type will have their types changed to that of the the selected variant. If guards could not be fully evaluated, those guards will be pared down with available information and no types of elements (components, connectors) will be changed.

Here is a variant component type (Type_1) with two variants (two possible types: 1.1 and 1.2):



Which would translate to the following in abbreviated non-XML notation:

componentType{
  (attr) id = "Type_1"

  variant{
    guard{
      booleanExp{
        equals{
          symbol = language
          value = "English"
        }
      }
    }
    (xlink) variantType = "#Type_1.1"
  }

  variant{
    guard{
      booleanExp{
        equals{
          symbol = language
          value = "Spanish"
        }
      }
    }
    (xlink) variantType = "#Type_1.2"
  }
}

The first variant has the guard language == "English" and the second variant has the guard language == "Spanish". If we perform selection based on a symbol table with the entry language = "English", variant Type_1 will then look like this:



Translated to abbreviated non-XML notation, this is:

componentType{
  (attr) id = "Type_1"

  variant{
    guard{
      booleanExp{
        bool = true
      }
    }
    (xlink) variantType = "#Type_1.1"
  }
}

Note that the variant pointing to Type_1.2 is removed because its guard evaluated to false, but the Type_1.2 remains in the document. Also, the guard for variant representing Type_1.1 has been reduced to a single boolean expression containing the boolean value 'true'. As noted above, the selection algorithm will also go through all the components that were originally of component type Type_1 and update them so that those components will now be of type Type_1.1.

Note that the algorithm will report an error if all of the guards for the variants (of a single variant component type) evaluate to false or if more than one guard evaluates to true.

The selector requires the Boolean Eval component to evaluate the boolean guards used in optional and variant elements. Please see the options and variants schema in xADL 2.0 for a list of optional and variant elements that are supported by the selector.


The selector component is an asynchronous component and communicates through the following messages:

To invoke the selection service, the requesting component must send the PerformArchSelectorMessage.

PerformArchSelectorMessage

public PerformArchSelectorMessage(String archURL,
               String targetArchURL, String componentID,
               SymbolTable table, String startingID,
               boolean isStructural)

Parameters:
archURL - This is the url of the xADL architecture to be selected.
targetArchURL - This is the url of the resulting selected architecture.
componentID - This is ID of the component requesting the selection service. This ID is the same as the ID in the progress message corresponding to this selection process. This is to allow the requesting component to only listen in on the progress messages it cares about. This field can be null.
symTable - This is the table that contains all the variables and their values (user constraints) that the evaluation process is based on.
startingID - This is the ID of the ArchStructure or type-version element where we should start the selection process.
isStructural - This flag is true if the ID passed in corresponds to an ArchStructure element, false if its a type-version element .

The symbol table can be created from a file with the following format: The file must be in ASCII. Comments can be represented by // just as in C++ or Java. The basic layout of the file is as follows:

Variable = value
Variable = value
etc.

There can be leading and trailing spaces that will be stripped away. The value of the variable is represented by strings as specified here. Some examples:

/* Set the value of alarm variable to the date Jan 1st 2003 */
alarm    = #1/1/03#
/* Set the value of speed variable to the number 23.1 */
speed    = 23.1
/* Sets the value of language variable to the string 'English' */
language = "English"

Then, to invoke the selector:


/* In a C2Component*/
// Imports
import archstudio.comp.selectordriver.FileParser;

...

// First create the symbol table from file
FileParser parser = new FileParser( );
SymbolTable myTable = parser.createTable( "myTable.txt" );

// Then create the message
// This invokes the selection on the architecture at archURL,
// with the starting point specified by startingID, which
// refers to an arch structure element
PerformArchSelectorMessage selectMessage =
    new PerformArchSelectorMessage(archURL, targetURL, id,
    myTable, startingID, true);

// Sends the request upwards
sendToAll(selectMessage, topIface);

During the selection process, the selector will continuously send out messages to inform other components of its progress:

ArchSelectorStatusMessage

public ArchSelectorStatusMessage(String selectedArchURL,
   String componentID, int currentValue, int upperBound ,boolean isDone,
   boolean errorOccurred, Exception error)

Parameters:
selectedArchURL - This is the URL of the new (resulting) architecture.
componentID - This is the ID of the component who requested the selection service. This field may be null
currentValue - This is the numerical representation of the current progress.
upperBound - This is total expected work that is required.
isDone - This is a flag to signal whether or not the selection process has completed. Note: this will be true in the case of errors.
errorOccurred - This flag to signal whether or not an error has occurred.
error - This is the actual exception that occurred, please refer to the list below.
Exceptions:
InvalidURLException - This exception is thrown when the string passed in for the architecture is not an architecture that is already opened.
MissingElementException - This exception is thrown when the selector cannot find a required element in the architecture description.
NoSuchTypeException - This exception is thrown when it encounters an unknown/invalid type when evaluating.
TypeMismatchException - This exception is thrown when the type of the operands do not match during an evaluation.
VariantEvaluationException - This exception is thrown when a variant type has an improper (too many or no) variants that evaluated to true.
BrokenLinkException - This exception is thrown when a HREF resolves to null.


Additional questions about the Selector should be sent to Ping H. Chen.