My installed OclOperations do not work as expected. See testresults in both
cases (below).
Can someone help me further?
Thanks
Peter G.
Case 1: run-time and design-time installation of OclOperation
=========================================
[EcoOclOperation(typeof(OclOperations.OclOperation_DateTime_AddYears),
true)]
public class ToonbankEcoSpace: Borland.Eco.Handles.DefaultEcoSpace
...
public class OclOperation_DateTime_AddYears : OclOperationBase
{
public override void Evaluate(IOclOperationParameters parameters)
{
System.DateTime dt = (DateTime) parameters.Values[0].Element.AsObject;
int years = (int) parameters.Values[1].Element.AsObject;
parameters.Result.SetOwnedElement(Support.CreateNewConstant(ResultType,
dt.AddYears(years) ));
}
protected override void Init()
{
IOclType[] oclParameters = new IOclType[2];
oclParameters[0] = Support.DateTimeType;
oclParameters[1] = Support.IntegerType;
InternalInit("addyears", oclParameters, Support.DateTimeType);
}
}
Result:
-------
design time
ok = expressionhandle.Expression
nok = ECO Diagram . class . derived attribute . derivation
nok = state diagram . guard (undefined operation in actionlanguage
editor)
nok = state diagram . effect (undefined operation in ocl expression
editor)
run time
ok: ECO debugger
ok = ECO Diagram . class . derived attribute . derivation
ok = state diagram . guard (seems to work correctly)
nok = state diagram . effect
Case 2: design-time installation of OclOperation
================================
public class ToonbankEcoSpace: Borland.Eco.Handles.DefaultEcoSpace
{
static ToonbankEcoSpace()
{
IOclTypeService oclService =
(IOclTypeService)GetTypeSystemService().StaticEcoServices.GetEcoService(type
of(IOclTypeService));
// Install operations for design time use
InstallOperations(oclService);
}
private static void InstallOperations(IOclTypeService oclService)
{
oclService.InstallOperation(new
OclOperations.OclOperation_DateTime_AddYears());
}
...
public ToonbankEcoSpace(): base()
{
InitializeComponent();
rhRoot.EcoSpace = this;
// Install operations for run time use
OclOperations.Init(this);
}
...
class OclOperations
{
static public void Init(IEcoServiceProvider EcoServiceProvider)
{
// install operations
IOclService oclService =
EcoServiceProvider.GetEcoService(typeof(IOclService)) as IOclService;
oclService.InstallOperation(new OclOperation_DateTime_AddYears());//
addyears
}
...
public class OclOperation_DateTime_AddYears : OclOperationBase
{
public override void Evaluate(IOclOperationParameters parameters)
{
System.DateTime dt = (DateTime) parameters.Values[0].Element.AsObject;
int years = (int) parameters.Values[1].Element.AsObject;
parameters.Result.SetOwnedElement(Support.CreateNewConstant(ResultType,
dt.AddYears(years) ));
}
protected override void Init()
{
IOclType[] oclParameters = new IOclType[2];
oclParameters[0] = Support.DateTimeType;
oclParameters[1] = Support.IntegerType;
InternalInit("addyears", oclParameters, Support.DateTimeType);
}
}
Result:
-------
design time
ok = expressionhandle.Expression
nok = ECO Diagram . class . derived attribute . derivation
nok = state diagram . guard (undefined operation in actionlanguage
editor)
nok = state diagram . effect (undefined operation in ocl expression
editor)
run time
ok: ECO debugger
ok = state diagram . guard (seems to work correctly)
nok = state diagram . effect, with exception: operation call failes :
undefined operation addyears
Please do not cross-post.
--Jesper
Exactly :-)
--
Holger
> Hi all,
>
> My installed OclOperations do not work as expected. See testresults
> in both cases (below).
> Can someone help me further?
Custom OCL operations that are added to the ecospace with the
[EcoOclOperation] attribute will show up in OCL-editors in the forms,
but not in the class designer (including state diagrams) since the
diagrams are unaware of which ecospace that particular class belongs
to. it should work in runtime though. It seems to work in all cases
except when you use it to define an effect... odd, requires some
investigation.
--
/Jonas, Borland Eco R&D
I tried to add your operation to a C# winforms project, added it to the
ecospace with [EcoOclOperation], added a class with a statemachine and
a transition that had a trigger and your operation in the effect. it
executes just fine in runtime.
Do you have a sample of your project that shows the error?
OK
(continued on borland.public.csharpbuilder.modeldrivenarchitecture.eco)
Ok, that is clear to me. Thx.
Is there any way to make common use or not domain specific OclOperations
accessible in the class designer and state diagrams?
Peter G.
No, I don't.
And I'm affraid I made a typo. Sorry about this.
=> custom OclOperations works fine in trigger.effects
Peter G.
If I add a custom operation through the attribute method, I get a
"Exception has been thrown by target of an invocation" ? (I use Delphi,
not C#)
I now install the operation through InstallOperation instead, but the
attribute method is neat, but doesn't work for me.
BTW. does anyone know what the parameter is called for OclSortDirection?
I have tried "Descending", "oclDescending", "oclSortDescending" and
"OclSortDirectionDescending" but I haven't found the right keyword.
Does anybody know?
Per
> Is there any way to make common use or not domain specific
> OclOperations accessible in the class designer and state diagrams?
At the moment, no. It would be possible (in highlander) to add a new
registry for ocl operations that should be registered in all ecospaces.
> If I add a custom operation through the attribute method, I get a
> "Exception has been thrown by target of an invocation" ? (I use
> Delphi, not C#)
Any callstacks or additional information?
> BTW. does anyone know what the parameter is called for
> OclSortDirection? I have tried "Descending", "oclDescending",
> "oclSortDescending" and "OclSortDirectionDescending" but I haven't
> found the right keyword. Does anybody know?
there are two different ways to specify an enum value. either
#<EnumName>
or
<EnumType>::<EnumName>.
example:
Person.Allinstances->orderGeneric(
name, #ascending,
dateOfBirth, #ascending)
Person.Allinstances->orderGeneric(
name, OclSortDirection::descending,
dateOfBirth, OclSortDirection::ascending)
No call stack - no nothing?. Just that message.
Oh, so there are 2 ways. I think the # is the way to go. Thnx Jonas.
Per
> Jonas Hogstrom wrote:
> > Per Bakkendorff wrote:
> >
> > > If I add a custom operation through the attribute method, I get a
> > > "Exception has been thrown by target of an invocation" ? (I use
> > > Delphi, not C#)
> >
> > Any callstacks or additional information?
> No call stack - no nothing?. Just that message.
strange. I have not seen that myself, could you post a sample for
D2006u2 in binaries?
> Oh, so there are 2 ways. I think the # is the way to go. Thnx Jonas.
#<EnumName> is Ocl1.1 style
<EnumType>::<EnumName> is ocl1.4 style
Personally (from a parser writers perspective), I prefer the
<type>::<enum> style since it allows direct validation of the name of
the enum (only the ones that belong to the type are valid) and direct
type-deduction.
I'll try a little harder to provoke a message that is a little more
clear, than this odd message.
Hmm, I don't know what to post:)
The message appears when I decorate
the ECOSpace with "[EcoOclOperation(TypeOf(CommaText), False)]",
compile/build the project. After the compile is complete the cursor
disappears for a second (this is normal behavior), and then this message
appears. If I remove the attribute everything compiles ok.
BTW. the operation I install is the one that Daniel Polistchuck showed
in his blog. (http://blogs.borland.com/danielp)
Which one is the fastest?
<type>::<enum> seems like the best candidate as you have the type at hand.
Per
Yes, that is the one I would think is the fastest.