Xvcl And Samelevel
CjOS Project @ cjos.sourceforge.net
Index
Bind Pages
Cjos Library
Cjos Pages
Cjos News Pages
Eric Pages
Introduction To Smart Api
Osgi Pages
Registry Api Pages
Smart Api Pages
Xvcl Pages
CjOS Project
Summary Page
Mailing List
Download
CVS
JOS Technical Edition
Support This Project
Xvcl Pages; [ Cjos Audience]

Summary

How does the XVCL Processor implement the samelevel specification?

Specification

The samelevel attribute is part of an adapt command.

  • When "yes", variables defined by the adapted x-frame are available to the adapting frame.
  • When "no" (default), variables defined by the adapted x-frame go out of scope. They are invisible to the adapting frame.

Local variables

Normally, variables set by a frame are read-write. The set command can be used multiple times within a frame to change the value of a variable.

  • Note: A variable is read-only when it is in-use by a while command.

Variable set by an adapting frame

Normally, variables set by an adapting frame are read-only. When a variable is set in an adapting frame, the set command has no effect; variables cannot be modified. An adapted frame cannot reassign a value of a variable set by an adapting frame.

This is implemented in version 2.07:

 if(var==null||var!=null && isLocalVariable(name)){
 :
 }

Exception: samelevel

When samelevel="yes", an adapted frame itself has no variable table. Variables are set in the adapting frame.

sameLevel property

This property is part of the Frame class.

 /**
  * Checks whether this frame is adapted as samelevel.
  * @return true if adapted as samelevel.
  */
 public boolean isSameLevel(){
   if(adaptingNode!=null){
     return ((Adapt)adaptingNode).isSamelevel();
   }
   else{
     return false;
   }
 }

Inside Frame.parseAttributes()

 //first of all: if this frame is adapted with samelevel,
 //not creat variable table
 if(!this.isSamelevel()){
   super.createVariableTable();
   addVariablesToFrame();
 }

Adapt.samelevel

The samelevel field is part of the Adapt class.

 private boolean samelevel;

The samelevel field is initialized in the parseAttributes() method.

   samelevel=false;

Within the emit() method,

 //has SAMELEVEL attribute
 Attribute samelevelAtt=this.getAttribute(this.getAttributeExternalName("Adapt_samelevel"));
 String samelevelValue=null;
 if(samelevelAtt!=null){
   samelevelValue=samelevelAtt.getValue().trim().toLowerCase();
   if(!samelevelValue.equals("yes")&&!samelevelValue.equals("no")){
     throw new XVCLException("Invalid value for samelevel - "+samelevelValue, this, XVCLException.FATAL_ERROR);
   }
   if(samelevelValue.equals("yes")){
     this.samelevel=true;
   }
 }

The isSameLevel() method is part of the Adapt class.

 /**
  * Determines whether adapting with samelevel attribute.
  * @return true if adapting with samelevel.
  */
 public boolean isSamelevel(){
   return samelevel;
 }

Reference


Proposal

Allow an adapted frame to hide internal variables.

  1. Add a default-samelevel attribute to the x-frame command.
  • When "yes" (default), the set and set-multi commands provide current behavior.
  • When "no", the set and set-multi commands hide a variable from the adapting frame, unless samelevel is explicitly "yes".

  1. Add a samelevel attribute to the set command.
  • When "yes", the set command provides current behavior.
  • When "no", the set command hides a variable from the adapting frame.
  • The default value for samelevel is determined by the default-samelevel attribute of an x-frame.

  1. Add a samelevel attribute to the set-multi command.
  • When "yes" (default), the set-multi command provides current behavior.
  • When "no", the set-multi command hides a variable from the adapting frame.
  • The default value for samelevel is determined by the default-samelevel attribute of an x-frame.

The ref variable cannot be used by the adapting frame.

 <set var="ref" value="?@item?.name" samelevel="no"/>

The product.name variable is used by the adapting frame.

 <set var="product.name" value="?@@ref?"/>

private HashMap variableMap; private HashMap samelevelMap;

When samelevel="no", variableMap is not null, samelevelMap is not null. When samelevel="yes", variableMap is null and samelevelMap is not null.

When samelevel="yes", a variable is stored in variableMap. Otherwise, it is stored in samelevelMap.


Scenario

Let's say that we have frames A, B and C. A adapts B, B adapts C. When A adapts B, we specify samelevel="yes". But, when B adapts C, samelevel is "no".

 <x-frame name="A.xvcl">
 <set var="n" value="a"/>
 <adapt x-frame="B" samelevel="yes"/>
 </x-frame>

<x-frame name="B.xvcl"> <set var="n" value="b"/> <adapt x-frame="C"/> <set var="y" value="y"/> <set var="z" value="z" samelevel="no"/> </x-frame>

<x-frame name="C.xvcl"> <set var="n" value="c"/> <set var="x" value="x"/> </x-frame>

  • Variable n
    • The scope of variable n is A.
      • It is first defined by A.

    • B updates the value of n.
      • When A adapts B, samelevel is "yes", enabling B to update the value of n.

    • C cannot update the value of n.
      • When B adapts C, samelevel is "no"; the set command is silently ignored.

  • The scope of variable x is confined to C.
    • When B adapts C, samelevel is "no".

  • The scope of variable y is A, not B.
    • When A adapts B, samelevel is "yes".

  • The scope of variable z is confined to B.
    • When A adapts B, samelevel is "yes"; but, samelevel is "no" in the set command.

When samelevel="no" in the set command, where is variable z? It is stored in the variable map of frame B.

Conclusion

When samelevel is "no", the set command invokes

 getFrame().setVariableValue(...)

When samelevel is "yes", the set command invokes

 getFrame().getFrame().setVariableValue(...)

The use-samelevel patch modifies the set and set-multi commands (and the experimental external, property and xmlproperty commands).

 if ( isSameLevel() ) {
   if ( is_samelevel() ) {
     getFrame().getFrame().setVariableValue(...);
   }
   else {
     getFrame().setVariableValue(...);
   }
 }
 else {
   getFrame().setVariableValue();
 }

or rather

 Frame frame = getFrame();
 if ( isSameLevel() && is_samelevel() ) {
   frame = frame.getFrame();
 }
 frame.setVariableValue(...)

The use-samelevel patch modifies the behavior of updateVariableValue().

 Frame frame = getFrame();
 if ( isSameLevel() && is_samelevel() ) {
   frame = frame.getFrame();
 }
 frame.updateVariableValue();

Updating a variable value

 updateVariableValue (
     String variableName,
     String variableValue,
     boolean isDeferEvaluation,
     boolean isMultiValued,
     boolean isSameLevel
     );

  • The variableName variable must exist.
  • When isMultiValued, a variable is compatible with the while command.
  • When isSameLevel, a variable updates the adapting frame when adapted with samelevel="yes".

set command

(Proposed) The set command should reflect the setVariableValue() method.

 <set
     var="name"
     value="value"
     defer-evaluation="yes|no"
     multi-valued="yes|no"
     samelevel="yes|no"
     />

<set-multi var="name" value="value" defer-evaluation="yes|no" multi-valued="yes|no" samelevel="yes|no" />