Home » Modeling » OCL » Nesting OCL Environments and adding variables 
| Nesting OCL Environments and adding variables [message #47529] | 
Mon, 07 January 2008 09:47   | 
 
Eclipse User  | 
 | 
 | 
   | 
 
Previously we used to be able to create a child environment and add 
variables to it directly. 
 
      See the following method: 
 
      public Action createAction(Environment parent) { 
 
                  Environment environment = 
 EnvironmentFactory.ECORE_INSTANCE.createEnvironment(parent); 
                  OCLExpression targetExpression = 
ExpressionsUtil.createQuery(environment, getTarget(), true); 
                  List<EStructuralFeature> eFeatures = 
getFeaturePath(targetExpression); 
                  EStructuralFeature eFeature = getLastFeature(eFeatures); 
                  EClassifier eType = (eFeature != null) ? 
eFeature.getEType() : parent.getContextClassifier(); 
                  addVariable(environment, "oldValue", eType); 
                  addVariable(environment, "newValue", eType); 
                  return new NotificationActionImpl(getEventType(), 
eFeatures, getAction().createAction(environment)); 
 
      } 
 
 
           Now, in order to have the same effect, I am creating a new OCL 
instance with the environment of  parent OCL as below: 
 
 
      public Action createAction(Helper parentHelper) { 
 
                  OCL ocl = 
OCL.newInstance(parentHelper.getOCL().getEnvironment()); 
                  Helper helper = ocl.createOCLHelper(); 
                  helper.setContext(parentHelper.getContextClassifier()); 
                  //parentHelper.getOCL().getEnvironment() == 
helper.getOCL().getEnvironment() TODO 
                  OCLExpression<EClassifier> targetExpression = 
helper.createQuery(getTarget()); 
                  EcoreEnvironment  environment = (EcoreEnvironment) 
helper.getOCL().getEnvironment(); 
 
 
 
                  List<EStructuralFeature> eFeatures = 
getFeaturePath(targetExpression); 
                  EStructuralFeature eFeature = getLastFeature(eFeatures); 
                  EClassifier eType = (EClassifier) ((eFeature != null) ? 
eFeature.getEType() : parentHelper.getContextClassifier()); 
                  addVariable(environment, "oldValue", eType); 
                  addVariable(environment, "newValue", eType); 
                  return new NotificationActionImpl(getEventType(), 
eFeatures, getAction().createAction(helper)); 
 
      } 
 
 
      Since the OCL.Helper.getEnvironment() returns the rootEnvironment, I 
can not add my variables to the child environment. 
 
      Do you recommend us subclass OCL and OCL Helper to get desired effect? 
      I'd appreciate other suggestions
 |  
 |  
  |  
| Re: Nesting OCL Environments and adding variables [message #47561 is a reply to message #47529] | 
Tue, 08 January 2008 08:49    | 
 
Eclipse User  | 
 | 
 | 
   | 
 
Originally posted by: cdamus.ca.ibm.com 
 
Hi, Yucel, 
 
The protected OCLHelperImpl::getEnvironment() method returns the "root" 
environment of the OCL that created it only in the case that it doesn't, 
yet, have its own environment.  The OCLHelper cannot create an environment 
until it knows what its context is (as Classifier, Operation, or Property). 
 
You shouldn't need to create a new OCL instance on the same environment as 
another.  That just makes another object that you will have to dispose() 
when you are finished with it (the OCL::dispose() method is new in 1.2 M4 
to cover a requirement to "dispose" EMF objects by unloading them or 
clearing their adapter-lists; this is particularly important to prevent 
memory leaks in UML's CacheAdapter). 
 
You can add variable definitions to the OCL's root environment; the helper 
will see them when it parses expressions.  You can then remove the 
variables when you have finished, if you want to re-use the same OCL for 
further parsing.  This is particularly convenient because, every time that 
the helper's context is changed to parse another expression, its 
environment is destroyed and a new one is created.  So, you'd have to be 
recreating your variables every time you set the helper's context.  by 
creating the variables in the root environment, every new helper 
environment will inherit them. 
 
HTH, 
 
Christian 
 
Yucel Turkkan wrote: 
 
>       Previously we used to be able to create a child environment and add 
> variables to it directly. 
>  
>       See the following method: 
>  
>       public Action createAction(Environment parent) { 
>  
>                   Environment environment = 
>  EnvironmentFactory.ECORE_INSTANCE.createEnvironment(parent); 
>                   OCLExpression targetExpression = 
> ExpressionsUtil.createQuery(environment, getTarget(), true); 
>                   List<EStructuralFeature> eFeatures = 
> getFeaturePath(targetExpression); 
>                   EStructuralFeature eFeature = getLastFeature(eFeatures); 
>                   EClassifier eType = (eFeature != null) ? 
> eFeature.getEType() : parent.getContextClassifier(); 
>                   addVariable(environment, "oldValue", eType); 
>                   addVariable(environment, "newValue", eType); 
>                   return new NotificationActionImpl(getEventType(), 
> eFeatures, getAction().createAction(environment)); 
>  
>       } 
>  
>  
>            Now, in order to have the same effect, I am creating a new OCL 
> instance with the environment of  parent OCL as below: 
>  
>  
>       public Action createAction(Helper parentHelper) { 
>  
>                   OCL ocl = 
> OCL.newInstance(parentHelper.getOCL().getEnvironment()); 
>                   Helper helper = ocl.createOCLHelper(); 
>                   helper.setContext(parentHelper.getContextClassifier()); 
>                   //parentHelper.getOCL().getEnvironment() == 
> helper.getOCL().getEnvironment() TODO 
>                   OCLExpression<EClassifier> targetExpression = 
> helper.createQuery(getTarget()); 
>                   EcoreEnvironment  environment = (EcoreEnvironment) 
> helper.getOCL().getEnvironment(); 
>  
>  
>  
>                   List<EStructuralFeature> eFeatures = 
> getFeaturePath(targetExpression); 
>                   EStructuralFeature eFeature = getLastFeature(eFeatures); 
>                   EClassifier eType = (EClassifier) ((eFeature != null) ? 
> eFeature.getEType() : parentHelper.getContextClassifier()); 
>                   addVariable(environment, "oldValue", eType); 
>                   addVariable(environment, "newValue", eType); 
>                   return new NotificationActionImpl(getEventType(), 
> eFeatures, getAction().createAction(helper)); 
>  
>       } 
>  
>  
>       Since the OCL.Helper.getEnvironment() returns the rootEnvironment, I 
> can not add my variables to the child environment. 
>  
>       Do you recommend us subclass OCL and OCL Helper to get desired 
>       effect? I'd appreciate other suggestions
 |  
 |  
  |   |  
| Re: Nesting OCL Environments and adding variables [message #47708 is a reply to message #47647] | 
Thu, 10 January 2008 09:05   | 
 
Eclipse User  | 
 | 
 | 
   | 
 
Originally posted by: cdamus.ca.ibm.com 
 
Hi, Yucel, 
 
Adding custom operations is necessarily more complex than adding variables, 
because that requires a custom environment implementation.  I agree that 
the helper's environment should be more accessible. 
 
If you would raise an enhancement request, I'll see what we can do to 
address it. 
 
Thanks, 
 
Christian 
 
Yucel Turkkan wrote: 
 
> Christian, 
>  
> Thank you for your email. We've based our even-action processing code on 
> top of your OCL implementation. 
>  
> Similar to OCL OperationCalls, we also contribute variables to the 
> environment, in potentially nested contexts. For clarity: that method I 
> have given below can be called more than once, each call introducing 
> additional variables. 
>  
> Since we no longer can control the nesting of Environments that is held 
> privately by OCLHelper, we now need to create our own 
> EvaluationEnvironment type of object where we keep track of variables 
> which we can only contribute 
> to the root OCL Environment.  It is doable, but totally reduandant, given 
> that is what OCL EvaluationEnvironment is for. 
>  
> Perhaps you can let us register our own subclass of OCL.Helper so that we 
> can get access to the environment so that we can control the nesting of 
> the environments? 
>  
> Thanks for your consideration, 
>  
> Yucel
 |  
 |  
  |   
Goto Forum:
 
 Current Time: Mon Nov 03 22:06:49 EST 2025 
 Powered by  FUDForum. Page generated in 0.04578 seconds  
 |