| Promotion of Parts when Dropped: Design |
Problem:
VCEPreSetCommand is responsible for
the scoping of Java elements that are added to the JEM model. It
has four possible scopes:
- GLOBAL_GLOBAL
- This is an instance variable and
it also has its own method that initializes and returns it
- GLOBAL_LOCAL
- This is an instance variable, but
it is initialized in the method that initializes the parent
- LOCAL
- This is local to the method that
uses the object
- PROPERTY
- There is no instance variable and
it is a method argument
Right now the decision of the scope is
hard coded. For example, the code in VCEPresSetCommand right now
hard codes AWT and SWT to scope in a particular way.
protected
int
settingType(EObject property) {
if
(classAWTComponent.isInstance(property))
return
GLOBAL_GLOBAL;
// Hard
code AWT components to be global and globally initialized (in their own
getJavaBean() method)
else
if(classSWTShell
!= null
&& classSWTShell.isInstance(property))
return
GLOBAL_GLOBAL;
else
if
(classSWTControl != null
&& classSWTControl.isInstance(property))
return
GLOBAL_LOCAL;
// Hard
code SWT controls to be globally declared and initialized in their parent
method
else
return
PROPERTY;
}
We need to make this more flexible.
For one thing It means the ve.java package has knowledge of AWT and
SWT (which should be described just their respective jfc and swt plugins),
and for another it means that other people like Canoo cannot leverage the
logic.
Proposal:
Introduce an Enum property on org.eclipse.ve.internal.jcm.BeanFeatureDecorator
called scope.
Introduce an Enum property on org.eclipse.ve.internal.jcm.BeanDecorator
called scope.
This would look like:
<!-- The enumeration for
code generation scope. -->
<eClassifiers xsi:type="ecore:EEnum"
xmi:id="Scope" name="Scope" >
<eLiterals name="global_global"
value="2"/>
<eLiterals name="global_local"
value="3"/>
<eLiterals name="local"
value="1"/>
<eLiterals name="property"
value="0"/>
</eClassifiers>
The logic in VCEPreSetCommand would
be to check the BeanDecorator scope of the newValue and use this. If
it wasn't set then the BeanFeatureDecorator of the feature would be used.
If neither were present then the default would be PROPERTY;
Examples:
All AWT components are scoped in their
own method
-
java/awt/Component.override
<addedEObjects xsi:type="org.eclipse.ve.internal.jcm:BeanDecorator"
beanProxyClassName="org.eclipse.ve.jfc/org.eclipse.ve.internal.jfc.core.ComponentProxyAdapter"
scope="global_global"/>
JLabel wants to be scoped in the method
of the parent that declares it
-
javax/swing/JLabel.override
<addedEObjects xsi:type="org.eclipse.ve.internal.jcm:BeanDecorator"
scope="local"/>
All SWT controls should be scoped in
the parent method but an instance var in the class
-
org/eclipse/swt/widgets/Control.override
<addedEObjects xsi:type="org.eclipse.ve.internal.jcm:BeanDecorator"
beanProxyClassName="org.eclipse.ve.swt/org.eclipse.ve.internal.swt.ControlProxyAdapter"
scope="global_local"/>
except for SWT Composites that always
want to be in their own method
-
org/eclipse/swt/widgets/Composite.override
<addedEObjects xsi:type="org.eclipse.ve.internal.jcm:BeanDecorator"
beanProxyClassName="org.eclipse.ve.swt/org.eclipse.ve.internal.swt.CompositeProxyAdapter"
scope="global_global"/>
The default for everyone who doesn't
have a scope is "property". For anyone else who has their
own custom parent/child relationship they can override the scope on a per
class or per relationship basis.
Thanks,
Joe and Rich